AKS を使いこなす : チュートリアルの深堀り - アプリケーションの更新

今回は[チュートリアル:Azure Kubernetes Service (AKS) でのアプリケーションの更新](https://docs.microsoft.com/ja-jp/azure/aks/tutorial-kubernetes-app-update)の深堀をしていきます。

このチュートリアルではアプリケーションのバージョンを v1 から v2 にした場合、どのように展開できるかを見ていきます。

# アプリケーションの更新

まずはアプリケーションを更新して v2 を作成し、ACR にプッシュします。

1\. azure-vote 内の config_file.cfg の内容を変更。ここではタイトルを変更。

```config
# UI Configurations
TITLE = 'Azure Voting App v2'
VOTE1VALUE = 'Cats'
VOTE2VALUE = 'Dogs'
SHOWHOST = 'false'
```

2\. ```docker-compose``` でイメージを再度ビルドし、ローカルで実行。 

```shell
docker-compose up --build -d
docker-compose up
```
3\. ブラウザで http://localhost:8080 にアクセスして変更を確認。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/a9285280-8132-333d-f01a-da5e10ed6c2c.png"/>

4\. 新しいバージョンのタグをつけて ACR にプッシュ。

```shell
docker tag azure-vote-front kenakamuacr.azurecr.io/azure-vote-front:v2
az acr login -n kenakamuacr
docker push kenakamuacr.azurecr.io/azure-vote-front:v2
```
5\. ACR に追加されていることを確認。

```shell
> az acr repository show-tags --name kenakamuacr --repository azure-vote-front --output table
Result
--------
v1
v2
```

# 新しいバージョンの展開

## チュートリアルの手順

1\. ポッドの状態を監視。

```shell
kubectl get nodes -o wide --watch
```

2\. 別のシェルよりデプロイメントに対してイメージのタグを更新。

```shell
kubectl set image deployment azure-vote-front azure-vote-front=kenakamuacr.azurecr.io/azure-vote-front:v2                               
```
3\. 元のシェルでポッドの変化を確認。

- v1 ポッドが停止され v2 ポッドが起動していることを確認

```shell
NAME                                READY   STATUS              RESTARTS   AGE   IP           NODE                       NOMINATED NODE   READINESS GATES
azure-vote-back-847fc9bcb9-p7m9x    1/1     Running             0          8h    10.244.1.2   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-4r8sf   0/1     ContainerCreating   0          3s    <none>       aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-5cb78cfd57-tpzw2   0/1     ContainerCreating   0          4s    <none>       aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-c857778b-6px8s     1/1     Running             0          97m   10.244.1.5   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-97mz2     1/1     Terminating         0          97m   10.244.1.4   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-ttlx2     1/1     Running             0          8h    10.244.1.3   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-97mz2     0/1     Terminating         0          97m   10.244.1.4   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-4r8sf   1/1     Running             0          5s    10.244.0.12   aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-5cb78cfd57-tpzw2   1/1     Running             0          6s    10.244.0.11   aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-c857778b-97mz2     0/1     Terminating         0          98m   10.244.1.4    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-97mz2     0/1     Terminating         0          98m   10.244.1.4    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-vtsk6   0/1     Pending             0          0s    <none>        <none>                     <none>           <none>
azure-vote-front-c857778b-6px8s     1/1     Terminating         0          98m   10.244.1.5    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-vtsk6   0/1     Pending             0          0s    <none>        aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-ttlx2     1/1     Terminating         0          8h    10.244.1.3    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-vtsk6   0/1     ContainerCreating   0          0s    <none>        aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-ttlx2     0/1     Terminating         0          8h    <none>        aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-6px8s     0/1     Terminating         0          98m   10.244.1.5    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-vtsk6   1/1     Running             0          5s    10.244.1.6    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-ttlx2     0/1     Terminating         0          8h    <none>        aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-ttlx2     0/1     Terminating         0          8h    <none>        aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-6px8s     0/1     Terminating         0          98m   10.244.1.5    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-6px8s     0/1     Terminating         0          98m   10.244.1.5    aks-nodepool1-34717040-0   <none>           <none>
```

4\. 展開完了後現在の状態を確認。

```shell
> kubectl get pods -o wide                                                          NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE                       NOMINATED NODE   READINESS GATES
azure-vote-back-847fc9bcb9-p7m9x    1/1     Running   0          8h      10.244.1.2    aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-5cb78cfd57-4r8sf   1/1     Running   0          3m16s   10.244.0.12   aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-5cb78cfd57-tpzw2   1/1     Running   0          3m17s   10.244.0.11   aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-5cb78cfd57-vtsk6   1/1     Running   0          3m6s    10.244.1.6    aks-nodepool1-34717040-0   <none>           <none>
```
5\. サービスからロードバランサー IP を取得してアプリケーションをテスト。

```shell
> kubectl get services azure-vote-front                                             NAME               TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
azure-vote-front   LoadBalancer   10.0.10.225   20.43.78.36   80:32491/TCP   8h
```
## k8s での動作を確認

デプロイメントのイメージを更新したため、デプロイメントと関連するレプリカセットに影響があります。

1\. デプロイメントでイメージが更新されていることを確認。

```shell
> kubectl get deployments -o wide azure-vote-front
NAME               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS         IMAGES                                       SELECTOR
azure-vote-front   3/3     3            3           8h    azure-vote-front   kenakamuacr.azurecr.io/azure-vote-front:v2   app=azure-vote-front
```
2\. レプリカセットを取得。

- v1 と v2 の両方が存在
- v2 のハッシュが ```5cb78cfd57``` であることを確認。

```shell
> kubectl get replicasets -o wide -l app=azure-vote-front                           NAME                          DESIRED   CURRENT   READY   AGE     CONTAINERS         IMAGES                                       SELECTOR
azure-vote-front-5cb78cfd57   3         3         3       7m43s   azure-vote-front   kenakamuacr.azurecr.io/azure-vote-front:v2   app=azure-vote-front,pod-template-hash=5cb78cfd57
azure-vote-front-c857778b     0         0         0       8h      azure-vote-front   kenakamuacr.azurecr.io/azure-vote-front:v1   app=azure-vote-front,pod-template-hash=c857778b
```
3\. ```describe``` でデプロイメントの詳細を取得。イベントでどのようにポッドが展開されたか確認。

```shell
kubectl describe deployments azure-vote-front 
```
- v2 をスケールアップで 1 ポッド追加
- v1 をスケールダウンで 1 ポッド削除
- 後も同じように 1 つずつ追加を削除を繰り替えし

```shell
Events:
  Type    Reason             Age                From                   Message
  ----    ------             ----               ----                   -------
  Normal  ScalingReplicaSet  8m41s              deployment-controller  Scaled up replica set azure-vote-front-5cb78cfd57 to 1
  Normal  ScalingReplicaSet  8m40s              deployment-controller  Scaled down replica set azure-vote-front-c857778b to 2
  Normal  ScalingReplicaSet  8m40s              deployment-controller  Scaled up replica set azure-vote-front-5cb78cfd57 to 2
  Normal  ScalingReplicaSet  8m30s              deployment-controller  Scaled down replica set azure-vote-front-c857778b to 0
  Normal  ScalingReplicaSet  8m30s              deployment-controller  Scaled up replica set azure-vote-front-5cb78cfd57 to 3
```
展開がポッド 1 つずつ処理される理由は、デプロイメントのローリングアップデートの定義が以下のように設定されているため。

- Max Unavailable: 無効にできるポッドの最大数
- Max Surge: Desired を超えられるポッドの数

```yaml
RollingUpdateStrategy:  1 max unavailable, 1 max surge
```
## マニフェストを使った展開

マニフェストを変更して ```kubectl apply``` をしても同じ効果を得られる。

# まとめ

アプリケーションの更新も、新規の展開とほぼ同じで実行できますが、ローリングアップデートの定義が動作に大きな影響を与える点が重要となります。また問題が発生した場合のロールバックも使い方を学ぶ必要がありますが、こちらは別の機会に紹介します。

チュートリアルでは最後にクラスタのアップグレードと削除がありますが、こちらの記事ではまだクラスタを更新したり削除したくないため、一旦ここまでで完了とします。

[目次に戻る](https://qiita.com/kenakamu/items/e155740aa60c85a3d867)

# 参考

[Updating a Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment)