Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ecspresso exec

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

ecspresso exec

Avatar for FUJIWARA Shunichiro

FUJIWARA Shunichiro

April 23, 2021
Tweet

More Decks by FUJIWARA Shunichiro

Other Decks in Technology

Transcript

  1. ecspresso のご紹介 github.com/kayac/ecspresso Amazon ECS デプロイツール Simple / Minimal (最近は機能が増えてきた…)

    ECS サービスとタスク定義の管理に特化 Terraform / CloudFormation と連携可能 ecspresso handbook zenn.dev/fujiwara/books/ecspresso-handbook
  2. ecspresso のコマンド (v1.5) 設定⽣成 → init appspec サービス関係 → create

    delete status デプロイ → deploy scale refresh rollback wait タスク起動、タスク定義登録 → run register 検証 → diff verify render タスクの状態を⾒る → tasks (New!) execute-command!!! → exec (New!)
  3. ecspresso tasks ecspresso で管理しているサービス/タスク定義によって実⾏されているタスクを表⽰ $ ecspresso --config config.yaml tasks |

    ID | TASKDEFINITION | INSTANCE | LASTSTATUS | DESIREDSTATUS | CREATEDAT | GROUP | TYPE | +----------------------------------+--------------------+----------+------------+---------------+---------------------------+-----------------------+---------+ | 31aba18f436e415f819670e8936fb09f | ecspresso-test:276 | | RUNNING | RUNNING | 2021-04-22T22:46:51+09:00 | service:nginx-local | FARGATE | | 581833da4ade4ad9aafa0bbadcf9b636 | ecspresso-test:276 | | RUNNING | RUNNING | 2021-04-22T22:46:51+09:00 | service:nginx-local | FARGATE | | f218b20ec86d4be2bf77a28c76dfe306 | ecspresso-test:277 | | PENDING | RUNNING | 2021-04-22T22:49:36+09:00 | family:ecspresso-test | FARGATE | | 8a4124cac40e431095a46d36210189be | ecspresso-test:276 | | STOPPED | STOPPED | 2021-04-20T23:05:29+09:00 | service:nginx-local | FARGATE | | d0a37d791e924d5d8bbfdaeeb58ae882 | ecspresso-test:276 | | STOPPED | STOPPED | 2021-04-20T22:57:35+09:00 | service:nginx-local | FARGATE | --find 特定のタスクを選択後、詳細をJSONで表⽰ --stop 特定のタスクを選択後、停⽌
  4. ecspresso exec (本題) Demo asciinema.org/a/405167 # config.yaml filter_command: peco 対象のタスク、タスク内のコンテナの絞り込みに外部コマンドを指定可能

    fzf github.com/junegunn/fzf peco github.com/peco/peco percol github.com/mooz/percol など、複数⾏から1⾏を選択できるコマンドならなんでもOK (指定がなければID/コンテナ名を⼊⼒するpromptが出ます)
  5. ecspresso exec = aws ecs exeucte-command aws ecs execute-command と同様、引数での指定も可能

    aws ecs execute-command \ --cluster default --task ${task_id} \ --container ${container_name} \ --command sh --interactive ⇅ ecspresso exec --config config.yaml \ --id ${task_id} \ --container ${container_name} \ --command sh
  6. 実装の話をします aws ecs execute-command colipot svc exec ecspresso exec いずれも

    session-manager-plugin (コマンド) が必要 session-manager-plugin is なに?
  7. session-manager-plugin help とかないかな $ session-manager-plugin help Unknown operation help. Use

    session-manager-plugin --version to check the version. $ session-manager-plugin --help Unknown operation --help. Use session-manager-plugin --version to check the version. $ session-manager-plugin --version 1.2.54.0 とりつく島がない
  8. aws-cli (v2) の場合 awscli/customizations/ecs/executecommand.py にあります class ExecuteCommandCaller(CLIOperationCaller): def invoke(self, service_name,

    operation_name, parameters, parsed_globals): try: client = # ... response = client.execute_command(**parameters) # ... with ignore_user_entered_signals(): check_call(["session-manager-plugin", json.dumps(response['session']), region_name, "StartSession", # ... ) (要約) ExecuteCommand APIのレスポンスのsessionをJSONにしたもの、リージョ ン、"StartSession"を引数にして session-manager-plugin を呼ぶ。ユーザ割り込みシグ ナル(Ctrl-Cとか)は無視
  9. copilot-cli の場合 internal/pkg/exec/ssm_plugin.go あたりにあります const ( ssmPluginBinaryName = "session-manager-plugin" startSessionAction

    = "StartSession" ) func (s SSMPluginCommand) StartSession(ssmSess *ecs.Session) error { response, err := json.Marshal(ssmSess) if err != nil { return fmt.Errorf("marshal session response: %w", err) } if err := s.runner.InteractiveRun(ssmPluginBinaryName, []string{string(response), aws.StringValue(s.sess.Config.Region), startSessionAction}); err != nil { return fmt.Errorf("start session: %w", err) } (要約) ExecuteCommand APIのレスポンスのSessionをJSONにしたもの、リージョ ン、"StartSession"を引数にして session-manager-plugin を呼ぶ。 ( InteractiveRun の中で signal.Ignore(os.Interrupt) =ユーザ⼊⼒割り込みシグナル を無視)
  10. session-manager-plugin で exec する⽅法まとめ . ECS ExecuteCommand API を叩く .

    レスポンスの Session を JSON ⽂字列にしたもの、リージョン名、"StartSession" を引 数にして session-manager-plugin をコマンドとして呼ぶ (引数はaws-cliを読むとまだあるようだけど最低限これでOK) . SIGINT は無視する 無視しないと Ctrl-C が exec 先に伝わらないで⼿元のコマンドが終了してしまう
  11. 実習 ExecuteCommandを叩いてレスポンスのSessionをJSONで表⽰するコマンドを作る func main() { svc := ecs.New(session.Must(session.NewSession())) res, _

    := svc.ExecuteCommand(&ecs.ExecuteCommandInput{ Cluster: aws.String(os.Args[1]), Task: aws.String(os.Args[2]), Container: aws.String(os.Args[3]), Command: aws.String(os.Args[4]), Interactive: aws.Bool(true), }) sess, _ := json.Marshal(res.Session) fmt.Println(string(sess)) }
  12. $ go run exec.go default 581833da4ade4ad9aafa0bbadcf9b636 nginx sh | jq

    . { "SessionId":"ecs-execute-command-03e7af5c716f7b340", "StreamUrl":"wss://ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel/ ecs-execute-command-03e7af5c716f7b340?role=publish_subscribe", "TokenValue":"AAEAAcNzLXhpq...." } そのJSONで session-manager-plugin を呼ぶと… $ session-manager-plugin '{...}' ap-northeast-1 StartSession Starting session with SessionId: ecs-execute-command-03e7af5c716f7b340 # nginx -v nginx version: nginx/1.19.10
  13. まとめ ecspresso exec で快適な ECS Exec 環境を実装しました # config.yaml cluster:

    クラスタ名 service: サービス名 filter_command: peco この config.yaml を ecspresso --config に指定するだけで、ecspresso 管理下でない ECS サ ービスも簡単 exec できるのでぜひお試しを session-manager-plugin の使い⽅を公式のOSS実装から探りました