Tag: ECS

Dockerイメージの検証、更新する手順

できればインフラ構成についてもコード化したいため、CodeBuildのbuildspecでECSの設定を記述/更新していました。

このため、ECSの設定画面でポチポチと変更、検証することも可能ですが、Githubへのpush、CodeBuildで更新がかかると、ECSへの変更も元に戻ります。 (検証のために、ちょっとだけECS側で変更するのは無害です)

恒久的な変更はCodeBuild側へ変更するようにしましょう。

下記の手順はローカルでDockerイメージをダウンロードして検証する方法です。 「こうすると効率が良かった」というレベルのものです。

作業の流れ

  • ECRからイメージダウンロード
  • Mac上でコンテナを起動し、いろいろ検証( Dockerfileに必要な変更の検討など )
  • 必要な修正が決まったら、Githubのtestブランチにpush
  • Githubの testブランチへpushされるとCodeBuildでdocker buildが始まり、ECRにpushされる
  • ECRのDockerレポジトリのイメージIDをメモ
  • ECSで起動しているコンテナを変更して動作確認を行う という流れになります。

イメージをローカルにダウンロードする

プライベートなDockerレポジトリ(ECR)への認証を済ませる必要があります

認証情報の取得

bash/zsh:

aws ecr get-login-password --profile profile名 --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

fish:

aws ecr get-login-password --profile profile名 --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

手元で実行

(2019/02/22の内容で、環境変数などは将来的に変更する可能性があります)

docker run -p 10022:22 -e GITHUB_ENV=staging -e AWS_ACCESS_KEY_ID=XXXXXXXXXXXX -e AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYYYY -it 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/image-name:latest /bin/bash

-p 10022:22 : リモートにSSHログインできるようにdocker内にsshdを立てました(将来的にはssmに切り替えたいですが)、sshdがlistenするポートが22番ポートなのですが、これをMacの10022にポートフォワードしています

Read more...

ECS開発環境の時刻を変えたい

背景

開発環境の時刻を変えたい時があります。 「その時刻になった時の振る舞いを確認したい」 「ある時間帯をターゲットにした開発を行いたい」 などです。 そういった開発の時だけ夜間に来る、というのは現実的ではないので、手軽に開発環境の時刻を変える方法があると便利です。

EC2 Linuxサーバですとdateコマンドなどで時間を変更できます( https://qiita.com/na0AaooQ/items/af6b853faf32c58c21d3 ) ただECS Fargate環境だと( システム時刻の変更に管理者権限が必要なため )上記の方法が使えません。 このため環境変数で開発環境のロケールを変更できるようにしてみました。

  • Dockerコンテナの起動、複数コンテナの連携方法などの設定などはタスク定義に行います。「タスク」という単位でサーバが起動します。
  • サービスという概念もあり、タスクが含まれます( 同じタスクを3セット立ち上げたりします)。 サービスにはロードバランサーとの接続など「Dockerと接続する外界」といった設定項目が含まれます。

※ この方法で時刻をずらした場合、なにかデプロイされる度に、設定は初期化されます。  なにか新しいリビジョンのものがCI経由でデプロイされると、この環境変数の設定は初期化されます。

手順

  • AWS Webコンソールにログイン
  • AWS_Fargateで目的の環境のタスク定義をここから探す( env27とか、そういったものです )
  • 最新のタスク定義をクリック
  • [新しいリビジョンの作成 ]
  • [コンテナの定義]のコンテナ[ nginx ]と[ php-fpm ]のなど変更をします。 `片方だけだとエラーがでるはずです。
  • [環境]の[Key]に環境変数名 TIMEZONE を入力、 値として任意のタイムゾーン( 例えば America/Argentina/Buenos_Aires のようなもの )を入力します。 ※ この『America/****』の文字列はスラッシュを含む全てです。
  • この地域はもうすぐ朝が来てしまう などで、他の地域を設定したい場合、 地図と時差を確認 して このIBMのページの文字列をコピペします。

インフラへの設定が反映されたかを確認するのは良い習慣です。確認する場合は、設定したコンテナをクリック、環境変数が設定されているかで確認できます。

  • [ 作成 ]をクリック *これでできた新しいリビジョンのタスク定義で、サービスを再起動します

時刻のロケールを戻す

2つの方法があります。 このページの[手順]の[新しいリビジョンの作成]のクリック後、 上記同様、nginxとphp-fpmの2つのコンテナの環境変数を変更します。 [コンテナの定義]のコンテナ[ nginx ]と[ php-fpm ]のそれぞれに対して設定を行います。 [環境]の[Key]のTIMEZONEの箇所で

  1. 環境変数 TIMEZONE の値を Asia/Tokyo にする
  2. 環境変数 TIMEZONE自体を消す( この環境変数が無かった場合は Asia/Tokyo を設定するようにしています )

2つの方法があります。どちらでも同じ結果になり、デメリットは発生しないので、どちらでも良いです。 強いていうと、 2 の方が綺麗になるので良いかと思います。

Read more...

ECS Fargate を CLIで操作

ECSのサービス設定、つくる作業が煩雑なので、CLIで自動化できないか検討。

aws ecs create-service --cluster example-dev-20181030-1 \
  --service-name env36\
  --task-definition env36\
  --desired-count 1\
   --launch-type FARGATE\
  --deployment-configuration maximumPercent=200,minimumHealthyPercent=100\
   --network-configuration "awsvpcConfiguration={subnets=[subnet-0123456789abcdef0,subnet-0123456789abcdef1,subnet-0123456789abcdef2],securityGroups=[sg-0123456789abcdef0],assignPublicIp=DISABLED}"\
   --deployment-controller type=ECS

aws cliのecsのcreate-serviceのオプションは多いのでCLIで作るのを想定してる感じある。

Read more...

CodePipeline、ブランチごとデプロイ

基本、下記をなぞる。 が、「artifacts として事前準備で作成したタスク定義ファイルを指定します。」という表現だけが違う、気がする。 AWS CodePipelineがECSへのデプロイをサポートしたのでやってみる - Qiita

ECSのタスク定義に使用する( aws ecs register-task-definition –cli-input-json ./imagedefinitions.json で使用する )ファイルのフォーマットと artifactsのフォーマットは異なる。 [ The image definition file image definitions.json contains invalid JSON format ]というエラーが出る。

構成

  • Githubのあるブランチにgit pushすると、CodePipelineが反応する
  • CodePipeline経由で、CodeBuildが起動、DockerイメージをビルドしてECRにdocker push、ECRのタスク定義も更新して新しいイメージが見えるようにする
  • 開発者が見る、URLはALB -> ECSインスタンス -> ECSコンテナ という形でアクセスする
  • ALBはリクエストヘッダ中のホスト名の箇所で特定のターゲットグループに振り分ける設定にする
  • むやみにALBインスタンスを増やさない

作業の流れ

ECRでDockerレポジトリを作成、Dockerイメージをビルドして、Dockerレポジトリに入れる。 Dockerレポジトリにあるイメージを用いて、ECSのタスク定義を行う。

CodePipelineは設定を行えば、定期的にGithubの特定のレポジトリを監視して、 変更があったらDockerイメージをビルドできる。この際、『どのようにビルドするか』を Gitレポジトリのトップディレクトリにある buildspec.yml に従って行う。このbuildspec.ymlを用意しておく。 あらかじめGithubに目的のブランチを作っておく( でないとCodePipelineの設定時に、ターゲットのブランチがプルダウンメニューに現れない ) CodePipelineの設定を行い、自動ビルドを回し始める。

手順

  1. 対応ブランチごとにECRのリポジトリを作成する

https://ap-northeast-1.console.aws.amazon.com/ecs/home?region=ap-northeast-1#/repositories

ECSの管理コンソールにログイン ->[ リポジトリの作成 ]->[ リポジトリ名 ]にレポジトリ名[ api9 ]などを入れる。 このECRのレポジトリ名はGithubのブランチと揃えるようにした。

  1. Dockerイメージを作成する 既にあるDockerの作業環境を流用する。 Dockerイメージをビルドする。 このコマンドは ECRでDockerレポジトリを作成した後、[ プッシュコマンドの表示 ]で確認できるコマンドに沿う。
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

で表示されたコマンドを実行。Dockerfileがあるディレクトリに移動し

Read more...

ECS EC2タイプでの基本的なサービスの立ち上げ

ALB->ECSインスタンス->コンテナ->RDSとかRedis といった構成を構築する

  • ネットワークはECSデフォルトのブリッジをつかう
  • イメージ内には2つのポートをlistenするnginxが立っている。
  • ALBのリスナーでは、リクエストヘッダ内のパラメータを見て、人ごとに作られたターゲットグループに振る
  • ターゲットグループからECRのタスク、サービスに振られる。

作業の流れ

ECRにログイン

  • Dockerイメージ作成
  • ECRにコンテナイメージのpush
  • クラスターを作成( ECSインスタンスの入れ物的なもの )
  • タスク定義
  • タスク定義を元にクラスター内にサービスを作成

ECRにイメージをpush

ECRへのアクセス権を得るには下記出力を実行する

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

コンテナにタグつけ

docker tag example_web:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/example_web:latest

push

docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/example_web:latest

タスク定義

  • タスク定義名 : 何か入力
  • ネットワークモード : <default>

コンテナの追加

コンテナ名 : 任意

イメージ : ECRのページで確認。 あるいはdocker push で指定する先

メモリ制限 : ソフト制限 500MB / ハード制限 1000MB にした

参考

コンテナ用に予約するメモリのソフト制限 (MiB 単位)。
システムメモリが競合している場合、Docker はコンテナメモリをこのソフト制限に維持しようとします。
ただし、コンテナは必要に応じて、memory パラメーターで指定したハード制限 (該当する場合)、またはコンテナインスタンスの使用可能なメモリの、
いずれか先に達するまで、追加のメモリを消費できます。

このパラメータは、Docker Remote API の コンテナを作成する セクションの MemoryReservation と docker run の --memory-reservation オプションにマッピングされます。

コンテナ定義で memory と memoryReservation の一方または両方を 0 以外の整数を指定する必要があります。 両方を指定する場合、memory は
memoryReservation より大きいことが必要です。memoryReservation を指定する場合、
コンテナが配置されているコンテナインスタンスの使用可能なメモリリソースからその値が減算されます。それ以外の場合は、memory の値が使用されます。

たとえば、コンテナが通常 128 MiB のメモリを使用しているが、短期間に 256 MiB のメモリにバーストする場合は、
memoryReservation を 128 MiB に、memory ハード制限を 300 MiB に設定できます。
この設定により、コンテナは、コンテナインスタンスの残りのリソースから 128 MiB のメモリのみを確保できますが、必要に応じて追加のメモリリソースを消費できるようにもなります。

ポートマッピング ホストポート : 空 / コンテナポート 10080 / プロトコル TCP

Read more...

コンテナの再起動

ECSのある環境を再起動したい

いろいろな理由で再起動したいことはあります。例えば

  • SecretsManagerの変更したので再起動して反映したい
  • docker-php環境を更新したので、再起動して最新のdockerイメージで起動し直したい
  • 起動時のログを追いかけたいとき

などですね。

手順

1. タスク定義のリビジョンを上げる

  • AWS管理画面にログイン
  • 左上のサービス一覧から[ ECS ]を検索してクリック
  • 左側メニューから[ タスク定義 ]を選択
  • 目的の環境のタスク定義をクリック(env25など)
  • 一番新しいリビジョン( 数字の大きいもの )をクリック
  • [ 新しいリビジョンを作成 ]->[ 作成 ] ( この作成は失敗することがあります )

2. クラスター内の各サービスが参照するタスク定義のリビジョンを上げる

  • ECS管理画面の左側のメニューから[ クラスター ]を選択
  • [ dev-20181030-1 ]
  • サービス名のカラムから再起動したいサービス名をクリック(env25など)
  • 右上の方の[ 更新 ]をクリック
  • [ リビジョン ]のプルダウンメニューをクリック
  • 少しスライドして[ latest ]と書いてあるタスク定義を選択(1で作成したリビジョン番号を選択)
  • [ 次のステップ ]->[ 次のステップ ]…->[ サービスの更新 ]

以上でECSコンテナの再起動が行われます

※ 再起動ですが、結構時間かかります… 細かく『いまどういう状態なのか?』を確認する場合ですが、 この再起動はブルーグリーン方式で、ダウンタイムが無いように再起動するようにしています。

どのような順番で行われるかというと、

  1. ECSの該当サービスで追加のタスク( タスクの中には nginx, php-fpm, volumeなどのコンテナが含まれます )が追加されます。
  2. タスクはロードバランサーの中のターゲットグループの中に追加されます( EC2 -> ロードバランサー -> ターゲットグループで該当のサービス名が書いてあるターゲットグループを探す )
  3. dockerコンテナはターゲットグループに追加され、ヘルスチェックに成功すると新しいコンテナをheltyにし、アクセスを受け付け始め古いコンテナをdrainingします 上記の流れで『今、デプロイがどのような状態なのか?』を知ることができます
Read more...