Azure Container Service で Managed Disk を使いたいと思って調べていた時に、Azure Container Service Engine のサンプルに引っかかったので、いろいろと調べてました。
ちょっと前にオープンソース化された ACS Engine ですが、いい感じに ARM Template を作ってくれるだけのコンポーネントで、ECS Agent とは全く異なるものでした。
サンプルの中に Kubernetes のエージェントとして Windows と Linux を同時に扱うものがあったので、面白そうだったので実際にデプロイしてみました。
ACS Engine の準備
まず ACS Engine のリポジトリをクローンしてきます。ドキュメントに書いてあるように Docker を使った方が楽なのでおすすめです。
acs-engine/acsengine.md at master · Azure/acs-engine · GitHub
Docker の環境が出来ていれば devenv.sh を実行して、初回のみ make build を行います。
./script/devenv.sh make build
これでボリュームがマウントされた ACS Engine の Docker 環境にログインされるので、後は ARM Template を生成すれば終わりです。今回使うのは kubernetes-hybrid.json というファイルです。
acs-engine/kubernetes-hybrid.json at master · Azure/acs-engine · GitHub
dnsPrefix やサービスプリンシパルなどの情報が抜けてるので、acs-engine の実行前に埋めておきます。デフォルトでは Windows と Linux で 2 つずつインスタンスが作られるので注意。
JSON の修正が終われば、そのファイルを acs-engine に食わせるだけです。
./acs-engine ./example/windows/kubernetes-hybrid.json
実行すると Kubernetes のデプロイに必要な証明書など、いろいろと作成してくれます。
Azure へのデプロイに必要な azuredeploy.json と azuredeploy.parameters.json も作成されているので、次はこのファイルと Azure CLI を使ってデプロイを行います。
Azure にデプロイ
デプロイには Azure CLI 2.0 を使いました。手順としては Resource Group を作成して、その Group に対して ARM Template を指定してデプロイを行う形です。
Resource Group や Location は適宜読み替えてほしいですが、大体 2 行で処理は終わります。
az group create --name "Container-RG" --location "Japan West" az group deployment create --name "kubernetes" --resource-group "Container-RG" \ --template-file "./azuredeploy.json" --parameters "@./azuredeploy.parameters.json"
parameters に指定するパスの前に付いている @ は必要なので忘れないように。地味にはまりました。
デプロイを実行すると、大量のリソースが作成されます。ACS 自体はリソースとして作成されないです。
これまでと同じように kubectl を使って Kubernetes ダッシュボードからノードを確認しておきます。
名前の付け方やラベルに多少の違いはありますが、1 つの Kubernetes 内で Windows と Linux のノードが動作しています。実は ACS で作ったものより、Kubernetes のバージョンが新しいです。
クラスタが完成したので、実際にアプリケーションをデプロイして確認してみます。
アプリケーションをデプロイ
Windows ノードにデプロイするのは IIS なので、Azure の Kubernetes ドキュメントから拾ってきた YAML をほぼそのまま利用します。変更点としてはイメージを microsoft/iis に変えただけです。
apiVersion: v1 kind: Service metadata: name: win-webserver labels: app: win-webserver spec: ports: - port: 80 targetPort: 80 selector: app: win-webserver type: LoadBalancer --- apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: app: win-webserver name: win-webserver spec: replicas: 1 template: metadata: labels: app: win-webserver name: win-webserver spec: containers: - name: windowswebserver image: microsoft/iis nodeSelector: beta.kubernetes.io/os: windows
これとほぼ同じ内容でイメージを nginx に、nodeSelector を linux に変更したものを Linux ノードにデプロイするために用意しました。
YAML をアップロードしてデプロイを行うと、あっさりと Windows と Linux のデプロイが作成されます。
ちょっと不思議な光景ですが、上手く扱えば開発の自由度向上と運用の手間を削減できそうです。
それぞれのポッドが作成完了になった後に、外部エンドポイントにアクセスするとデフォルトのページが表示されます。イメージのサイズが違うので仕方ないのですが、IIS の方が数倍時間がかかりました。*1
同じネットワーク内にいるので、コンテナ間での通信も問題ないです。サービス名だけで繋がります。
kubectl exec を使うことで、Windows と Linux のポッドに接続できるので、それを使って試しました。
最後に何となく、それぞれのポッドのレプリカを増やして試してみました。
普通の感覚だと 2 ノードでレプリカを 2 つに増やすと、それぞれのノードにデプロイされるはずですが、nodeSelector で OS を指定しているので、ちゃんと同一ノード上にデプロイされました。
実行環境は全て 1 つの Kubernetes にまとめてしまって、ネームスペースで Production / Staging など区別し、アプリケーションは OS 問わず同じクラスタに乗せてしまうというのもありかもしれません。
*1:しかも Windows は Premium Storage を使っているというのに