makoto-developer's テックブログ

Kubernetes 1.35(Timbernetes)の新機能と破壊的変更

Kubernetes v1.35 (コードネーム: Timbernetes) が2025年12月17日にリリースされた。本記事では、公式ドキュメントに基づき、主要な新機能と改善点、破壊的変更について解説する。

直近、v1.35へアップグレードする必要があったので、公式ドキュメントを精査して個人的にまとめた。

主要な新機能

1. Structured Authentication Configuration (GA)

認証設定を構造化されたファイルで管理できる。1.29 で Alpha、1.30 で Beta、1.34 で GA になって LockToDefault が付いたので、1.35 では既定で有効かつ無効化できない。

# authentication-config.yaml
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
jwt:
  - issuer:
      url: https://issuer.example.com
      audiences:
        - my-app
    claimMappings:
      username:
        claim: sub
      groups:
        claim: groups

従来の --oidc-issuer-url などのフラグよりも、遥かに柔軟である。

2. Podリソースのインプレース更新 (GA)

Podを再起動せずに、実行中のPodのCPUとメモリリソースを動的に変更できるようになった。

apiVersion: v1
kind: Pod
metadata:
  name: resizable-pod
spec:
  containers:
  - name: app
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "200m"
      requests:
        memory: "100Mi"
        cpu: "100m"
    resizePolicy:
    - resourceName: cpu
      restartPolicy: NotRequired
    - resourceName: memory
      restartPolicy: NotRequired

Podを停止せずにリソース変更:

kubectl set resources pod resizable-pod -c app --limits=memory=300Mi,cpu=300m --requests=memory=150Mi,cpu=150m

これにより、ダウンタイムなしでPodのリソース調整が可能になり、アプリケーションの可用性が向上する。

3. CSI Volume Expansion(1.24 で GA。1.35 の変更ではない)

CSI(Container Storage Interface)ボリュームの動的拡張は ExpandCSIVolumes で制御されていたが、この gate は 1.24 で GA になり、すでに削除されている。1.35 で何かが変わったわけではないので、下の使い方は「いま使える形」として読んでほしい。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-ssd

# ボリューム拡張
# → PVCのstorage値を変更するだけ
spec:
  resources:
    requests:
      storage: 20Gi  # 10Gi → 20Gi

ダウンタイムなしでストレージを拡張できる。

4. Job Backoff Limit Per Index (GA)

Job の失敗回数制限をインデックスごとに設定できるようになった。

apiVersion: batch/v1
kind: Job
metadata:
  name: indexed-job
spec:
  completions: 10
  parallelism: 3
  completionMode: Indexed
  backoffLimitPerIndex: 3  # 各インデックスごとに3回まで再試行
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: worker
        image: worker:latest
        env:
        - name: JOB_COMPLETION_INDEX
          valueFrom:
            fieldRef:
              fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']

これにより、一部のタスクが失敗してもJob全体が停止しない。

5. ノードごとのボリューム数上限を後から変えられる (Beta)

1.35 で動いたのはこちらで、MutableCSINodeAllocatableCount が Beta になり既定で有効になった(1.33 Alpha → 1.34 Beta → 1.35 で既定有効)。CSI ドライバが報告するノードあたりのボリューム上限を、ノードを作り直さずに更新できる。関連して VolumeLimitScaling が 1.35 で Alpha として入っている。

なお下の StorageClass の例のように parameters へ上限を書く形はドライバ固有の設定であって、Kubernetes 共通の仕組みではない。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: pd.csi.storage.gke.io
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: pd-ssd
  maxVolumesPerNode: "16"  # ノードごとに最大16個

これにより、ノードのボリューム枯渇を防げる。

6. Workload Identity & Pod証明書 (Beta)

Podが独自の証明書を持ち、Workload Identityを使用できるようになった。

apiVersion: v1
kind: Pod
metadata:
  name: workload-identity-pod
spec:
  serviceAccountName: my-workload
  containers:
  - name: app
    image: my-app:latest
    volumeMounts:
    - name: workload-cert
      mountPath: /var/run/secrets/workload-identity
  volumes:
  - name: workload-cert
    projected:
      sources:
      - serviceAccountToken:
          path: token
          expirationSeconds: 3600

これにより、Podが外部サービス(AWS、GCP、Azureなど)に対して安全に認証できる。

7. Node Declared Features (Alpha)

ノードが自身の機能を宣言できるようになった。1.35 では Alpha で、NodeDeclaredFeatures は既定で無効である(Beta になって既定で有効になるのは 1.36)。

apiVersion: v1
kind: Node
metadata:
  name: node-1
  labels:
    node.kubernetes.io/feature.gpu: "true"
    node.kubernetes.io/feature.sriov: "true"
    node.kubernetes.io/feature.rdma: "true"

これにより、Schedulerはノードの機能に基づいてPodを配置できる。

8. StatefulSet maxUnavailable (Beta)

StatefulSetでローリングアップデート時の同時停止数を制御できるようになった。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  replicas: 5
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 2  # 同時に2つまで停止可能
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25

これにより、StatefulSetのアップデート速度が向上する。

9. Job managed-by フィールド (GA)

Jobを管理しているコントローラーを明示的に指定できるようになった。

apiVersion: batch/v1
kind: Job
metadata:
  name: managed-job
  managedFields:
  - manager: custom-job-controller
    operation: Update
spec:
  managedBy: custom-job-controller.example.com
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: worker
        image: worker:latest

これにより、カスタムJobコントローラーとKubernetesネイティブのJobコントローラーが衝突しない。

10. Storage Version Migration (Beta・既定では無効)

リソースのストレージバージョンを移行できるようになった。

apiVersion: migration.k8s.io/v1alpha1
kind: StorageVersionMigration
metadata:
  name: migrate-deployments
spec:
  resource:
    group: apps
    version: v1
    resource: deployments

これにより、古いAPIバージョンで保存されたリソースを新しいバージョンに移行できる。

11. Pod metadata.generation (GA)

Podにmetadata.generationフィールドが追加された。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  generation: 1  # Podの更新回数
spec:
  containers:
  - name: app
    image: nginx:1.25

これにより、Podの変更履歴を追跡できる。

12. PreferSameNode トラフィック分散ポリシー (GA)

ServiceのトラフィックをPodと同じノードに優先的に送信できるようになった。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  trafficDistribution: PreferSameNode  # 同じノードを優先

これにより、ノード間通信のレイテンシを削減できる。

パフォーマンス改善

1. API Server のスループット向上

API Serverのパフォーマンスが改善された。特に、大規模クラスタ(1000ノード以上)での改善が確認されている。

主な改善点:

  • リクエスト処理の並列化
  • キャッシュ機構の最適化
  • etcd通信の効率化

2. etcd のコンパクション改善

etcdの自動コンパクションが改善された。

# kube-apiserver flags
--etcd-compaction-interval=5m  # デフォルト: 5分
--etcd-compaction-mode=periodic

これにより、etcdのディスク使用量が削減される。

3. Scheduler のレイテンシ削減

SchedulerのPod配置レイテンシが改善された。

主な改善点:

  • スケジューリングアルゴリズムの最適化
  • ノード評価処理の並列化
  • キャッシュヒット率の向上

破壊的変更

公式の CHANGELOG が「Urgent Upgrade Notes(アップグレード前に必ず読め)」に挙げているのは、次の2件である。どちらもノードが起動しなくなる種類の変更なので、順序を間違えると止まる。

1. kubelet の --pod-infra-container-image が削除された

このフラグを渡したままだと kubelet が起動に失敗する。kubeadm を使っていないクラスタでは、kubelet を上げる前に手で取り除いておく必要がある(#133779)。

kubeadm 経由で extraArgs に渡していた場合は、init フェーズで kubelet の環境ファイルに書き込まれている。kubeadm は init でも join でもこれを消さないので、設定ファイルの extraArgs から自分で消す。

2. cgroup v1 で preflight がエラーになった

ホストが cgroup v1 で、kubelet のバージョンが 1.35 以降だと、kubeadm init / join / upgrade の SystemVerification preflight check が警告ではなくエラーを返すようになった(#134744)。1.34 までは警告で通っていたところで止まる。

どうしても cgroup v1 のまま動かすなら、2つとも要る。

# 1. preflight のエラーを無視する
kubeadm upgrade apply v1.35.0 --ignore-preflight-errors=SystemVerification

# 2. アップグレード前に ConfigMap へ failCgroupV1: false を足す
kubectl -n kube-system edit configmap kubelet-config

cgroup v2 への移行そのものについては、後述の「cgroup v1 が事実上ここで終わる」に確認コマンドを載せた。

廃止予定・削除予定

1. ⚠️ Ingress NGINX 公式サポート終了(2026年3月)

Ingress NGINX(kubernetes/ingress-nginx)は2026年3月に公式サポートが終了する。

移行先:

  • Gateway API(推奨)
  • 他のIngress Controller(Traefik、HAProxy、Envoy Gateway等)
# Gateway API への移行例
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml

# Gateway の作成
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    protocol: HTTP
    port: 80

影響:

  • セキュリティパッチが提供されなくなる
  • 新機能の追加が停止
  • コミュニティサポートのみに移行

対応期限: 2026年3月まで

2. ⚠️ cgroup v1 が事実上ここで終わる

kubelet のコードから cgroup v1 の扱いが消えたわけではない。変わったのは検証の厳しさで、1.35 以降の kubelet に対しては preflight check が警告ではなくエラーを返す(前述の「cgroup v1 がエラーになった」)。failCgroupV1: false を足せばまだ動かせるが、逃げ道を明示的に開ける必要がある以上、実質的には cgroup v2 が前提になったと考えたほうがいい。

確認方法:

# cgroup v2 が有効か確認
stat -fc %T /sys/fs/cgroup

# 出力が "cgroup2fs" なら cgroup v2
# 出力が "tmpfs" なら cgroup v1(要移行)

移行方法:

# Ubuntu/Debian
sudo grub-editconfig
# GRUB_CMDLINE_LINUX に以下を追加:
# systemd.unified_cgroup_hierarchy=1

# RHEL/CentOS
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"

# 再起動
sudo reboot

影響:

  • cgroup v1 のノードは preflight で止まる(failCgroupV1: false を入れれば通る)
  • CPU/メモリ制限の動作が変わる可能性

3. ⚠️ containerd v1.X サポート終了

containerd v1.X 系列のサポートが終了し、v2.0以降が必須になる。

確認方法:

containerd --version
# containerd containerd.io 1.6.28 の場合は要更新

更新方法:

# containerd v2.0 へ更新
sudo apt-get update
sudo apt-get install containerd.io=2.0.*
sudo systemctl restart containerd

影響:

  • 古いcontainerdでは新しいKubernetesバージョンが動作しない
  • セキュリティパッチが提供されなくなる

4. ⚠️ kube-proxy ipvs mode 廃止予定

kube-proxy の ipvs モードが廃止予定となり、nftables モードへの移行が推奨される。

現在のモード確認:

kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode

移行方法:

# kube-proxy ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-proxy
  namespace: kube-system
data:
  config.conf: |
    mode: "nftables"  # ipvs → nftables

影響:

  • ipvs モードは将来のバージョンで完全削除される
  • パフォーマンスへの影響は軽微

5. 提供が終わっている API(1.35 での削除ではない)

1.35 で新しく削除された API バージョンは無い。ただし古いクラスタから一気に上げるなら、flowcontrol の beta API はすでに全部使えなくなっている点に注意が要る。公式の Deprecated API Migration Guide によると、提供が終わったのは次のとおりである。

API バージョン提供終了
flowcontrol.apiserver.k8s.io/v1beta1v1.26
flowcontrol.apiserver.k8s.io/v1beta2v1.29
flowcontrol.apiserver.k8s.io/v1beta3v1.32

いま使えるのは flowcontrol.apiserver.k8s.io/v1 だけになる。

# v1beta3 → v1 への移行
kubectl-convert -f old-manifest.yaml \
  --output-version flowcontrol.apiserver.k8s.io/v1 > new-manifest.yaml

アップグレード前のチェックリスト

1. API バージョンの確認

# 使用中のAPIバージョンを確認
kubectl api-resources --api-group=flowcontrol.apiserver.k8s.io

2. Deprecated API の使用確認

# Deprecated APIの使用を検出
kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis

3. Feature Gate の確認

# 現在のFeature Gateを確認
kubectl get --raw /metrics | grep feature_gate

4. テスト環境での検証

本番環境にアップグレードする前に、必ずテスト環境で検証する。

# テストクラスタでアップグレード
kubeadm upgrade plan
kubeadm upgrade apply v1.35.0

移行ガイド

ステップ1: バックアップ

# etcd バックアップ
ETCDCTL_API=3 etcdctl snapshot save snapshot.db

# マニフェストバックアップ
kubectl get all --all-namespaces -o yaml > all-resources.yaml

ステップ2: コントロールプレーンのアップグレード

# マスターノードでアップグレード
kubeadm upgrade plan
kubeadm upgrade apply v1.35.0

# kubelet のアップグレード
systemctl stop kubelet
apt-get install -y kubelet=1.35.0-00
systemctl start kubelet

ステップ3: ワーカーノードのアップグレード

# ワーカーノードでアップグレード
kubeadm upgrade node
systemctl stop kubelet
apt-get install -y kubelet=1.35.0-00
systemctl start kubelet

ステップ4: 検証

# バージョン確認
kubectl version

# ノードステータス確認
kubectl get nodes

# Pod ステータス確認
kubectl get pods --all-namespaces

ベストプラクティス

1. ブルーグリーンデプロイ

本番環境では、ブルーグリーンデプロイを使用する。

1. 新しいクラスタ(Green)を作成
2. アプリケーションを新しいクラスタにデプロイ
3. トラフィックを徐々に新しいクラスタに移行
4. 古いクラスタ(Blue)を削除

2. カナリアリリース

一部のワーカーノードのみを先にアップグレードする。

# ラベルを付ける
kubectl label nodes worker-1 upgrade=canary

# カナリアノードでPodを実行
kubectl run test-pod --image=nginx --overrides='
{
  "spec": {
    "nodeSelector": {
      "upgrade": "canary"
    }
  }
}'

3. モニタリング

アップグレード中は、メトリクスを常時監視する。

# Prometheus アラート
- alert: HighAPIServerLatency
  expr: apiserver_request_duration_seconds{quantile="0.99"} > 1
  for: 5m
  annotations:
    summary: "API Server のレイテンシが高い"

まとめ

Kubernetes 1.35(Timbernetes)は、以下の点で重要なリリースである。

主要な新機能:

  • Podリソースのインプレース更新(GA): ダウンタイムなしでPodのリソース変更が可能
  • Structured Authentication Configuration(GA・1.34 から): 認証設定の柔軟な管理
  • Workload Identity & Pod証明書(Beta): Podが外部サービスに安全に認証
  • Node Declared Features(Alpha): ノードが自身の機能を宣言
  • StatefulSet maxUnavailable(Beta): StatefulSetのアップデート速度向上
  • PreferSameNode(GA): ノード間通信のレイテンシ削減

パフォーマンス改善:

  • API Serverのスループット向上
  • Schedulerのレイテンシ削減
  • etcdのコンパクション改善

破壊的変更(公式の Urgent Upgrade Notes に挙がっている2件):

  • kubelet の --pod-infra-container-image 削除 - 残したままだと kubelet が起動しない
  • cgroup v1 で preflight がエラー - failCgroupV1: false で回避はできる

廃止予定(重要):

  • ⚠️ Ingress NGINX 公式サポート終了(2026年3月) - Gateway APIへの移行を推奨
  • ⚠️ cgroup v1 が事実上の終わり - cgroup v2 への移行が実質必須
  • ⚠️ containerd v1.X サポート終了 - v2.0以降へ更新が必要
  • ⚠️ kube-proxy ipvs mode 廃止予定 - nftables modeへの移行を推奨

アップグレードは慎重に行い、必ずバックアップとテストを実施する。本番環境では、ブルーグリーンデプロイやカナリアリリースを使用することを推奨する。

Kubernetesの最新動向は↓のサイトからチェック

References