Dockerで1.12から追加されswarm modeを使うと別途オーケストレーションツールを使わずとも簡単にブルーグリーンデプロイメントを実現できて便利です。簡単にブルーグリーンデプロイメントする手順を紹介したいと思います。
ブルーグリーンデプロイメントとは本番として使える環境を2環境用意して片方を待機系にしておき、待機系を更新してから環境を切り替えることでデプロイを行う方法です。環境をそれぞれブルーとグリーンと呼びます。
Dockerクラスタの構築とDockerイメージの用意の手順はほぼ説明しません。
必要環境は以下のとおり
- Docker 1.12.1以上
- Nginx
- erb
ざっくり全体像
- Dockerのサービスとしてblueとgreenの2環境を用意します。
- 環境の更新は
docker service update
コマンドで行います - アクティブ環境の切り替えはNginxのupstreamの設定を更新して接続先のサービスを切り替えることで実現します。
#準備作業
##1. クラスタを作ります
チュートリアルを見つつクラスターを作ります。1ノードでも試せますが2ノード以上あった方が雰囲気がでます。
https://docs.docker.com/engine/swarm/swarm-tutorial/
##2. サービスを作成します
Swarmのマネージャーノードでdocker service createコマンドを発行してサービスを作成します。
これでサービスの起動も行われます。
sudo docker service create --replicas 2 --name blue -p 8000:80 <イメージ>
sudo docker service create --replicas 2 --name green -p 8001:80 <イメージ>
<イメージ>の部分にはdocker run
と同じ形式でイメージを指定できます。
--replicas
はコンテナを起動する数、-p
は公開ポートとコンテナ内のポートを指定します。(docker runの-pと同じです)この場合だと8000と8001がノードでDockerの外部に公開されるポートになります。
sudo docker service ls
をしてREPLICASが2/2になっていれば作成完了です。
しばらくしても0/2のままであればサービスの起動に失敗していますので、各ノードのdockerのログなどを確認します。
AWS ECSを使っている場合など、docker login
が必要な場合はあらかじめdocker login
してから--with-registry-auth
オプションを指定します。
docker service create
コマンドには大量のオプションがあり、ほとんどのオプションが後ほど説明するdocker service update
と共通です。一通り眺めておくと良いと思います。
##3. Nginxの設定のテンプレートを用意します
erbでテンプレートを作成します。
環境に応じて接続先を変更します。
<DOCKER_NODEn_IP>
にはDockerクラスタのノードのIPを指定します。
upstream backend {
<% if ENV['SERVICE_ENV'] == 'blue' %>
server <DOCKER_NODE1_IP>:8000;
server <DOCKER_NODE2_IP>:8000;
<% else %>
server <DOCKER_NODE1_IP>:8001;
server <DOCKER_NODE2_IP>:8001;
<% end %>
}
ちなみにここにノードのIPを記述していなくてもコンテナが立ち上がっているノードにはリクエストが飛びます。
これはDockerのSwarmクラスタ自体にロード・バランシング機能が組み込まれているためです。
「docker ingress network」などで検索していただくと仕組みがわかると思います。
##4. Nginxの設定をします
nginx.confを編集して先ほど作成したupstreamにリクエストが向かうようにします。
パッケージ管理システムからNginxをインストールした状態でconf.dが存在する環境であればおそらくnginx-app.confはnginx.confから読まれる設定になっているでしょう。
conf.dからIncludeするようになっていない場合はIncludeする設定をしてください。
server {
...
location / {
proxy_pass http://backend;
}
...
}
##5. アクティブ環境切り替え用のスクリプトを用意する
アクティブ環境更新用のシェルスクリプトを用意します。
Nginxの設定を環境にあわせて更新してからそれを読み込みこます。
export SERVICE_ENV=$1
erb nginx-app.conf.erb > /etc/nginx/conf.d/nginx-app.conf
nginx -s reload
##6. 初期のアクティブ環境を設定します。
手前の手順で作成したシェルスクリプトを使って初期の環境をblueに設定します。
sudo ./set-active-env.sh blue
#デプロイ作業
##1. green環境の更新
ここからデプロイの作業です。現在はblue環境がアクティブな環境なのでgreen環境を更新します。
sudo docker service update --image <新しいイメージ> green
各ノード上で新しいイメージの取得と起動が行われます。
数分待つとgreen環境が更新されます。
下記はよく使いそうなオプションです。service createの時に指定することもできます。
--replicas レプリカ数の変更
--with-registry-auth 認証情報のノードへの引き継ぎ(docker loginを使う環境では必須)
--update-parallelism 同時に更新を行うサーバー数
##2. アクティブ環境をgreenに変更
準備のところで作成したシェルスクリプトを使ってgreen環境に変更します。
sudo ./set-active-env.sh green