↓メインコンテンツへスキップ
  1. Blogs/

GKEのdefault_compute_class_enabledを有効にしても何も起きなかったので調べた

3 分
Terraform GoogleCloud GKE
0222-nnn
著者
0222-nnn
猫が好き
目次
Terraform-GoogleCloud - この記事は連載の一部です
パート 36: この記事

概要
#

cluster_autoscaling.default_compute_class_enabledというスイッチがあります。Terraform Registryの説明はこうです。

If enabled, cluster autoscaler will use Compute Class with name default for all the workloads, if not overriden.

有効にすればオートスケーラがdefaultというComputeClassを使ってくれる、と読めます。ところが有効にしても何も変わりません。ノードの選ばれ方も、kubectl get computeclassesの中身も、有効にする前と同じで、期待した動作になりませんでした。

有効なのに何も変わらないので、設定が効いているのかどうかを判断できません。 そこで、切り替えながら実測して何を制御しているのかを確かめます。

名前がややこしいことも、調べにくさに拍車をかけています。

層 名前
Terraform cluster_autoscaling.default_compute_class_enabled
REST API clusterAutoscaling.defaultComputeClassConfig.enabled
コンソール Autopilot compute class compatibility

同じスイッチを3通りの名前で呼んでいるので、ドキュメントを横断すると別機能に見えます。

対象読者は、GKEのStandardクラスタをTerraformで作ったことがある人です。ノード自動プロビジョニング(NAP)とオートスケーラの入門は扱いません。

Autopilotクラスタそのもの、カスタムComputeClassの設計指針、GPU/TPUの選択は扱いません。

検証すること
#

  • 有効にすると何が変わるか
  • defaultというComputeClassは誰が作るのか
  • スイッチのON/OFFでオートスケーラのマシン選択が変わるか
  • 切り替えはクラスタ再作成を伴うか

前提環境
#

  • Google Cloud CLI、Terraform
  • Billingが有効な検証用Google Cloud Project
  • GKE、Compute Engineを操作できるGoogleアカウント
  • 検証時のバージョン:Terraform 1.14.5、google 7.46.0、GKE 1.35.7-gke.1027000

使用するTerraformコード
#

スイッチが効く場所
#

flowchart TB
    POD["Pod
nodeSelector も computeClass も指定なし"] POD --> SCHED["スケジューラ"] SCHED -->|"既存ノードに空きがない"| NAP["Node Auto Provisioning"] NAP --> SW{"default_compute_class_enabled"} SW -->|"false"| OLD["従来の選び方でマシンを決める"] SW -->|"true"| NEW["既定の ComputeClass に従う"]

このスイッチは何も指定していない Pod のために NAP がマシンを選ぶときにだけ効きます。既存ノードに空きがあれば、そこに載って終わりです。

enable_autopilot とは別物
#

先に紛らわしい点を片付けます。

設定 効果
enable_autopilot クラスタ全体をAutopilotモードにする
default_compute_class_enabled Standardのまま、オートスケーラのマシン選択だけを変える

この記事で扱うのは後者で、クラスタはStandardのままです。

構成
#

ノード自動プロビジョニング(NAP)を有効にします。NAPがないとオートスケーラはノードプールを作れず、このスイッチに作用対象がありません。

cluster_autoscaling {
  enabled = true

  default_compute_class_enabled = var.default_compute_class_enabled

  resource_limits {
    resource_type = "cpu"
    maximum       = var.nap_max_cpu
  }
  resource_limits {
    resource_type = "memory"
    maximum       = var.nap_max_memory_gb
  }

  auto_provisioning_defaults {
    service_account = google_service_account.gke_node.email
    oauth_scopes    = ["https://www.googleapis.com/auth/cloud-platform"]
    disk_size       = 30
    disk_type       = "pd-balanced"
  }
}

固定のノードプールは1ノードだけにします。ここに収まらないPodを起動すると、NAPがノードを作る。そのとき何を選ぶかが、このスイッチの観測点になります。

確認コマンドでつまずく
#

まずfalseの状態を見ようとして、いきなりつまずきました。

gcloud container clusters describe tf-adv-gke-dcc --zone=asia-northeast1-a \
  --format="yaml(clusterAutoscaling)"
  null

REST APIのフィールド名はclusterAutoscalingですが、gcloud container clusters describeの出力ではautoscalingです。

gcloud container clusters describe tf-adv-gke-dcc --zone=asia-northeast1-a \
  --format=json | jq '.autoscaling'
{
  "autoprovisioningNodePoolDefaults": { "...": "..." },
  "autoscalingProfile": "BALANCED",
  "defaultComputeClassConfig": {},
  "enableNodeAutoprovisioning": true,
  "resourceLimits": [
    { "maximum": "12", "resourceType": "cpu" },
    { "maximum": "48", "resourceType": "memory" }
  ]
}

defaultComputeClassConfigは空オブジェクトです。enabled: falseとは出ません。無効かどうかは、空かどうかで判断します。

有効にしても何も起きない
#

trueに変えます。

terraform plan
  # google_container_cluster.primary will be updated in-place
          ~ default_compute_class_enabled = false -> true
Plan: 0 to add, 1 to change, 0 to destroy.

in-place更新なので、クラスタ再作成は起きません。

terraform apply
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
{
  "enabled": true
}

APIには反映されました。では、中身はどうなったのか。

kubectl get computeclasses
NAME             AGE
autopilot        16m
autopilot-arm    16m
autopilot-spot   16m

有効にする前とまったく同じです。 しかもこの3つは、スイッチがfalseのときから存在していました。

(false のとき)
NAME             AGE
autopilot        5m38s
autopilot-arm    5m38s
autopilot-spot   5m38s

既存のノードもPodも動きません。ノードの選ばれ方も変わりません。

default は自分で作る
#

ここで気付きます。Registryの説明にある「defaultという名前のComputeClass」が、どこにも存在しません。

autopilot、autopilot-arm、autopilot-spot、autopilot-arm-spotはGKEが用意します。defaultだけがありません。有効にしても生成されません。

公式にもそう書かれています。クラスタ既定にするには「default という名前の ComputeClass を新しく作る」ことになっています。

つまりこのスイッチは、自分でdefaultという名前のComputeClassを作って初めて意味を持ちます。

作ってみます。分かりやすいように、オートスケーラが自力では選ばないn2を指定します。

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: default
spec:
  priorities:
    - machineFamily: n2
  nodePoolAutoCreation:
    enabled: true
  whenUnsatisfiable: ScaleUpAnyway

作る前は、何も指定しないPodに対してオートスケーラがe2-standard-2を選んでいました。

NAME                                                  TYPE            POOL
gke-tf-adv-gke-dcc-nap-e2-standard-2--943f1681-l4d6   e2-standard-2   nap-e2-standard-2-yg2nnsw8

defaultを作ったあと、同じ形のPodを起動します。

NAME                      READY   STATUS    NODE
burst2-85bdf8fbc5-z7qwh   1/1     Running   gke-tf-adv-gke-dcc-nap-n2-standard-2--7c4379cf-9mxh

NAME                                                  TYPE            POOL
gke-tf-adv-gke-dcc-nap-n2-standard-2--7c4379cf-9mxh   n2-standard-2   nap-n2-standard-2-gpgug1e5

n2-standard-2になりました。Pod側はnodeSelectorもComputeClassの指定も書いていません。

スイッチを切ると無視される
#

では、defaultさえあればスイッチは要らないのでしょうか。確かめます。

defaultをmachineFamily: c3に変えて、スイッチをfalseに戻します。そのうえで、既存のどのノードにも収まらないPod(CPU 3500m / メモリ 6Gi)を起動します。

kubectl get computeclass default -o jsonpath='{.spec.priorities}'
[{"machineFamily":"c3"}]
{}

結果です。

burst6 node: gke-tf-adv-gke-dcc-nap-e2-standard-4--6bbc1af1-j7r7
e2-standard-4

c3ではなくe2-standard-4の新しいノードプールが作られました。default ComputeClassは無視されています。

スイッチ default ComputeClass オートスケーラが作ったノード
true machineFamily: n2 n2-standard-2
false machineFamily: c3 e2-standard-4

スイッチは効いていました。「defaultを作る」と「スイッチを入れる」の両方が要ります。

つまずいた話: describe には出ない
#

この検証は素直に進みませんでした。上の対照実験を、条件を変えて4回やり直しています。

3回目は、PodがPendingのまま動きませんでした。kubectl describe podが言うのはこれだけです。

Warning  FailedScheduling  default-scheduler
  0/5 nodes are available: 1 Insufficient memory, 4 Insufficient cpu.

「リソースが足りない」としか分かりません。ComputeClassの指定が悪いのか、NAPが動いていないのか、判断できません。

理由はオートスケーラのログにありました。

gcloud logging read 'logName=~"cluster-autoscaler-visibility" AND resource.labels.cluster_name="tf-adv-gke-dcc"' \
  --limit=5 --freshness=2h --format=json
{
  "noDecisionStatus": {
    "noScaleUp": {
      "unhandledPodGroups": [{
        "napFailureReasons": [{
          "messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
          "parameters": ["asia-northeast1-a"]
        }],
        "rejectedMigs": [{
          "mig": { "nodepool": "nap-e2-medium-go8qcpk2" },
          "reason": {
            "messageId": "no.scale.up.mig.failing.predicate",
            "parameters": ["NodeResourcesFit", "Insufficient cpu", "Insufficient memory"]
          }
        }]
      }]
    }
  }
}

resource_limitsのCPU上限(12)に当たっていました。ComputeClassとは無関係です。

describeが見せるのはスケジューラの言い分だけです。 オートスケーラが何を検討して、どのノードプールをなぜ却下したかは、このログにしかありません。

スケールアップした場合の判断も残ります。

  2026-09-04T23:18:54  nap-e2-standard-4-14bu1tk2  <- ['burst5-...']
  2026-09-04T22:46:25  nap-n2-standard-2-gpgug1e5  <- ['burst3-...']
  2026-09-04T22:24:01  nap-e2-standard-2-yg2nnsw8  <- ['burst-...']

先にこれを見ていれば、やり直しは1回で済みました。

後片付け
#

terraform destroy
Destroy complete! Resources: 22 destroyed.

NAPが作ったノードプールもクラスタごと消えます。ただしresource_limitsを大きくしすぎると、オートスケーラがその範囲までノードを作れてしまう。検証用のプロジェクトでは小さめにします。

まとめ
#

  • 有効にしただけでは何も起きない。 defaultという名前のComputeClassを自分で作って初めて効く
  • defaultはGKEが用意しない。 autopilot・autopilot-arm・autopilot-spotは最初からあるが、defaultだけがない
  • 「作る」と「有効にする」の両方が要る。 スイッチを切るとdefaultは無視される
  • falseは空オブジェクトとして現れる。 enabled: falseとは出ない
  • 確認するキーはautoscaling。 REST APIのclusterAutoscalingという名前で--formatを書くとnullが返る
  • 切り替えはin-place。クラスタ再作成は起きない
  • オートスケーラが動かない理由はdescribeに出ない。 cluster-autoscaler-visibilityログを見る

参考資料
#

Terraform-GoogleCloud - この記事は連載の一部です
パート 36: この記事

関連記事

GKEノードプールのSURGEアップグレードをBlue/Greenと同じ条件で測って比べてみた
3 分
Terraform GoogleCloud GKE
GKEノードプールをBlue/Greenでアップグレードして、soak期間中にロールバックしてみた
5 分
Terraform GoogleCloud GKE CloudKMS
GKEノードのブートディスクをCMEKで暗号化して鍵をローテーションしてみた
6 分
Terraform GoogleCloud GKE CloudKMS CMEK
TerraformでGKEのPodにSecret Managerの値をファイルとしてマウントしてみた
3 分
Terraform GoogleCloud GKE SecretManager
TerraformでGKEのスタンドアロンNEGを消したらLBのバックエンドが戻らなかった話
3 分
Terraform GoogleCloud GKE LoadBalancing
Peering越しのPod→VM通信が落ちる原因を、ルートだと思い込んでいた話
4 分
Terraform GoogleCloud GKE VPC