しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

AppVeyor から Azure Container Service 上の Kubernetes へ自動でデプロイを行う

これまで AppVeyor と Kubernetes でやってきたことの集大成として、AppVeyor から Azure Container Service 上の Kubernetes への自動デプロイを試してみます。

やってきたことは以下のエントリを参照してください。Kubernetes はかなり良いですね。

AppVeyor から Kubernetes にデプロイするためには、認証情報が必要なので先に作成しておきます。

Service Account Token を取得

トークンを作成するためには kubectl を使って Service Account をまず作成する必要があります。

kubectl create serviceaccount appveyor

コマンドで Service Account を作成したら、ダッシュボードでトークンを確認できるので簡単です。

コンフィグの中にあるシークレットから、Base64 デコード済みのトークンをコピーできます。

f:id:shiba-yan:20170503210641p:plain

作成はコマンドで作りますが、削除と編集はダッシュボードから簡単に行えるのがアンバランスでした。

appveyor.yml に処理を追加

現在の Kubernetes ダッシュボードは以下のようになっています。基本的にアップデートを行うだけなので、予めアプリケーションはデプロイしてあります。

f:id:shiba-yan:20170503211019p:plain

appveyor.yml には kubectl のダウンロードと、イメージの更新コマンドを追加します。

version: '{build}'

image: Visual Studio 2017

environment:
  DOCKER_USER: XXXXX
  DOCKER_PASS:
    secure: XXXXX
  DOCKER_IMAGE_NAME: shibayan/appveyor-aspnet-docker:$(APPVEYOR_REPO_BRANCH)-$(APPVEYOR_BUILD_NUMBER)
  KUBE_MASTER: https://XXXXX
  KUBE_TOKEN:
    secure: XXXXX

install:
  - curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.6.2/bin/windows/amd64/kubectl.exe

before_build:
  - nuget restore

build_script:
  - msbuild .\AspNetApplication\AspNetApplication.csproj /nologo /verbosity:m /t:Build /t:pipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempDir="..\publish";AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release
  - docker build -t %DOCKER_IMAGE_NAME% .

test_script:
  - ps: |
      $cid = docker run -d $env:DOCKER_IMAGE_NAME
      $hostip = docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" $cid
      curl "http://${hostip}" -UseBasicParsing

deploy_script:
  - docker login -u %DOCKER_USER% -p %DOCKER_PASS%
  - docker push %DOCKER_IMAGE_NAME%
  - kubectl set image deployment/aspnet aspnet=%DOCKER_IMAGE_NAME% --server=%KUBE_MASTER% --token=%KUBE_TOKEN% --insecure-skip-tls-verify=true

kubectl は curl でダウンロードするだけなので簡単です。現在のデプロイメントに対してイメージを更新するコマンドは kubectl set image になります。

オプションとして --server と --token を追加して、Kubernetes のマスターの URL とさっき作成したトークンを渡します。証明書の検証が問題になるので --insecure-skip-tls-verify=true を指定してスキップします。

AppVeyor で実際にビルド

appveyor.yml の修正を GitHub にコミットして、実際に AppVeyor でビルドを行いました。kubectl の実行結果から成功したことが分かります。たったこれだけでアップデートが行われます。

f:id:shiba-yan:20170503211728p:plain

アップデート中にダッシュボードを確認すると、新しいレプリカセットとポッドが作成されています。

既にベースイメージは pull されているので、コンテナの起動は非常に高速です。

f:id:shiba-yan:20170503211656p:plain

アップデートが完了したら、ブラウザで外部エンドポイントにアクセスしてみます。アプリケーションに違いがないと、本当にアップデートが行われたのか確認しにくいので、テキストを少しだけ変えておきました。

例によって Razor のプリコンパイルを行っていないので、起動に少し時間がかかりますが表示されます。拍子抜けするぐらいあっさりと AppVeyor からのデプロイが行えました。

f:id:shiba-yan:20170503211807p:plain

ちなみに GitHub に push してから AppVeyor でのビルドが完了するまで 2 分ほどです。Docker Hub よりネットワーク的に近い Azure Container Registry を使うと pull は早くなりそうです。

今回は 1 エージェントかつ 1 レプリカで試しましたが、Kubernetes はまだ VMSS に対応していないみたいなので、エージェントを増やす手間がかかります。レプリカに関しては別の機会にまとめます。