ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Azure Container Service の Kubernetes に YAML ファイルを使ってデプロイする

前回の記事では、Azure Container Service に Kubernetes を展開し、ASP.NET Core アプリケーションをデプロイしました。
gooner.hateblo.jp

今回は、kubectl の run コマンドを使わずに、YAML ファイルを使ってデプロイしてみます。元ネタは、こちらの公式ドキュメントになります。

デプロイに関連する用語

Pod

Pod は、複数のコンテナをまとめて管理できます。Pod 内のコンテナは同じホストにデプロイされるため、複数のコンテナでディレクトリなどを共有できます。
f:id:TonyTonyKun:20170410091436p:plain

Replica Set

Replica Set は、Pod のレプリカを管理します。常時レプリカを監視しているので、障害が発生したら Pod を破棄して、新しい Pod を立ち上げてくれます。
f:id:TonyTonyKun:20170410091516p:plain

Deployment

Deployment は、Replica Set を管理します。Replica Set の状態を履歴として管理しているので、更新やロールバックを行うことができます。
コンテナの Image バージョンを更新する Kubectl コマンドを実行すると、新しい Replica Set B が作成され、古い Replica Set A は破棄されます。
f:id:TonyTonyKun:20170410092559p:plain
Deployment は、Replica Set を宣言的に定義でき、ロールアウト履歴なども管理できるため、次世代 Replication Controller と呼ばれています。

Deployment の作成

3つの nginx の Pod を持つ Replica Set を管理する Deployment を作成する場合には、以下のような YAML ファイルを定義します。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80

Azure Container Service に SSH 接続して、kubectl の create コマンドを実行します。今回は、YAML ファイルを GitHub で管理しています。

$ git clone https://github.com/thara/k8s-samples.git
$ cd k8s-samples
$ kubectl create -f nginx/deployment-nginx.yaml --record
deployment "nginx-deployment" created

パラメータの「--record」は必須ではありませんが、指定することで kubectl コマンドの実行履歴を記録できます。
Deployment、Replica Set、Pod が作成された結果を確認します。

$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           1m

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3450387708   3         3         3         1m

$ kubectl get pods --show-labels
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-3450387708-06x07   1/1       Running   0          2m        app=nginx,pod-template-hash=3450387708
nginx-deployment-3450387708-dv8sq   1/1       Running   0          2m        app=nginx,pod-template-hash=3450387708
nginx-deployment-3450387708-g7v2b   1/1       Running   0          2m        app=nginx,pod-template-hash=3450387708

Deployment の更新

Pod で使われている Image を更新する場合には、以下のような YAML ファイルを定義します。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.11 # Update the version of nginx from 1.10 to 1.11
        ports:
        - containerPort: 80

GitHub から更新した YAML ファイルを Pull した後、kubectl の apply コマンドを実行します。

$ git pull
$ kubectl apply -f nginx/deployment-nginx.yaml --record
deployment "nginx-deployment" configured

Replica Set と Pod が更新された結果を確認します。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3450387708   0         0         0         20m
nginx-deployment-3531652349   3         3         3         7m

$ kubectl get pods --show-labels
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-3531652349-7wrw8   1/1       Running   0          7m        app=nginx,pod-template-hash=3531652349
nginx-deployment-3531652349-chpw0   1/1       Running   0          7m        app=nginx,pod-template-hash=3531652349
nginx-deployment-3531652349-g2fqc   1/1       Running   0          7m        app=nginx,pod-template-hash=3531652349

古い Replica Set(nginx-deployment-3450387708)の Pod が破棄され、新しい Replica Set(nginx-deployment-3531652349)の Pod が作成されたことが分かります。

Deployment の履歴

kubectl の rollout history コマンドで実行履歴を確認してみます。

$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION        CHANGE-CAUSE
1               kubectl create -f nginx/deployment-nginx.yaml --record
2               kubectl apply -f nginx/deployment-nginx.yaml --record

履歴の一覧を表示する以外にも、特定の Revision の履歴を確認することもできます。

$ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" with revision #2
  Labels:       app=nginx
        pod-template-hash=3531652349
  Annotations:  kubernetes.io/change-cause=kubectl apply -f nginx/deployment-nginx.yaml --record
  Containers:
   nginx:
    Image:      nginx:1.11
    Port:       80/TCP
    Volume Mounts:      <none>
    Environment Variables:      <none>
  No volumes.

$ kubectl rollout history deployment/nginx-deployment --revision=1
deployments "nginx-deployment" with revision #1
  Labels:       app=nginx
        pod-template-hash=3450387708
  Annotations:  kubernetes.io/change-cause=kubectl create -f nginx/deployment-nginx.yaml --record
  Containers:
   nginx:
    Image:      nginx:1.10
    Port:       80/TCP
    Volume Mounts:      <none>
    Environment Variables:      <none>
  No volumes.

Pod で使われている nginx の Image が更新されたことが分かります。

Deployment のロールバック

Deployment の更新後に予期せぬ問題が発生し、切り戻したいこともあるでしょう。kubectl の rollout undo コマンドでロールバックしてみます。

$ kubectl rollout undo deployment/nginx-deployment
deployment "nginx-deployment" rolled back

Replica Set と Pod がロールバックされた結果を確認します。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3450387708   3         3         3         32m
nginx-deployment-3531652349   0         0         0         19m

$ kubectl get pods --show-labels
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-3450387708-0jmtc   1/1       Running   0          1m        app=nginx,pod-template-hash=3450387708
nginx-deployment-3450387708-rvrn9   1/1       Running   0          1m        app=nginx,pod-template-hash=3450387708
nginx-deployment-3450387708-wsnw7   1/1       Running   0          1m        app=nginx,pod-template-hash=3450387708

新しい Replica Set(nginx-deployment-3531652349)の Pod が破棄され、古い Replica Set(nginx-deployment-3450387708)に新しい Pod が作成されたことが分かります。
1つ前の Revision だけでなく、特定の Revision にロールバックすることも可能です。

まとめ

今回は、kubectl の run コマンドを使わずに、YAML ファイルを使ってデプロイしてみました。
kubernetes にコンテナをデプロイして運用するには、Deployment や Replica Set の概念を理解しておく必要があります。YAML ファイルに定義することで、デプロイ環境の作成や破棄が簡単にできますし、kubernetes 側で宣言的な Pod の構成を維持してくれます。
次回は、ボリュームをマウントすることで、コンテナ間で共有したり永続化する方法を試してみたいと思います。
gooner.hateblo.jp