ここでは、Kubernetes 1.37 の CHANGELOG から SIG-CLI (kubectl) の取り組みについてまとめています。📝 は筆者によるコメントです。
新たに追加されたコマンドとフラグ
-
--proxy-urlフラグ: API サーバへのリクエストに使用するプロキシ URL。kubeconfig に設定されたプロキシ設定を上書きできる -
kubectl explain --max-depthフラグ:--recursiveでネストされたフィールドを出力する際の最大の再帰深度を指定(0は無制限)
変更があったコマンドとフラグ
-
kubectl top pod --field-selectorフラグ:kubectl top podで--field-selector(spec.nodeNameなど)による絞り込みが利用可能になった -
kubectl get -o kyaml: kyaml 出力フォーマットが Stable に昇格した
廃止予定のコマンドとフラグ
-
kubectl run --filename/-fフラグ: 以前から無視されていたフラグで、正式に非推奨化された
削除されたコマンドとフラグ
なし
そのほか、変更の詳細は、 https://github.com/superbrothers/kubernetes-docs/compare/kubernetes-1.36...kubernetes-1.37 で参照できます。
所感
v1.37 においても kubectl に大きな変更はありませんでした。
kubectl top pod で --field-selector がサポートされたのは個人的に嬉しい変更です。--field-selector spec.nodeName=<Node名> と指定することで、特定ノード上の Pod のリソース使用量をぱっと確認できるようになりました。
KYAML 形式での出力(-o kyaml)は v1.35 で導入されてから着実に進み、このバージョンでついに GA(Stable)となりました。
KYAML はインデント事故を防ぐため {} や [] を使う flow style ベースの YAML サブセットですが、標準 YAML と 100% 互換があるため、ファイル拡張子や既存の適用ツールを変更せずに共存できる設計になっています。KEP-5295 では、下記のロードマップが描かれており、現在は最初のステップである CLI 出力が完了した段階です。
- CLI 出力の実装・GA(今回達成)
- フォーマッタ(yamlfmt)や CI 検証ツールの整備
- 公式ドキュメント(kubernetes.io)での従来の YAML と KYAML の併記
- コミュニティやエコシステムへの普及
実際の運用では OSS など外部から取得したマニフェストはどうしても従来の YAML 形式のまま残るため、リポジトリ内で通常の YAML と KYAML が混ざることになります。パーサ上は互換があるとはいえ、2 つの形式をどう管理していくかは悩ましい部分でもあり、今後実際の現場やコミュニティにどこまで浸透していくのか興味深いところです。
Changelog since v1.36.0
Urgent Upgrade Notes
(No, really, you MUST read this before you upgrade)
なし
Changes by Kind
Dependency
なし
Deprecation
-
kubectl runで無視されていた--filename/-fフラグを非推奨としました。 (#138671, @Suknna) [SIG CLI]-
📝
kubectl runには--rm(終了時に Pod を削除する)処理のために内部でDeleteFlagsを流用しており、その影響で-f / --filenameフラグが芋づる式に生えてしまっていた。
kubectl runは引数から動的に Pod を作成するだけで-fを指定しても単に無視されていた。
今回正式に deprecated マークがついたことで指定時に警告が出るようになり、ヘルプからも非表示になった。
-
API Change
なし
Feature
-
kubectl describe statefulsetの出力に ServiceName、PodManagementPolicy、PersistentVolumeClaimRetentionPolicy を追加しました。 (#137547, @kfess) [SIG CLI] -
kubectl topでmetrics.k8s.io/v1をサポートしました。 (#139726, @tico88612) [SIG CLI and Instrumentation]-
📝
kubectl topや HPA などで長年利用されてきたメトリクス API(metrics.k8s.io)は、これまでずっとv1beta1のままでしたが、v1.37 でついに GA(Stable)へ昇格した(KEP #5207)。
これに伴い、kubectl topも優先してmetrics.k8s.io/v1を参照するように更新された。クラスタ側(metrics-server など)がv1を提供していない場合は自動的にv1beta1へフォールバックするため、既存の環境でも問題なく動作する。
-
-
出力に表示されるネストされたフィールドの深さを制限する
--max-depthフラグをkubectl explain --recursiveに追加しました。 (#138809, @shady0503) [SIG CLI and Testing]-
📝
kubectl explain --recursive(または-R)は全階層のスキーマツリーを展開するため、Pod や CRD などの巨大なリソースでは出力が膨大になっていた。
--max-depthフラグを使うことで展開する階層の深さを制限できるようになり、上位の構造をざっくり俯瞰したい場合に便利になった。
--max-depth=0は無制限(デフォルト)で、--max-depth=N(N > 0)で N 階層まで展開される。なお、--max-depthは単体では利用できず、--recursive(または-R)とセットで指定する必要がある(指定しないとエラーになる)。上限に達した階層ではフィールド名と型が表示され、その配下の展開が省略される。
-
-
kubeconfig に設定されたプロキシ URL を上書きする
--proxy-urlフラグをkubectlに追加しました。 (#139862, @Mujib-Ahasan) [SIG CLI]-
📝
--serverや--namespaceなどと同様に、kubectl の全サブコマンドで共通して使えるグローバルフラグとして追加された。
kubeconfig のproxy-url設定をコマンド実行時のみ一時的に上書きできる。環境変数のHTTPS_PROXYでは接続先が localhost や 127.0.0.1 の場合に Go の HTTP クライアント仕様でプロキシがバイパスされてしまう制約があったが、このフラグを指定することで確実にプロキシ経由で接続できるようになった。
-
-
kubectl top podを実行する際、Pod のメトリクスに--field-selectorを適用できるようにしました。 (#139107, @Mujib-Ahasan) [SIG CLI]-
📝 これまで
kubectl top podに--field-selectorを指定すると直接 Metrics API へ渡されていたが、Metrics API はmetadata.nameとmetadata.namespaceしかサポートしていないため、spec.nodeNameなどを指定するとエラー(BadRequest)になってしまっていた。
今回、Core API(Pod API)側で--field-selectorに合致する Pod を取得してから kubectl 側でメトリクスをフィルタリングする方式に改修された。
これにより、kubectl top pod -A --field-selector spec.nodeName=<node-name>で特定ノード上でリソースを消費している Pod を簡単に一覧できるようになってめっちゃ便利。
-
-
kubectl get -o kyamlのサポートを Stable に昇格しました。 (#140076, @soltysh) [SIG CLI]-
📝 YAML 特有の曖昧さやインデント崩れを回避する安全な YAML 方言である KYAML(
-o kyaml)が Stable に昇格した。
KYAML の詳しい仕様や背景については Kubernetes 1.34: 新しい kubectl 出力形式 kyaml をサポートしました で解説している。
無効化用の環境変数(KUBECTL_KYAML)も削除されて正式な標準出力形式となったが、コミュニティ全体が今後 KYAML の採用に本格的に動くかは未知な印象。自分も積極的に KYAML に移行しようという気持ちは今のところない。
-
-
プラグインの実行時に、
kubectlバイナリのパスを環境変数KUBECTL_PATHに設定するようにしました。 (#138694, @brianpursley) [SIG CLI and Testing]-
📝 プラグイン内から改めて
kubectlを呼び出す際に、プラグインを起動した親のkubectlバイナリのパスを特定できるようにするための環境変数。複数バージョンの混在環境や$PATH外から実行された場合でも、呼び出し元と同一のバイナリを確実に再実行できるようにすることが目的。
-
Documentation
-
kubectlの日本語翻訳を更新しました。 (#131176, @yude) [SIG CLI and Testing] - 生成されるドキュメントのフォーマットを修正し、他のコマンドとの一貫性を向上させるために、
kubectl explainの詳細説明 (long description) を更新しました。 (#140357, @ingyeoking13) [SIG CLI]-
📝 ドキュメント生成時に
<type>.<fieldName>の山括弧が HTML エスケープされてしまい、公式サイトのドキュメントで<type>.<fieldName>とそのまま出力されてしまっていた等の問題があったみたい。
他のコマンドのヘルプ表記に合わせて大文字(TYPE.FIELDNAME[.FIELDNAME])に修正された。
-
Failing Test
なし
Bug or Regression
-
指定されたグループ下にリソースタイプが見つからない場合の
kubectlエラーメッセージにグループ名を追加しました(例:the server doesn't have a resource type "pdb" in group "hpa")。 (#140759, @makeittotop) [SIG CLI]-
📝 これまで
kubectl get pdb.hpaのように存在しないグループを指定した場合に、単にthe server doesn't have a resource type "pdb"と出力されてしまい、リソースタイプ自体が存在しないかのように誤解しやすかった。
今回の改修で、指定されたグループやバージョンに応じてメッセージに含めるよう修正された。グループ名のタイポや指定ミスにすぐ気付けるようになった素晴らしい改善。- グループ指定時:
the server doesn't have a resource type "pdb" in group "hpa" - バージョン指定時:
the server doesn't have a resource type "pdb" in version "v1" - 両方指定時:
the server doesn't have a resource type "pdb" in group "hpa" and version "v1"
- グループ指定時:
-
-
custom-columns 出力で
--label-columnsを指定した場合に、kubectl getがエラーを返すように変更しました。 (#138094, @ahmadmaha02) [SIG CLI]-
📝 これまで
-o custom-columnsと-L / --label-columnsを同時に指定した場合、エラーにならず単に--label-columnsが黙って無視されていた。
今回の改修で、既存の--show-labelsと同様に明示的なエラー(--label-columns option cannot be used with custom-columns printer)を返すようになった。
もしスクリプト等で両方を指定していた場合は実行失敗するようになるため注意が必要。
-
-
kubectl cluster-info dump --output-directoryが全ユーザーから読み取り可能な (world-readable) ダンプファイルを作成していた問題を修正しました。ダンプされた Pod ログに機密データが含まれる可能性があるため、ファイルはパーミッション 0600 で作成され、kubectlが作成するディレクトリは 0700 で作成されます。 (#140189, @ashvinctrl) [SIG CLI and Security]-
📝
kubectl cluster-info dumpは、クラスタのデバッグや障害診断のためにリソース情報や全 Pod のログを一括でダンプするコマンド。
Pod ログには認証トークンや接続文字列などの機密情報がうっかり出力されているケースがあり、--output-directoryで出力したファイルが誰でも読めるパーミッション(0644/ ディレクトリ0755)になっていたため、所有者のみが読める0600/0700にするように改善された。
-
-
複数の StorageClass にデフォルトのアノテーションが付与されている場合、
kubectl get storageclassで実際に有効なデフォルトの StorageClass のみに "(default)" と表示するように修正しました。 (#135964, @jaehanbyun) [SIG CLI and Storage]-
📝 実は Kubernetes には、複数の StorageClass にデフォルトアノテーションが付いている場合「最も新しく作成されたもの(CreationTimestamp が最新のもの)」を優先してデフォルトとして扱う仕様がある(公式ドキュメント にも明記されている)。無停止でデフォルトを切り替えるための仕様。
これまでkubectl get scではアノテーションがついているすべてに(default)と表示されてしまっていたが、今回の修正でこの内部仕様に合わせて実際に有効となる 1 つだけに(default)が付くようになった。
-
-
kubectl drain --disable-eviction --dry-run=serverが無期限にハングするバグを修正しました。 (#137543, @kfess) [SIG CLI and Testing]-
📝
kubectl drainでも--dry-run(client/server)が利用できることを知らなかった。ノードのメンテナンス前に、どの Pod が影響を受けるかや、PDB(PodDisruptionBudget)や DaemonSet などで退避がブロックされないかを安全に事前検証・シミュレーションするのに役立つみたい。
kubectl drainでは通常 Eviction API を使って Pod を退避するが、--disable-evictionを指定すると Pod を直接削除するパスを通る。--dry-run=serverの場合、API サーバ側で検証のみ行われるため Pod は実際には削除されない。通常パスでは Pod の削除完了を待つ処理(waitForDelete)をスキップするようになっていたが、--disable-eviction側のパスではこの判定が抜けていたため、削除されるはずのない Pod の削除を待ち続けてコマンドが終了しない状態になっていた。今回の修正で server dry-run 時に待機せず即座に終了するようになった。
-
-
Pod への attach の試行が失敗した際にログが重複して出力される問題を修正しました。 (#139091, @olamilekan000) [SIG CLI]
-
📝 CHANGELOG の文面からは分かりづらいが、
kubectl attachではなくkubectl run(-iや--attach)での挙動修正。
kubectl run --rm -i ...でワンショットコマンドを実行した際、コンテナが一瞬で終了すると attach に失敗してログストリーミングへフォールバックすることがある(warning: couldn't attach to pod/..., falling back to streaming logs:)。
このとき、attach 前に取りこぼし防止として事前出力していたログがあるにもかかわらず、フォールバック時にも最初からの全ログを再度取得していたため、同じログが 2 回出力されてしまっていた(スクリプト等で出力をパースしている場合に壊れる問題があった)。
実装としては、事前ログ取得処理が完了した直後のクライアント現在時刻を保持しておき、フォールバック時のリクエストでPodLogOptions.SinceTimeにその時刻を指定することで、それ以降のログのみをストリーミングして重複を防ぐように修正されている。
-
-
大規模なデータセット(100行以上)における
kubectlのリソース出力のリグレッションを修正しました。 (#138550, @rawkode) [SIG CLI]-
📝 「100 行以上」というピンポイントな数字の理由は、1.37 の開発中にテーブル出力(
kubectl get等)のメモリ消費を抑えるため、tabwriterを 100 行ごとに定期 flush する最適化(#138023)が入ったことによる。
しかしtabwriterはすでに出力(flush)した過去の行を再パディングできないため、101 行目以降に最初の 100 行より長い文字列が現れると、そこから列幅が広がってしまい最初の 100 行と列の位置がズレてしまうリグレッションが発生していた。
今回の修正で、出力前に全行を事前スキャンして各列の最大幅をあらかじめ計算し、ヘッダー行に最大幅分のパディングを入れてから flush することで列ズレを解消した。なお、元の最適化も今回の修正も 1.37 の開発ブランチ上で連続してマージされたため、過去のリリース(1.36 以前)にこのバグが含まれていたわけではない。
-
-
コンテナ型(リストまたはマップ)のパッチ適用時に、以前は成功していた apply リクエストに対して
422 requiredエラーが返される可能性があった Server-Side Apply のリグレッションを修正しました。 (#140294, @jpbetz) [SIG API Machinery, Architecture, Auth, CLI, Cloud Provider, Cluster Lifecycle, Instrumentation, Network, Node, Scheduling, Storage and Testing]-
📝 CHANGELOG の「コンテナ型」とは、マップや構造体、リストなどの入れ子データ構造のこと。
CRD 等で内部に必須フィールドを持つオブジェクト型がnullable: trueと定義されている場合、kubectl apply --server-sideでfield: nullを適用してフィールドをクリアしようとすると、内部で空のオブジェクト{}に変換されてしまい、必須フィールドが欠落しているとして422 (field required)エラーで拒絶されるリグレッションが発生していた。
Server-Side Apply の中核ライブラリであるstructured-merge-diffの更新によってこの問題が修正され、従来どおり null によるクリアが正常に行えるようになった(なお、1.36.0 にも存在していたため 1.36 系にもバックポートされている)。
-
-
kubectl exec実行時のエラー報告を改善しました。 (#138214, @hunshcn) [SIG CLI and Testing]-
📝 CHANGELOG の「エラー報告の改善」とは、
--(ダッシュセパレータ)の前に余計な引数を渡した際のチェック厳格化のこと。
kubectl execではkubectl exec <pod> -- <cmd>の形式で実行するのが標準だが、kubectl exec my-pod extra1 extra2 -- bashのように Pod 名と--の間に余計な引数を挟んでしまった場合、これまでは中間の引数が何のエラーも出ずサイレントに無視・破棄されたままコマンドが実行されてしまっていた。
今回の修正で--の前に指定できる引数が Pod 名の 1 つだけ(または-f指定時の 0 個)に厳格化され、余計な引数がある場合はサイレント無視されずにエラーとなるように改善された。
-
-
--restartおよび--image-pull-policyに無効な値が指定された際のkubectl runのエラーメッセージを更新し、受け入れ可能な値の一覧を表示するようにしました。 (#138188, @ogormans-deptstack) [SIG CLI]-
📝
--restartや--image-pull-policyは大文字始まり(NeverやAlways等)を指定する必要があるが、うっかり小文字で--restart=neverと指定して弾かれた際などに、有効な値の一覧が表示されるようになった。ドキュメントを調べに行かずに済む親切な改善。# 変更後の出力例 $ kubectl run nginx --image=nginx --restart=never error: invalid restart policy: never, valid values are: Always, OnFailure, Never $ kubectl run nginx --image=nginx --image-pull-policy=always error: invalid image pull policy: always, valid values are: Always, IfNotPresent, Never
-
Other (Cleanup or Flake)
なし