Amazon EC2 Container Serviceで構築されたシステムでDockerコンテナを入れ替える
はじめに
ついにAmazon EC2 Container Service(ECS)がAWS管理コンソールから使えるようになりましたね!
まだ実装されていないAPIがあったりしますが、CLIだけでなくGUIで操作が出来るというのは、格段に敷居が低くなりますね。
で、こんな用途を想定して、試してみました。
- Amazon ECSでシステムを構築している。
- システムにバージョンアップがあった場合、古いシステムが入ったコンテナを廃棄し、新しいシステムが入ったコンテナをデプロイして入れ替える。
やってみる
Clusterなどは前述の触ってみた記事で一通り完了していると想定します。
最初のバージョンのDockerイメージを作成する
今回は静的コンテンツで構成されたWebシステムとします。とりあえずindex.htmlだけある状態です。
Dockerfileを作成します。git checkoutでgithubのコミット断面を指定しています。
$ cat Dockerfile FROM nginx RUN apt-get -y update RUN apt-get -y install python-software-properties RUN add-apt-repository ppa:git-core/ppa RUN apt-get -y install git RUN rm -rf /usr/share/nginx/html RUN git clone https://github.com/smokeymonkey/ecs-web.git /usr/share/nginx/html RUN cd /usr/share/nginx/html && \ git checkout 6fc2551671e8ff4fd8c8f195792d2ff74fb2659a
これをバージョン1.0とし、docker buildしてDockerイメージを作成、docker pushします。
$ docker build -t smokeymonkey/ecs-web:1.0 . $ docker push smokeymonkey/ecs-web:1.0
最初のバージョンのタスク定義(Task Definition)を作成する
ECS管理コンソールで[Task Definitions]-[Create new Task Definition]をクリックし、[Create a Task Definition]画面を開きます。[Task Definition Name]を"website"とし、[Add Container Definition]をクリックします。
こんな感じで、[Image]欄に最初のバージョンのDockerイメージを入力します。また[Environment Variables]にVersionタグを入れておきます。各パラメータを埋めて[Add]ボタンをクリックします。
Container Definitionが作成されたので、[Create]ボタンをクリックします。
サービスを作成する
タスクを動かすためのサービスを作成します。[Create Service]画面で、[Task Definition]で先ほど作ったタスク定義(website:1)を指定します。またELBに登録しておきます。その他パラメータを埋めて[Create Servcie]ボタンをクリックします。
サービスが作成されると、以下のようにクラスタの[Services]タブに"website"というサービスが登録されます。
そしクラスタの[Tasks]タブでは、"website:1"タスクが表示され、実行されていることが確認できます。
この状態で実際にELBにアクセスすると、以下のようにHTMLコンテンツが表示されます。
これで一旦、Amazon ECSによるシステムが構築されました。
新しいバージョンのDockerイメージを作成する
静的HTMLコンテンツを書き換えます。
Dockerfileのgit checkoutを書き換えて、新しいコミット断面を指定します。
$ cat Dockerfile FROM nginx RUN apt-get -y update RUN apt-get -y install python-software-properties RUN add-apt-repository ppa:git-core/ppa RUN apt-get -y install git RUN rm -rf /usr/share/nginx/html RUN git clone https://github.com/smokeymonkey/ecs-web.git /usr/share/nginx/html RUN cd /usr/share/nginx/html && \ git checkout 982544160c2a67324a9f30f683924f1cb14dfb48
バージョン1.1としてbuild & pushします。この時キャッシュを使ってしまうとgit cloneで新しいコミット断面を拾ってこないので--no-cacheオプションをつけてます。
$ docker build --no-cache -t smokeymonkey/ecs-web:1.1 . $ docker push smokeymonkey/ecs-web:1.1
新しいバージョンのタスク定義を作成する
ECS管理コンソールの[Task Definitions]で、タスク定義"website"を選択し、[Create new revision]ボタンをクリックします。
[Create new revision]画面が表示されるので、コンテナ定義(以下の例だとwebsite)をクリックします。
コンテナ定義の編集画面が表示されます。[Image]欄に新しいバージョンのDockerイメージを指定します。またまた[Environment Variables]のVersionタグも書き換えます。
以下のように[Image]欄が変わっている事を確認して、[Create]ボタンをクリックします。
すると以下のように、タスク定義"website"に、元々あったタスク定義"website:1"とは別に"website:2"が作成されます。
コンテナを入れ替える
対象のクラスタを選択し、[Services]タブで該当サービスを選択して、[Update]ボタンをクリックします。
Serviceの[Task Definition]を、新しいシステムのタスク定義である"website:2"に変更し、[Update Services]ボタンをクリックします。
この状態では、まだ古いタスクが動いたままになっていますので、クラスタの[Tasks]タブで[Stop All]ボタンをクリックします。
確認画面が表示されるので[Yes, Stop]ボタンをクリックします。
しばらく待つと、新しいタスク(website:2)が動き始めます。
ELBにアクセスすると、ちゃんとWebコンテンツがバージョンアップしてますね!
さいごに
安全なシステムバージョンアップを行うのであれば、もう1つクラスタを用意して、Blue-Green Deployment構成とするのが良いと思いますが、単純にシステムを最新化したい(=Dockerコンテナを入れ替えたい)だけなのであれば、ECS管理コンソールから数クリックで出来ちゃいます。やっぱGUIは便利ですね!
今後のECSのバージョンアップにも期待してます!