02
2020

Amazon ECSへのDockerイメージのデプロイ方法(Latest運用簡易版)

CATEGORY開発環境
最近Dockerアプリの開発環境をAWSのAmazon ECSに構築する必要があって、環境構築の方法とかは普通に見つかったけど、デプロイの方法とかが分かりにくかったので、手順をここに纏めとく。
なお、タイトルに「Latest運用簡易版」とある通り、いわゆるタグを latest とかで毎回上書きする簡易的な手順。
latest でのデプロイは、本番では推奨されていないので注意。
(タグを変えてのデプロイは、CodeDeploy とかを使うと出来るらしい?)

1. Amazon ECRのリポジトリ作成

AWS上のDockerコンテナレジストリであるAmazon ECRに、使用するDockerイメージ用のリポジトリを登録する。
Docker Hubとかでも流れは同じだと思うが、今回は以下ECRで説明。)

これは基本的に名前を入れるだけなので、あまり迷うことは無いと思う。
Latest運用ということで 「タグのイミュータビリティ」だけは「無効にする」を選んでおく。
(有効にすると同じタグで上書きできないらしい。)

2. Dockerイメージのビルド

次にデプロイするDockerイメージをビルドする。
これはまだAWS上じゃなくてOK。普通にDockerをインストールしてる自分のマシンとかビルドマシンとかでやる。こんな感じ。
docker build -t リポジトリ名 .
-t でさっき作ったECRのリポジトリ名に合わせたタグをつける。

3. ECRへのアップロード

続けて、ビルドしたマシンで今度はイメージをECRにアップロードする。コマンド的にはこんな感じ。
$(aws ecr get-login --no-include-email --region リージョン)
docker tag リポジトリ名:latest アカウントID.dkr.ecr.リージョン.amazonaws.com/リポジトリ名:latest
docker push アカウントID.dkr.ecr.リージョン.amazonaws.com/リポジトリ名:latest
実行するマシンにはAWS CLIがインストールされていて、また接続情報とかが設定されている必要がある。
かつ、AWS側にも、接続してくるアカウントに対して、ECRのアップロード権限とかのポリシーを付与している必要がある。
1行目の $ もコマンドの一部なので注意。

ちなみに、↑のコマンドはECRのリポジトリを開いて「プッシュコマンドの表示」ボタンを押すと表示されるので、実際に使う際はそこからコピペしてください。

4. ECSクラスターの構築

アップロードしたDockerイメージを動かすECSクラスターを構築する。
この手順は、既にいろんな人がまとめているのでそちらの記事を参照。
今回は以下のQiitaの記事をとても参考にさせて頂いた。感謝m(__)m
※ クラスタ構築は第3回辺りに登場。

クラスターのサービスで、先ほどのECRのリポジトリを指定する。初回のデプロイについては、タスクが起動した時点で完了。

5. Dockerイメージの更新

今回の本題。さてここまででDockerコンテナがECSで動くようになったとして、そのイメージをどうやって更新すればいいのかについて。

まず、ECRのイメージの更新だが、これは新規で作成する場合と全く一緒。ビルド元のファイルを更新してから、上の2,3の手順をもう一度実行すればOK。

次にECSの動いているイメージの差し替えだが、これがちょっと分かり難い。
結論から書くとECSの「サービス」を選んで「更新」画面を開き、「新しいデプロイの強制」のチェックボックスをONにした状態で次へ進んでいって、「サービスの更新」を実行すればよかった。
そうすると、今動いてるタスクが停止して、勝手に新しいイメージを使ったタスクが立ち上がる。

もちろんデプロイの度にこんな手順はやってられないので、AWS CLIから以下のようにコマンドを叩くのが早い。
aws ecs update-service --cluster クラスター名 --service サービス名 --force-new-deployment
実行するアカウントには、ECSの操作権限とかのポリシーを付与しておく必要がある。

Jenkinsタスクとかにここまでのコマンドをまとめてやれば、ビルドからデプロイまで自動化できる。

注意点1) タスクが再起動しない

「新しいデプロイの強制」をチェックすればいいんでしょ?と試してみたものの、いつまで経っても再起動せず暫く悩む羽目になったので、その原因と対策も書いておく。

まずタスクが起動or再起動しない場合は、ECSのサービスの「イベント」欄に起動できない原因が書いてあったりするので、それを確認する。
で、今回ハマったのは「2つ目のタスクが起動できない」問題。

サービスをデフォルトの設定で作ると、「タスクの数 1」「最小ヘルス率 100」「最大率 200」とかになってると思う。
これは「タスクは必ず1つ以上生存必須」「タスクは最大で2つまで起動可」の意味。
…なんだけど、今回はDockerのホストにFargateじゃなくてEC2を使ってて、かつ開発環境なので1台のホストしかなかった。
なので、リソース的にも、またポート番号とか的にも、1タスクしか起動できなかった。
そのため、永遠に2つ目のタスクが起動できず、2つ目が起動しないと1つ目を停止できないので、そこで止まっていたorz

解決策としては、2つ目を起動できるリソースがあれば手っ取り早いけど、今回は開発環境なのでそもそもダウンタイムがあってもいいので、「最小ヘルス率 0」「最大率 100」に変更して解決した。

注意点2) タスクがなかなか再起動しない

これはELB使っていると起きる問題。ELBがタスクの終了を一定時間保留してしまうので、タスクがなかなか再起動してくれない。
この秒数はELBの設定から変えられるので、環境や用途に合わせて短くすればよい。
(今回は開発環境なので10秒とかにしたし、ヘルスチェック回数とかも最短まで削った。)

この設定はこちらの記事を参考にさせて頂いた。詳細はそちらを参照で。

注意点3) ECRのゴミデータの自動削除

ECRに同じタグで新しいDockerイメージをアップロードすると、古いバージョンはタグ無しのイメージとなって残る模様。
ECRはストレージ課金もあるので、これだとどんどん料金が膨らんでしまう。なのでその対処法。

古いイメージの削除の設定は、ECRのリポジトリのとこに出てくる「Lifecycle Policy」から設定できる。
ここで「タグ付けなし」を選べば、日数や個数で古いイメージを自動的に削除してくれる。リポジトリ作成時は忘れず設定を。
(条件を頑張れば、タグが付いてる古いやつとかも消せるはず。)


以上、こんなところで。分かってしまえば大した話でもなかったけど、最初動くまではハマりまくりだったので、参考になれば。
スポンサーサイト



Tag: AWS Docker ECS ECR

0 Comments

Leave a comment