Kubernetes 1.31: SIG-CLI (kubectl) の変更内容

ここでは、Kubernetes 1.31 の CHANGELOG から SIG-CLI (kubectl) の取り組みについてまとめています。:memo: は筆者によるコメントです。

- https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.31.md

**新たに追加された主なコマンドとフラグ**

- `kubectl debug --keep-annotations/init-containers/labels/liveness/readiness/startup` フラグ: copy pod でオリジナルの設定を残す
- `kubectl kustomize --helm-api-versions` フラグ: Helm Chart `Capabilities.APIVersions` の値を明示的に指定する
- `kubectl kustomize --helm-kube-version` フラグ: Helm Chart `Capabilities.KubeVersion` の値を明示的に指定する
- `kubectl logs --all-pods` フラグ: Deployment や Service を対象とした場合に pod selector にマッチするすべての pods が対象にできるようになった

**変更があった主なコマンドとフラグ**

- `kubectl wait --for` フラグ: `--for=create` とすることでオブジェクトの作成を待つことができるようになった
- `kubectl create secret docker-registry --from-file` フラグ: キー名の指定がない場合は `.dockerconfigjson` が使われるように変更
- `kubectl create token --bound-object-kind` フラグ: Node へのトークンの紐づけをサポート
- `kubectl run` コマンド: セパレータの指定が必須になった

**廃止予定のコマンドとフラグ**

なし

**削除されたコマンドとフラグ**

- `kubectl run --filename/force/grace-period/kustomize/recursive/timeout/wait` フラグ: 廃止予定だったため削除
- `kubectl drain --delete-local-data` フラグ: 廃止予定だったため削除

そのほか、細かい変更は、 https://github.com/superbrothers/kubernetes-docs/compare/kubernetes-1.30...kubernetes-1.31 で参照できます。

## 所感

`kubectl wait --for=create` や `kubectl logs --all-pods` など、便利機能がいくつか追加されました。これまでサードパーティのツールを使っていた部分を kubectl に寄せることもできそうです。

廃止予定だったフラグの削除や非推奨だった `kubectl run` のセパレータなしが廃止されたり、スクリプト内で使われてそうなコマンド、フラグに変更が入っています。1.31 へアップグレードする前にスクリプトを見直しておきましょう。

## What's New (Major Themes)

なし

## Urgent Upgrade Notes

なし

## Changes by Kind

### Deprecation

なし

### API Change

なし

### Feature

- kubectl wait に --for=create オプションが追加されました ([#125868](https://github.com/kubernetes/kubernetes/pull/125868), [soltysh](https://github.com/soltysh)) [SIG CLI and Testing]
    - :memo: `kubectl wait` コマンドでオブジェクトの作成を待てるようになりました。次のように使われることが想定されています。  
        ```
        kubectl wait --for=create deploy/test-1
        kubectl wait --for=jsonpath=.status.readyReplicas=1 deploy/test-1
        ```
- `kubectl debug` に copy pod からの probes, labels, annotations, initContainers の削除を制御できる `--keep-*` フラグが追加されました ([#123149](https://github.com/kubernetes/kubernetes/pull/123149), [mochizuki875](https://github.com/mochizuki875)) [SIG CLI and Testing]
    - :memo: `kubectl debug` コマンドはデバッグ対象として node, pod, copy pod の3種類があります
    - :memo: copy pod の作成で機能する下記フラグが追加され、通常削除せれてしまう設定を残したままにできるようになりました
        - `--keep-labels`
        - `--keep-annotations`
        - `--keep-liveness`
        - `--keep-readiness`
        - `--keep-startup`
        - `--keep-init-containers`
- `kubectl set image` コマンドに補完機能が追加されました ([#124592](https://github.com/kubernetes/kubernetes/pull/124592), [ah8ad3](https://github.com/ah8ad3)) [SIG CLI]
- `kubectl logs` コマンドに、pod selector を使用するオブジェクトからすべての pods を取得するための `--all-pods` フラグが追加されました ([#124732](https://github.com/kubernetes/kubernetes/pull/124732), [cmwylie19](https://github.com/cmwylie19)) [SIG CLI and Testing]
    - :memo: deployment や svc を対象に `kubectl logs` コマンドを実行した場合にこれまではそれらオブジェクトの pod selector にマッチする1つの pod が対象になっていました
    - :memo: `--all-pods` フラグを指定することで、pod selector にマッチするすべての pods が対象になります。同時にこのフラグを指定して場合 `--prefix` フラグが自動で有効化されてログ出力に `[<pod>/<container>] ` のプレフィックスが付与されます。
- `kubectl config set-context` コマンドに namespace のオートコンプリートが追加されました ([#124994](https://github.com/kubernetes/kubernetes/pull/124994), [TessaIO](https://github.com/TessaIO)) [SIG CLI]
- `kubectl port-forward` コマンドに ports のオートコンプリートが追加されました ([#124683](https://github.com/kubernetes/kubernetes/pull/124683), [TessaIO](https://github.com/TessaIO)) [SIG CLI]
    - :memo: pod `spec.containers.ports` フィールドが設定されている必要があります
- Node オブジェクトにバインドされた ServiceAccount トークンの作成が許可されました。これにより、ユーザは Pod にバインドされたトークンと同様に、ServiceAccount トークンの有効性を指定した Node オブジェクトにバインドできます。`kubectl create token <serviceaccount-name> --bound-object-kind=Node --bound-object-node=<node-name>` で使用できます ([#125238](https://github.com/kubernetes/kubernetes/pull/125238), [munnerz](https://github.com/munnerz)) [SIG Auth and CLI]
    - :memo: 「Node オブジェクトにバインドされた ServiceAccount トークン」というのは、トークンのライフサイクルを Node オブジェクトにも紐づけるという意味で、紐づけた Node オブジェクトが削除された場合にトークンが無効化されるようになります
    - :memo: そのほか、トークンに Node 名が含まれるようになります。KEP は https://kep.k8s.io/4193
- kubectl で WebSocket を使用した PortForward を無効にするには、環境変数のフィーチャーゲートを明示的に設定する必要があります。`PORT_FORWARD_WEBSOCKETS=false` ([#125528](https://github.com/kubernetes/kubernetes/pull/125528), [seans3](https://github.com/seans3)) [SIG API Machinery and CLI]
    - :memo: 「PortForward using WebSockets instead of SPDY」がベータに昇格してデフォルトで有効化されたため、kubectl でこの機能を無効にするには明示的に環境変数を設定する必要があります
- クライアントサイドの apply において、null 値を「この値に関連付けられたキーを削除する」として定義できるようになりました ([#125646](https://github.com/kubernetes/kubernetes/pull/125646), [HirazawaUi](https://github.com/HirazawaUi)) [SIG API Machinery, CLI and Testing]
    - :memo: null 値はパッチ時にはキーを削除するという挙動ですが、作成時にはデフォルト値が入る挙動になっており、`kubectl apply` で初回実行時にデフォルト値が入り、再度実行すると削除されるようになっていたようです (https://github.com/kubernetes/kubernetes/issues/123304)
    - :memo: この変更で null 値は削除の挙動に統一されて初回実行時にもフィールド自体が削除されるようになりました
- `kubectl debug` の `--custom` フラグがデフォルトで有効になり、yaml サポートが追加されました ([#125333](https://github.com/kubernetes/kubernetes/pull/125333), [ardaguclu](https://github.com/ardaguclu)) [SIG CLI and Testing]

## Bug or Regression

- `kubectl describe configmap` 実行時に、data の異なるキーと値のペア間に追加の行が挿入されるようになりました ([#123597](https://github.com/kubernetes/kubernetes/pull/123597), [siddhantvirus](https://github.com/siddhantvirus))
- `kubectl` が以下の操作をサポートするようになりました
    - `kubectl create secret docker-registry <NAME> --from-file=<path/to/.docker/config.json>`
    - `kubectl create secret docker-registry <NAME> --from-file=.dockerconfigjson=<path/to/.docker/config.json>` ([#119589](https://github.com/kubernetes/kubernetes/pull/119589), [carlory](https://github.com/carlory))
    - :memo: docker-registry type の secret はキーが `.dockerconfigjson` である必要がありますが、`--from-file` で指定した場合に指定したファイル名がキー名になってしまいうまくいっていなかったようです
    - :memo: このタイプの場合でキーが指定されていなければ `.dockerconfigjson` がキー名になるように変更されています
- `kubectl create cronjobs` を使用する際の役割に対する追加ルール要件（cronjobs/finalizers）が削除され、後方互換性が保たれました ([#124883](https://github.com/kubernetes/kubernetes/pull/124883), [ardaguclu](https://github.com/ardaguclu))
- `kubectl` が位置引数が存在する場合に `kubectl-create-subcommand` プラグインを見つけられるようになりました（例: `kubectl create subcommand arg`） ([#124123](https://github.com/kubernetes/kubernetes/pull/124123), [sttts](https://github.com/sttts))
    - :memo: kubectl plugin で `kubectl-create-subcommand` がサポートされるようになっていましたが、サブコマンドが引数を受け取る場合にそれがコマンドとして処理されてしまってコマンドが見つからないバグがあったようです
- Windows cmd.exe でスペースを含むダブルクオートされたパスの `EDITOR/KUBE_EDITOR` が修正されました ([#112104](https://github.com/kubernetes/kubernetes/pull/112104), [oldium](https://github.com/oldium)) [SIG CLI and Windows]
- `kubectl describe` で NetworkPolicy のポート範囲が正しく表示されないバグが修正されました（開始ポートのみが表示される問題） ([#123316](https://github.com/kubernetes/kubernetes/pull/123316), [jcaamano](https://github.com/jcaamano))
- `kubectl get` コマンドで `--sort-by` フラグを使用する際に、文字列がアルファベット順にソートされないバグが修正されました ([#124514](https://github.com/kubernetes/kubernetes/pull/124514), [brianpursley](https://github.com/brianpursley))
    - :memo: `--sort-by` フラグの処理は github.com/fvbommel/sortorder ライブラリが使用されているんですが、これが文字列のソートをうまくやってくれていなかったようです
    - :memo: ライブラリの使用をやめて単純に文字列比較するというように修正されています (`i.String() < j.String()`)
- sample-cli-plugin のヘルプテキストが一貫性を持つよう修正され、常に `kubectl ns` が使用されるようになりました ([#125641](https://github.com/kubernetes/kubernetes/pull/125641), [nirs](https://github.com/nirs))
- `kubectl` で Pod が終了した際に、STATUS 列に Pod のフェーズが 'Failed' または 'Succeeded' と表示されるようになりました ([#122038](https://github.com/kubernetes/kubernetes/pull/122038), [lowang-bh](https://github.com/lowang-bh))
    - :memo: これまで Pod が削除されている最中は Pod がすでに終了していて Failed または Succeeded のフェイズだとしても Terminating と表示されていたみたいです

### Other (Cleanup or Flake)

- `kubectl exec [POD] [COMMAND]` を `--` セパレータなしで実行する機能が削除されました。`--` セパレータは Kubernetes v1.18 リリースから推奨されており、古い方法での `kubectl exec` の呼び出しは非推奨とされていました。この変更は、古い `kubectl exec` コマンド実行の非推奨化と一致し、`kubectl exec [POD] -- [COMMAND]` の使用を強制して、互換性の向上と推奨されるプラクティスの遵守を促進します ([#125437](https://github.com/kubernetes/kubernetes/pull/125437), [ardaguclu](https://github.com/ardaguclu)) [SIG CLI and Testing]
    - :memo: ずっと今後セパレータ指定が必須になるよと警告が出ている状態でしたが、いよいよ必須になるようです。世のスクリプトで壊れるものが多く出そうで怖いですね。
- `kubectl describe service` と `kubectl describe ingress` が endpoints ではなく endpointslices を使用するようになりました ([#124598](https://github.com/kubernetes/kubernetes/pull/124598), [aroradaman](https://github.com/aroradaman)) [SIG CLI and Network]
- 非推奨およびサポートされていない `kubectl run` フラグ（filename, force, grace-period, kustomize, recursive, timeout, wait）のサポートが削除されました。また、`kubectl drain` の非推奨な `--delete-local-data` のサポートが削除され、代わりに `--delete-emptydir-data` を使用する必要があります ([#125842](https://github.com/kubernetes/kubernetes/pull/125842), [soltysh](https://github.com/soltysh)) [SIG CLI]
    - :memo: `kubectl run` の削除されたフラグはあまり使われていない気がするので問題なさそうです。もともと 1.29 で削除されるよとあったみたいですが、削除対応が漏れていたっぽいです
    - :memo: `kubectl drain --delete-local-data` フラグはローカルデータとは何がわかりやすいということで `--delete-emptydir-data` が代わりに用意されたという経緯だったと思います
        - emptydir データを削除されるとまずいケースって存在するんですかね。これがまずいとクラスタ運用できなさそうですが
- `kubectl describe service` がロードバランサー IP の内部トラフィックポリシーと IP モードを表示するようになりました ([#125117](https://github.com/kubernetes/kubernetes/pull/125117), [tnqn](https://github.com/tnqn)) [SIG CLI and Network]