GCP Dockerクラスタで無停止デプロイを実現する設定ガイド

プロダクションレベルのCI/CD、コンテナオーケストレーション、自動フェイルオーバーの実践ガイド

本番環境へのソフトウェアアップデートのデプロイは、本来何事もなく完了するごく普通のプロセスであるべきです。しかし現実には、モノリシックなサーバーの再起動、未処理のデータベースマイグレーション、不適切なロードバランシングによって、サービスの停止、WebSocket切断、502 Gateway Errorなどの障害が頻繁に発生しています。

真のゼロダウンタイムデプロイメント(無停止デプロイ)を実現するには、アプリケーション実行環境の分離、継続的デリバリー(CD)の自動化、そしてダウンタイムゼロのトラフィックルーティングの実装が不可欠です。以下に、Google Kubernetes Engine(GKE)、Artifact Registry、GitHub Actionsを活用し、Google Cloud Platform(GCP)上で本番運用に耐えうるDockerクラスタを構築するための設計ブループリントを示します。

ゼロダウンタイムデプロイメントのアーキテクチャ

flowchart TD
    subgraph CI_CD["CI/CD パイプライン"]
        GA["GitHub Actions"] -->|Workload Identity 認証| GAR["Artifact Registry"]
        GA -->|イメージのビルド & プッシュ| GAR
        GA -->|Rolling Update のトリガー| GKE_Master["GKE Control Plane"]
    end

    subgraph GCP_Cloud["GCP ネットワーク & クラスタ"]
        LB["Cloud Load Balancing"]
        
        subgraph GKE_Cluster["GKE Cluster - production"]
            subgraph Active_Pods["稼働中の Pods (旧バージョン)"]
                Pod1["Pod v1.0<br/>Readiness: 200 OK"]
                Pod2["Pod v1.0<br/>Readiness: 200 OK"]
            end
            
            subgraph New_Pods["新規作成 Pods (新バージョン)"]
                Pod3["Pod v1.1<br/>Readiness: 起動中/検証中"]
                Pod4["Pod v1.1<br/>Readiness: 200 OK"]
            end
        end
    end

    Client["クライアント / トラフィック"] -->|HTTPS| LB
    LB -->|100% のアクティブトラフィックをルーティング| Active_Pods
    LB -.->|Readiness Pass 後に順次切り替え| Pod4
    GKE_Master -->|preStop sleep 10s & SIGTERM| Active_Pods

1. コンテナ化 ベストプラクティス (Dockerfile)

無停止デプロイはコンテナレイヤーの設計から始まります。コンテナは終了シグナル(SIGTERM)を適切にハンドリングし、プロセス終了前に実行中のアクティブなリクエスト処理を正常に完了させる必要があります。

dockerfile
# イメージサイズと攻撃表面(Attack Surface)を最小化するマルチステージビルドnFROM node:20-alpine AS buildernWORKDIR /appnCOPY package*.json ./nRUN npm cinCOPY . .nRUN npm run buildnnFROM node:20-alpine AS runnernWORKDIR /appnENV NODE_ENV=productionnn# クラウドセキュリティ標準に準拠した非rootユーザーでの実行nRUN addgroup u002du002dsystem u002du002dgid 1001 nodejs u0026u0026 adduser u002du002dsystem u002du002duid 1001 appusernCOPY u002du002dfrom=builder /app/dist ./distnCOPY u002du002dfrom=builder /app/node_modules ./node_modulesnCOPY package.json ./nnUSER appusernEXPOSE 3000nn# Node.jsにおけるSIGTERMシグナルのグレースフルハンドリングnCMD [u0022nodeu0022, u0022dist/server.jsu0022]

2. Kubernetes デプロイメント設定 (deployment.yaml)

GCPが起動中または終了処理中のコンテナへトラフィックをルーティングするのを完全に防ぐため、Rolling Updates(ローリングアップデート)、Liveness Probes(生存性確認)、および Readiness Probes(準備完了確認) を設定します。

yaml
apiVersion: apps/v1nkind: Deploymentnmetadata:n  name: isotope-backend-appn  namespace: productionnspec:n  replicas: 4n  strategy:n    type: RollingUpdaten    rollingUpdate:n      maxSurge: 25%        # 古いPodを停止する前に、新しいPodを1つ作成n      maxUnavailable: 0%   # ローリングアウト中も100%の処理能力を維持n  selector:n    matchLabels:n      app: isotope-backendn  template:n    metadata:n      labels:n        app: isotope-backendn    spec:n      containers:n      - name: backend-apin        image: us-central1-docker.pkg.dev/isotope-blue/app-repo/backend:latestn        ports:n        - containerPort: 3000n        resources:n          requests:n            cpu: u0022250mu0022n            memory: u0022512Miu0022n          limits:n            cpu: u0022500mu0022n            memory: u00221024Miu0022n        readinessProbe:n          httpGet:n            path: /healthzn            port: 3000n          initialDelaySeconds: 5n          periodSeconds: 5n        livenessProbe:n          httpGet:n            path: /healthzn            port: 3000n          initialDelaySeconds: 15n          periodSeconds: 10n        lifecycle:n          preStop:n            exec:n              command: [u0022/bin/shu0022, u0022-cu0022, u0022sleep 10u0022] # ロードバランサがPodの規制登録を解除する猶予時間を確保

3. CI/CD パイプラインの自動化 (GitHub Actions)

このパイプラインは、Dockerコンテナのビルド、Workload Identity Federationを使用した安全なGCP認証(静的なサービスアカウントキーの保持は不要)、およびGKEでのローリングデプロイの実行を自動化します。

yaml
name: Deploy Backend to GCP GKEnnon:n  push:n    branches: [ main ]nnenv:n  PROJECT_ID: isotope-bluen  GAR_LOCATION: us-central1n  GKE_CLUSTER: isotope-prod-clustern  GKE_ZONE: us-central1-an  REPOSITORY: app-repon  IMAGE: backendnnjobs:n  setup-build-publish-deploy:n    name: Build and Deploy to GKEn    runs-on: ubuntu-latestn    steps:n    - name: Checkout Coden      uses: actions/checkout@v4nn    - name: Authenticate to Google Cloudn      uses: google-github-actions/auth@v2n      with:n        workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/github-pool/providers/github-provider'n        service_account: 'github-deployer@isotope-blue.iam.gserviceaccount.com'nn    - name: Set up Cloud SDKn      uses: google-github-actions/setup-gcloud@v2nn    - name: Configure Docker for Artifact Registryn      run: |-n        gcloud auth configure-docker ${{ env.GAR_LOCATION }}-docker.pkg.dev u002du002dquietnn    - name: Build and Push Docker Imagen      run: |-n        IMAGE_TAG=${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE }}:${{ github.sha }}n        docker build -t $IMAGE_TAG .n        docker push $IMAGE_TAGnn    - name: Get GKE Credentialsn      uses: google-github-actions/get-gke-credentials@v2n      with:n        cluster_name: ${{ env.GKE_CLUSTER }}n        location: ${{ env.GKE_ZONE }}nn    - name: Deploy Rolling Update to GKEn      run: |-n        IMAGE_TAG=${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE }}:${{ github.sha }}n        kubectl set image deployment/isotope-backend-app backend-api=$IMAGE_TAG -n productionn        kubectl rollout status deployment/isotope-backend-app -n production

4. 無停止リリースにおける運用チェックリスト

  • データベーススキーマのマイグレーション: コードのデプロイを行う前に、必ず後方互換性のあるスキーマ変更(例: 非推奨化する前に新規カラムを追加する等)を先行して実行する。
  • グレースフルシャットダウンの処理: バックエンドコード側でprocess.on('SIGTERM')をキャッチし、10秒間のpreStopウィンドウ内でアクティブなDBプールやコネクションを正常にクローズできるようにする。
  • 無停止ヘルスチェックの実装: /healthz エンドポイントは、KubernetesのReadiness Probeに対して200 OKを返す前に、クリティカルな依存関係(DB接続、Redisキャッシュなど)が正常であることを確認する。

技術解説メルマガ / テクニカルディスパッチ

隔週配信のテクニカルディスパッチをご購読ください。エンタープライズアーキテクチャ、最新のAIエージェントフレームワーク、グロース自動化戦略を詳しく解説します。価値の高いエンジニアリングのインサイトのみをお届けします(スパムは一切ありません)。