最近は暑いのでめっきり外に出なくなりましたが、相変わらずDevOpsのOpsばっかりやっています。
さて、今やってるプロジェクトではAmazon EC2 Container Service(ECS)で完全にDockerベースでの開発をしています。本番運用を見越したオペレーションの作り込みをやってるわけですが、今回はBlue-Green Deploymentを実現してみたよってお話。
材料
必要な材料は以下の通り。
- VPC
- Route53
- EC2
- ELB
- AutoScaling Group
- ECS
方式
最近ELBがAutoScaling Group単位での切り替えができるようになったので、これを利用します。基本的に構成はクラスメソッドさんが紹介されたエントリを参考にさせていただきました。
Auto Scaling環境でのBlue-Green Deploymentの切替がAWS ELBでできるようになりました。 | Developers.IO
というわけで今回構築した構成がこちら。
簡単に説明すると
- BlueとGreenのEC2 AutoScaling Groupをつくる
- ECSでBlueとGreen用のClusterをつくる
- AutoScaling GroupでLaunchされるEC2はECSのクラスタにジョインさせる(userdataで定義すれば勝手にジョインされる)
- ECS Cluster上ではTask(Dockerコンテナの集合)を稼働させる
- Primary ELB(ユーザーから参照される方)にぶら下がるAutoScaling Groupが現在の稼動系
- 稼働してないAutoScaling GroupにはStandbyがぶらさがり、ELBの切り替えによってBlueとGreenを切り替える
というオペレーションです。
ecs-formation
今回はこの流れを実現するためにecs-formationというツールを書きました。
以下の機能をサポートしています。まあどんな感じかはREADMEをご覧あれ。
- docker-composeライクなTask Definitionの定義
- ECSのServiceの更新
- Blue-Green Deployment
Task Definition
docker-compose.ymlを拡張してmemoryとかcpu_unitsとかの定義ができるようにしてます。
nginx:
image: nginx:latest
ports:
- 80:80
environment:
PARAM1: value1
PARAM2: value2
links:
- api
memory: 512
cpu_units: 512
essential: true
Service
Serviceはいわゆるスケジューラーのことで、指定したTask数(desired_count)分のタスクをクラスタ上で走らせるようコントロールします。これも以下のように定義できます。
test-service:
task_definition: test-definition
desired_count: 2
Blue-Green Deployment
Blue-Grenn Deploymentは以下のように定義します。
blue:
cluster: test-blue
service: test-service
autoscaling_group: test-blue-asg
green:
cluster: test-green
service: test-service
autoscaling_group: test-green-asg
primary_elb: test-elb-primary
standby_elb: test-elb-standby
あとはecs-formation bluegreen apply Blue-Grenn定義名
みたいな感じでコマンド打つとBlue-Greenの切り替えが起こります。この処理ではELBの切り替えと、次に稼働系統となる方のECSクラスタの更新を行います。
ChatOps
今のプロジェクトではdeployをSlack → CircleCI経由で行ってます。Blue-Greenも同様です。
Slackでこんな感じで指示すると・・・
CircleCIが走りだして・・・
(途中省略・・・、Serviceの起動確認等が行われる)
切り替わったっぽい。めでたしめでたし。