Lab 4: ローリングアップデート

このラボでは、Deploymentのローリングアップデートでアプリケーションを無停止で更新し、問題が発生した場合のロールバック方法を学びます。

1. 初期バージョンのデプロイ

hello-app のバージョン1.0をデプロイします。このイメージはレスポンスにバージョン番号を含むので、アップデートの確認に適しています。

cat << 'EOF' > hello-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
  labels:
    app: hello-app
spec:
  replicas: 4
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080
EOF

kubectl apply -f hello-deployment.yaml

2. Serviceの作成とアクセス確認

cat << 'EOF' > hello-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-svc
spec:
  selector:
    app: hello-app
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080
  type: NodePort
EOF

kubectl apply -f hello-service.yaml

# バージョン1.0が表示されることを確認
curl http://localhost:30080

レスポンスに Version: 1.0.0 と表示されるはずです。

3. ローリングアップデートの実行

イメージをバージョン2.0に更新します。

# イメージを更新
kubectl set image deployment/hello-app hello-app=gcr.io/google-samples/hello-app:2.0

# アップデートの進行状況を確認
kubectl rollout status deployment/hello-app
💡 ローリングアップデートの動作: Kubernetesは新しいPodを少しずつ起動し、古いPodを少しずつ終了させます。これにより、サービスを中断することなくアプリケーションを更新できます。

4. アップデートの確認

# バージョン2.0に変わったことを確認
curl http://localhost:30080

# ReplicaSetの状態を確認(新旧2つのReplicaSetがある)
kubectl get replicasets -l app=hello-app

# Podのイメージを確認
kubectl get pods -l app=hello-app -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

5. ロールアウト履歴の確認

# デプロイ履歴を表示
kubectl rollout history deployment/hello-app

# 特定リビジョンの詳細
kubectl rollout history deployment/hello-app --revision=1
kubectl rollout history deployment/hello-app --revision=2

6. ロールバック

問題が発生した場合、前のバージョンに即座に戻せます。

# 1つ前のバージョンに戻す
kubectl rollout undo deployment/hello-app

# ロールバックの状況を確認
kubectl rollout status deployment/hello-app

# バージョンが1.0に戻ったことを確認
curl http://localhost:30080
💡 ポイント: kubectl rollout undo は前のReplicaSetを再び使うだけなので、非常に高速です。特定のリビジョンに戻すには --to-revision=N を指定します。

7. アップデート戦略の確認

# 現在のアップデート戦略を確認
kubectl get deployment hello-app -o jsonpath='{.spec.strategy}' | python3 -m json.tool
💡 デフォルト設定:
maxSurge: 25% … 更新中に希望レプリカ数を超えて作成できるPodの割合
maxUnavailable: 25% … 更新中に利用不可になってもよいPodの割合

8. クリーンアップ

kubectl delete -f hello-service.yaml
kubectl delete -f hello-deployment.yaml

📝 練習問題

課題: ローリングアップデートとロールバックを練習しましょう。
  1. nginx:1.24 でDeployment web-app(レプリカ数3)を作成する
  2. NodePortService(ポート30088)を作成してアクセスを確認する
  3. イメージを nginx:1.25 に更新し、kubectl rollout status で進行状況を確認する
  4. kubectl rollout history で履歴を確認する
  5. kubectl rollout undo で1.24に戻す
  6. すべてのリソースを削除する

解答例

# 1. Deployment作成
kubectl create deployment web-app --image=nginx:1.24 --replicas=3

# 2. Service作成とアクセス確認
kubectl expose deployment web-app --type=NodePort --port=80 --name=web-app-svc
curl http://localhost:$(kubectl get svc web-app-svc -o jsonpath='{.spec.ports[0].nodePort}')

# 3. イメージ更新
kubectl set image deployment/web-app nginx=nginx:1.25
kubectl rollout status deployment/web-app

# 4. 履歴確認
kubectl rollout history deployment/web-app

# 5. ロールバック
kubectl rollout undo deployment/web-app
kubectl rollout status deployment/web-app

# 6. クリーンアップ
kubectl delete service web-app-svc
kubectl delete deployment web-app

次のラボへ → Lab 5: PersistentVolumeとStatefulSet