🐡

GKE Pod 垂直auto scaling by terraform

2025/02/22に公開
gke.tf
# GKE Cluster
resource "google_container_cluster" "primary" {
  name     = "my-gke-cluster"
  location = "us-central1"

  # Remove default node pool
  remove_default_node_pool = true
  initial_node_count       = 1

  # Enable Workload Identity
  workload_identity_config {
    workload_pool = "${var.project_id}.svc.id.goog"
  }

  # Enable VPA
  vertical_pod_autoscaling {
    enabled = true
  }
}

# Node Pool
resource "google_container_node_pool" "primary_nodes" {
  name       = "my-node-pool"
  cluster    = google_container_cluster.primary.name
  location   = google_container_cluster.primary.location
  node_count = 3

  node_config {
    machine_type = "e2-standard-4"

    service_account = google_service_account.gke_sa.email
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]
  }
}

# Service Account for GKE nodes
resource "google_service_account" "gke_sa" {
  account_id   = "gke-sa"
  display_name = "GKE Service Account"
}

VPAのKubernetesリソース定義(これはKubernetesマニフェストとして適用する必要があります):

vpa.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: my-app-deployment
  updatePolicy:
    updateMode: "Auto"  # または "Off", "Initial", "Recreate"
  resourcePolicy:
    containerPolicies:
    - containerName: '*'
      minAllowed:
        cpu: "100m"
        memory: "100Mi"
      maxAllowed:
        cpu: "1"
        memory: "1Gi"
      controlledResources: ["cpu", "memory"]

Terraformでkubernetes_manifestリソースを使用してVPAを適用する例:

kubernetes.tf
provider "kubernetes" {
  host                   = "https://${google_container_cluster.primary.endpoint}"
  token                  = data.google_client_config.default.access_token
  cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth[0].cluster_ca_certificate)
}

resource "kubernetes_manifest" "vpa" {
  manifest = {
    apiVersion = "autoscaling.k8s.io/v1"
    kind       = "VerticalPodAutoscaler"
    metadata = {
      name      = "my-app-vpa"
      namespace = "default"
    }
    spec = {
      targetRef = {
        apiVersion = "apps/v1"
        kind       = "Deployment"
        name       = "my-app-deployment"
      }
      updatePolicy = {
        updateMode = "Auto"
      }
      resourcePolicy = {
        containerPolicies = [
          {
            containerName = "*"
            minAllowed = {
              cpu    = "100m"
              memory = "100Mi"
            }
            maxAllowed = {
              cpu    = "1"
              memory = "1Gi"
            }
            controlledResources = ["cpu", "memory"]
          }
        ]
      }
    }
  }
}

サンプルアプリケーションのDeployment:

deployment.tf
resource "kubernetes_deployment" "example" {
  metadata {
    name = "my-app-deployment"
  }

  spec {
    replicas = 3

    selector {
      match_labels = {
        app = "my-app"
      }
    }

    template {
      metadata {
        labels = {
          app = "my-app"
        }
      }

      spec {
        container {
          image = "your-app-image:latest"
          name  = "my-app"

          resources {
            requests = {
              cpu    = "100m"
              memory = "100Mi"
            }
            limits = {
              cpu    = "500m"
              memory = "500Mi"
            }
          }
        }
      }
    }
  }
}

主な特徴と注意点:

  1. VPAの動作モード:

    • Auto: 自動的にリソースを調整(ポッドの再起動が必要)
    • Initial: 新しいポッドの初期リソース設定のみ
    • Off: 推奨値の計算のみ(実際の変更なし)
    • Recreate: 自動調整(ポッドを再作成)
  2. リソース制限:

    • minAllowed: 最小リソース要求
    • maxAllowed: 最大リソース要求
    • controlledResources: VPAが制御するリソースタイプ
  3. 設定のベストプラクティス:

    • アプリケーションの特性に基づいて適切な最小/最大値を設定
    • クリティカルなワークロードには慎重なVPA設定が必要
    • 初期段階ではupdateMode: "Off"で動作を観察することを推奨
  4. 前提条件:

    • GKEクラスタでVPAが有効化されていること
    • 適切なIAM権限が設定されていること
    • メトリクスサーバーが動作していること

このコードにより、GKEクラスタでVPAを使用してポッドのリソース要求を自動的に最適化できます。

Discussion