はじめに
AKSへのデプロイメントはそれぞれのリソース(AKS, ACR)を作ってしまえば、 kubectl
コマンドを使い簡単に実行することができる。実際の開発において、わざわざコマンドを叩いてデプロイメントを実行するとなると、迅速な機能のリリースができなくなる。したがって、CI/CD pipelineを実装して、AKSへのデプロイを自動化するのが良い。今回の記事では、Azure Pipeline と Github を用いて、docker コンテイナーのAKSへのデプロイメントを自動化してみる。
Azure Kubernetes Service と Azure Container Registry のリソースの作成する。
それぞれのリソースの作り方は、以下の記事で説明している。
Azure Kubernetes Service にコンテイナー化したSpring Bootのアプリをデプロイしてみる - Qiita
Azure DevOpsの作成
Projectの作成
Service connection の追加
Azure DevOps からAzureリソースにアクセスするために、それぞれのリソースごとにservice connection の作成が必要。
Docker Container Registry の service connection の追加
Registry typeでAzure Container Registry を選択すると、別でポップアップウインドウが表示される。ブラウザーでポップアップウインドウをブロックしている場合は出てこないので、設定を変える必要がある。 またブロックしていないにもかかわらず、ポップアップが出てこない場合はブラウザーの更新が解決する場合がある。
ポップアップから、Azureに無事ログインができたら、SubscriptionとAzure Container registryそれぞれのドロップダウンメニューにAzure側のSubscription及び、ACRのリソースが表示される。それぞれ任意のアイテムを選択して、service connection nameを決め、登録する。
Azure Kubernates Service の service connection の追加
Azure Pipeline の作成
今回はGithubと連携して、特定のブランチに新たなコードがプッシュされたらAzure Pipelineを実行するように設定していく。
GithubとAzure Pipelineの連携がされていない場合は自動的にGithubのOAuthページにリダイレクトされるので、要求されているアクセス権を許可する。
Githubとの連携が成功したら、任意のレポジトリを選択する。今回のデモのアプリケーションは、前回のAzure Kubernetes Service にコンテイナー化したSpring Bootのアプリをデプロイしてみるで作ったSpring Bootのアプリケーションと同じもの。実際のGithub repositoryはこちら → https://github.com/ryuichi-f/deploy-aks
k8s/deployaks-app-depl.yml に一箇所だけ変更点がある。spec.template.spec.containers.image にazure container registry のURLとimage ネームを追加した。
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployaks-app-depl
spec:
replicas: 1
selector:
matchLabels:
app: deployaks-app
template:
metadata:
labels:
app: deployaks-app
spec:
containers:
- name: deployaks-app
image: nicetestacr.azurecr.io/deploy-aks # <- 変更
---
apiVersion: v1
kind: Service
metadata:
name: deployaks-app-loadbalancer
spec:
type: LoadBalancer
selector:
app: deployaks-app
ports:
- name: deployaks-port
protocol: TCP
port: 80
targetPort: 8080
pipeline YAMLのテンプレートの選択なので、一番シンプルな Starter pipelineを選ぶ。
pipeline YAML に以下のコードを貼り付ける。そして、”Save and run” をクリック。
trigger:
- main
variables:
ACRServiceConnection: 'niceTestACRServiceConnection'
AKSServiceConnection: 'niceTestAKCServiceConnection'
dockerRegistryURL: 'nicetestacr.azurecr.io'
imageRepo: deploy-aks
tag: '$(Build.BuildId)'
stages:
- stage: build_image
displayName: build an image
jobs:
- job: build_container_image_job
pool:
vmImage: ubuntu-latest
steps:
- task: Docker@2
inputs:
containerRegistry: $(ACRServiceConnection)
repository: '$(imageRepo)'
command: buildAndPush
Dockerfile: '$(Build.SourcesDirectory)/Dockerfile'
buildContext: '$(Build.SourcesDirectory)'
tags: |
$(tag)
- job: publish_k8s_manifest_files_job
pool:
vmImage: ubuntu-latest
steps:
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)/s/k8s'
artifact: 'manifests'
publishLocation: 'pipeline'
- stage: deploy_container
dependsOn: build_image
displayName: deploy a container
jobs:
- job: deployment_job
pool:
vmImage: ubuntu-latest
variables:
aksSecretName: testAKSSecretName
steps:
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
artifactName: 'manifests'
targetPath: '$(Pipeline.Workspace)/manifests'
- task: KubernetesManifest@0
inputs:
action: 'deploy'
kubernetesServiceConnection: $(AKSServiceConnection)
namespace: 'default'
containers: |
$(dockerRegistryURL)/$(imageRepo):$(tag)
manifests: |
$(Pipeline.Workspace)/manifests/deployaks-app-depl.yml
Pipeline YAML のそれぞれのセクションの説明
trigger:
- main
trigger
で指定したブランチにコードが push された際に、Azure pipelineを実行がされる。
variables:
ACRServiceConnection: 'niceTestACRServiceConnection'
AKSServiceConnection: 'niceTestAKCServiceConnection'
dockerRegistryURL: 'nicetestacr.azurecr.io'
imageRepo: deploy-aks
tag: '$(Build.BuildId)'
variables
でpipeline上で使用したい変数を定義できる。定義する場所の階層によって、変数のスコープが変わる。今回はもっとも上の階層で定義したので、すべての階層から変数にアクセスできる。
stages:
- stage: build_image
# 以下省略...
- stage: deploy_container
# 以下省略...
azure pipelineでは、それぞれのプロセスを段階に分けて定義していける。大きく分けて、 stage
, job
step
の3種類ある。その中でも、 stage
は最も上の階層の区分にあたる。今回は、build_image stageとdeploy_container stageの2つを定義している。
jobs:
- job: build_container_image_job
# 以下省略...
- job: publish_k8s_manifest_files_job
# 以下省略...
job
は stage
の区分の中をさらに分けた区分にあたる。それぞれの job
は別々の agent
にパラレルに実行される。
steps:
- task: DownloadPipelineArtifact@2
# 以下省略...
- task: KubernetesManifest@0
# 以下省略...
step
は job
の区分の中をさらに分けた区分にあたる。それぞれのstep
は上から順番に実行される。
- task: Docker@2
inputs:
containerRegistry: $(ACRServiceConnection)
repository: '$(imageRepo)'
command: buildAndPush
Dockerfile: '$(Build.SourcesDirectory)/Dockerfile'
buildContext: '$(Build.SourcesDirectory)'
tags: |
$(tag)
Docker@2
は container registry にimageをビルドしてプッシュを行うためのtask.
- containerRegistry: Azure container registry のservice connectionを指定
- repository: docker dockrtイメージのrepositoryの名前を指定
- command: Docker@2 のコマンドを指定。指定できるコマンドは以下の通り:
- 'buildAndPush' | 'build' | 'push' | 'login' | 'logout' | 'start' | 'stop’
- Dockefile: Docker ファイルの場所の指定。
- buildContext: docker イメージのビルドコンテキストを指定。
- tags: dockerイメージのタグを指定。リストとして複数指定できる。
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)/s/k8s'
artifact: 'manifests'
publishLocation: 'pipeline'
PublishPipelineArtifact@1
は指定したartifact(ファイルなど)を、特定のフォルダーにアップロードするためのタスク。アップロードされたartifactは DownloadPipelineArtifact@2
タスクで別のstage
にダウンロードして、使用することができる。
- inputs:
- targetPath: artifactの場所を指定。
- artifact: artifactを参照するための任意の名前を指定。
- publishLocation: アップロード先の任意のフォルダーの名前を指定。
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
artifactName: 'manifests'
targetPath: '$(Pipeline.Workspace)/manifests'
PublishPipelineArtifact@1
でアップロードされたartifactをダウンロードするためのタスク。
- inputs:
- buildType: artifactのソースのタイプを指定する。 指定できるタイプは以下の通り:
- 'current' | 'specific'
- artifactName:
PublishPipelineArtifact@1
指定したartifactの名前を指定。 - targetPath: アップロードされたartifactの場所を指定。
- buildType: artifactのソースのタイプを指定する。 指定できるタイプは以下の通り:
- task: KubernetesManifest@0
inputs:
action: 'deploy'
kubernetesServiceConnection: $(AKSServiceConnection)
namespace: 'default'
containers: |
$(dockerRegistryURL)/$(imageRepo):$(tag)
manifests: |
$(Pipeline.Workspace)/manifests/deployaks-app-depl.yml
k8s manifestファイルをk8s clusterにデプロイメントするためのタスク。
- inputs:
- action: 合計8個の指定できるアクションがある。それぞれ指定するアクションによって、それ以降の指定できるinputsの種類が変化する。今回は’deploy’アクションを指定する。指定できるアクションは以下の通り:
- 'deploy' | 'promote' | 'reject' | 'createSecret' | 'bake | scale' | 'patch’ | ‘delete’
- namespace: k8sのnamespaceを指定。
- containers: k8s manifestファイルの **
spec.template.spec.containers.image
セクションのdocker イメージURLを置換するためのURLを指定。 - manifest: k8sのmanifestファイルの場所を指定。
- action: 合計8個の指定できるアクションがある。それぞれ指定するアクションによって、それ以降の指定できるinputsの種類が変化する。今回は’deploy’アクションを指定する。指定できるアクションは以下の通り:
Azure pipelineがGithub repositoryの新しいコミットを検知して、自動的にpipelineが実行される。
すべてのステージ及び、ジョブが緑色のチェックマークに変化したらpipelineの実行が無事成功したことになる。次回以降、mainブランチに新しいコードがプッシュされるたびに、pipelineが実行され、アプリケーションがデプロイメントされる。
実際にデプロイされたアプリケーションへのIPアドレスは、AKSリソースの”Services and ingresses”で確認できる。
サービスを確認して、ロードバランサーの EXTERNAL-IP
を確認する。今回の パブリックIPは 20.18.213.108
なので、http://20.18.213.108/hello-world で Spring Boot のアプリケーションにアクセスできる。
おわり
Docker コンテイナーのデプロイメントをAzure Pipelineを用いて自動化することに成功した。一度Pipeline YAML でCI/CDで設定すると、それ以降のデプロイメントがシームレスになるので、迅速な機能のリリースを実現することができる。