no-image

Dockerのみでお手軽ロードバランシング&(ほぼ)0ダウンタイムデプロイ

Dockerを結構本番運用をガッツリやる会社もよく聞くようになってきた気がします。

で、大体その手の話を聞くと、本番はいかに安定したシステムとネットワークを構築することが肝になるため、

k8sAnsibleCoreOSRancherOS
コンテナなクラウドサービスの話になったりして・・・

これ以上その分野まで覚えようとすると大変すぎるし、自分はまあインフラエンジニアではないのでそこまではあまり興味が無かったりします。

そもそも、そこまでやるとするとかなりの知識が要りますし、かなり大変な作業となると思います。

でも、自分としてちゃんと問題なく動き、HTTPでロードバランシングでき、ダウンタイム0でのデプロイを実現できるWebシステムを構築したいわけです。
Dockerのみで。

このあたり、Webであればnginx-proxyで普通に行けるということを最近知りました。
しかも、めっちゃお手軽。

jwilder/nginx-proxyは主に複数のドメインを区切って同一サーバで複数のサービスを動かす目的として使用されています。
SSLなどもこれでリバースプロキシできるため、開発などのコンテナ作成時はかなりありがたい存在です。

jwilder/whoamiは、Webサーバで自分のコンテナIDを表示するDockerコンテナです。
ちゃんとロードバランシング出来ているかどうか非常にわかりやすいので使用しています。

で、実はこれ、同じドメインを複数のDockerに設定するとどうかというと、なんとそのままnginxの機能でhttpロードバランシングを組んでくれます。
実装例はこんな感じ。これだけです。

見ての通りですが、ロードバランシング対象のサーバを同じバーチャルホストで増やすだけです。

この状態でlocalhost:8000にアクセスしてみると・・・
普通に上手くバランシングして切り替わっていることがわかるはずです。

そして(ほぼ)ダウンタイム0デプロイですが、これは単純に対象の1つのコンテナを消して、新しく作りなおすという話です。
jwilder/nginx-proxyには、Dockerのsocketを見てコンテナが存在するかどうかを確認し、都度勝手に設定してくれる機能があります。
つまり、1つのサーバを止めるとそれを検知し、接続サーバから外してくれるということです。
(ほぼ)の理由として、nginx-proxyにあるnginxのリスタートが発火するからです。しかし本当に一瞬だとは思います。

新バージョンのサービスに切り替えたい時は、1つ消して新しくする、を個数分繰り返すだけです。
全てのサービスが停止されない限り、使用できない状態は無い、ということです。

また、nginx-proxyの中身を見てみましたが、こんな感じに書かれます。

普通にnginxのラウンドロビンでのロードバランシングとなります。
完全に自動で生成してくれるのはいいですね・・・。

1秒ごとにcurlを打つスクリプトを組んでみましたが、タイムアウトやエラーになることはありませんでした。
これでdockerだけでHTTPロードバランシング&(ほぼ)ダウンタイム0デプロイが実現できました。
個人用レベルであれば、普通にこれで本番運用も十分行けると思います。