Google Kubernetes Engine へのデプロイ:GKE Autopilot vs Standard の比較、CI/CD 構築、リアルなコスト数値

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

6ヶ月運用してわかった — GKE の本番環境での実態

Google Kubernetes Engine で本番ワークロードを運用して約6ヶ月が経った。経験は「嬉しい驚き」と「なぜ誰も教えてくれなかったのか」という瞬間の混在だった。最初のうちは、実際のトレードオフを省いたドキュメントを読みすぎて時間を無駄にしていた。このまとめは、あのとき読みたかった記事だ。

GKE を始める際の核心的な問いはシンプルだ:Autopilot か Standard か?答えは明白ではなく、間違った選択をすると、過剰な費用を払うか、最悪のタイミングで柔軟性を失うことになる。

アプローチ比較:GKE Autopilot vs Standard モード

GKE には根本的に異なる2つの運用モデルがあり、単なる機能の差ではなく、「誰が何を管理するか」という哲学の違いを表している。

Standard モード

ノードプールを自分でプロビジョニングして管理する。マシンタイプ、オートスケーリングのパラメータ、ディスクサイズ、ノード数を自分で決める。Kubernetes は設定通りに動作する。セルフマネージドのクラスターを運用した経験があれば、馴染みのある領域だ。

トレードオフ:ポッドがスケジュールされているかどうかに関わらず、予約したノードの容量分を支払う。e2-standard-4 マシン3台のノードプールは、たとえ深夜2時の実際のワークロードが 6 vCPU しか必要としなくても、24 vCPU と 96GB RAM のコストがかかる。

Autopilot モード

Google が基盤となるノードを完全に管理する。ポッドを定義するだけでよく、ノードプールもマシンタイプの選択も不要だ。課金はポッドの CPU/メモリリクエスト単位で、秒単位で切り上げられる。「自分が所有するノード」が存在しないため、アイドル状態のノード容量に費用はかからない。

トレードオフ:ノードの設定に対するコントロールを失う。一部の DaemonSet は動作せず、特権コンテナは制限され、特定のワークロード(GPU を多用する ML 推論など)は特別な対応が必要になる。

実際の比較数値

典型的な Web バックエンド(3つのマイクロサービス、中程度のトラフィック、ステージング+本番環境)を運用した場合の月額費用はこうなった:

Standard モード(3 × e2-standard-4、常時起動):
  ノードコスト:     ~$180/月(3ノード × $60)
  実際の使用率:  ~35-40% 平均 CPU 使用率
  使用済み vCPU 時間あたりの実効コスト: ~2.8×

Autopilot モード(同じワークロード):
  ポッドリクエスト:  ~$110/月(リクエストした分だけ支払い)
  節約:       ~38%

24/7 で高使用率のワークロードを運用しないチームにとっては、コスト面で Autopilot が優位だ。ノード使用率が継続的に70%以上になった時点で、Standard が再び合理的な選択肢になる。

メリットとデメリット

GKE Autopilot

  • メリット:ノード管理のオーバーヘッドなし — パッチ適用不要、キャパシティプランニング不要、「深夜3時になぜこのノードが NotReady なのか」問題もなし
  • メリット:ポッド単位の課金でアイドル容量の無駄が解消される
  • メリット:セキュリティ強化が組み込み済み(Workload Identity、シールドノード、バイナリ認証)
  • デメリット:Autopilot が基盤インフラをプロビジョニングする必要がある場合、ポッドの起動が遅くなることがある(30〜60秒)
  • デメリット:特権コンテナが使えない — 一部の監視エージェントやレガシーアプリが動作しない
  • デメリット:最低リソースリクエストが強制される(コンテナあたり 0.25 vCPU、0.5GB RAM)— 小さな cronjob がパディングされる

GKE Standard

  • メリット:ノード設定の完全なコントロール — GPU、カスタムマシンタイプ、Spot VM が使用可能
  • メリット:ポッドのスケジューリングが速い(ノードがすでに起動済み)
  • メリット:特権コンテナやカスタム DaemonSet を含む、あらゆるワークロードに対応
  • デメリット:使用されていないノードの容量分も支払う
  • デメリット:ノードのアップグレード、プール管理、キャパシティプランニングは自分の責任
  • デメリット:設定ミスによってセキュリティ上の問題を引き起こしやすい

ほとんどのチームへの推奨セットアップ

実際の経験から言えば、これは習得すべき重要なスキルの一つだ:まず Autopilot から始めて、具体的な制約にぶつかったときだけ Standard に移行する。ほとんどのチームはその制約に到達しない。

典型的な Web アプリケーションチームには、このセットアップを推奨する:

  • ステージングと本番の Web ワークロードには Autopilot を使用する
  • タイミングが柔軟なバッチ/ML ジョブがある場合は Spot VM を使った Standard を検討する
  • リソースリクエストは保守的かつ正確に設定する — Autopilot は実際の使用量ではなくリクエスト分を課金する
  • 初日から Workload Identity を有効にする — 後から追加するのははるかに難しい

実装ガイド

ステップ 1:GKE Autopilot クラスターを作成する

# gcloud をインストールして設定する
gcloud init
gcloud auth application-default login

# 必要な API を有効にする
gcloud services enable container.googleapis.com

# Autopilot クラスターを作成する
gcloud container clusters create-auto my-app-cluster \
  --location=asia-northeast1 \
  --release-channel=regular

# 認証情報を取得する
gcloud container clusters get-credentials my-app-cluster \
  --location=asia-northeast1

--release-channel=regular フラグを使うと、手動でアップグレードを管理しなくても安定した Kubernetes バージョンが利用できる。最新機能が欲しい場合は rapid、リスクを避けたい場合は stable を使用する。

ステップ 2:アプリケーションをデプロイする

基本的なデプロイマニフェストを作成する。Autopilot で重要なのは、常にリソースリクエストを設定することだ:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: gcr.io/PROJECT_ID/my-app:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "250m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer
kubectl apply -f deployment.yaml
kubectl get pods -w

ステップ 3:Cloud Build で CI/CD をセットアップする

Cloud Build は GKE とシームレスに統合でき、IAM の設定も最小限で済む。リポジトリのルートに cloudbuild.yaml を作成する:

# cloudbuild.yaml
steps:
  # コンテナイメージをビルドする
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA'
      - '.'

  # Container Registry にプッシュする
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'push'
      - 'gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA'

  # GKE にデプロイする
  - name: 'gcr.io/cloud-builders/kubectl'
    args:
      - 'set'
      - 'image'
      - 'deployment/my-app'
      - 'my-app=gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA'
    env:
      - 'CLOUDSDK_COMPUTE_REGION=asia-northeast1'
      - 'CLOUDSDK_CONTAINER_CLUSTER=my-app-cluster'

images:
  - 'gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA'

Cloud Build トリガーを使って GitHub リポジトリに接続する:

# Cloud Build に GKE へのデプロイ権限を付与する
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')@cloudbuild.gserviceaccount.com" \
  --role="roles/container.developer"

# トリガーを作成する(またはコンソール UI から行う)
gcloud builds triggers create github \
  --repo-name=my-app \
  --repo-owner=my-github-username \
  --branch-pattern='^main$' \
  --build-config=cloudbuild.yaml

main へのプッシュのたびに自動的に再ビルド・再デプロイされる。ビルド、プッシュ、ロールアウトを含むパイプライン全体は、小規模な Go または Node.js サービスなら通常3分以内で完了する。

ステップ 4:コスト最適化 — 重要な数値

クラスターが稼働したら、アプリケーションの動作に影響を与えずに請求額を大幅に削減できる3つの調整がある:

リソースリクエストを適切なサイズに調整する。アプリを1週間負荷をかけて運用した後、実際の使用量を確認する:

# リクエストに対する実際の CPU/メモリ使用量を確認する
kubectl top pods --sort-by=cpu

# GKE 組み込みの Vertical Pod Autoscaler から推奨設定を取得する
kubectl describe vpa my-app

Horizontal Pod Autoscaler を有効にする。オフピーク時間帯に自動でスケールダウンする:

kubectl autoscale deployment my-app \
  --cpu-percent=60 \
  --min=1 \
  --max=10

確約利用割引を活用する。1ヶ月間運用してベースラインの使用量が安定してきたら、1年間の確約利用割引によって Autopilot ポッドのオンデマンド料金を37%削減できる。私の場合、これだけで2ヶ月以内に元が取れた。

やり直すなら変えること

最初から古い Container Registry(gcr.io)ではなく Artifact Registry をセットアップする。より優れた IAM コントロール、リージョナルストレージ、脆弱性スキャンが組み込まれている。後でコンテナイメージの URL を移行するということは、すべてのデプロイマニフェストと CI 設定を更新することを意味する — 難しくはないが、面倒だ。

# Artifact Registry リポジトリを作成する
gcloud artifacts repositories create my-app-repo \
  --repository-format=docker \
  --location=asia-northeast1

# イメージ URL の形式
# asia-northeast1-docker.pkg.dev/PROJECT_ID/my-app-repo/my-app:tag

次のステップ

上記のセットアップを行えば、午後の半日で動作するコスト最適化済みの GKE デプロイと自動化された CI/CD が手に入る。この基盤から、自然な次のステップは適切な Ingress コントローラーの追加(GKE マネージドのものは Autopilot で良好に動作する)、名前空間ベースの環境分離のセットアップ、アラート用の Cloud Monitoring の組み込みだ。

特に Autopilot は、どれだけ運用オーバーヘッドを排除できるかで驚かされ続けている — 6ヶ月間で、ノードレベルのインシデントはゼロだった。それだけでも、セルフマネージドノードと比べてやや高い vCPU あたりのコストに十分値する。

Share: