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

## はじめに

ここでは、Kubernetes 1.19 の CHANGELOG から SIG-CLI (kubectl) の取り組みについてまとめています。

- https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.19.md
- https://relnotes.k8s.io/?areas=kubectl&releaseVersions=v1.19.0

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

- ` --warnings-as-errors ` フラグ（全コマンド共通）: サーバから受け取った警告をエラーとして扱い、ゼロ以外の終了コードで終了する
- `kubectl annotate` コマンドの `--list` フラグ: オブジェクトの `metadata.annotations` のリスト
- `kubectl create deployment` コマンドの `--port` フラグ: Deployment `spec.template.spec.containers.ports` を設定する
- `kubectl diff` コマンドの `--selector` (`-l`) フラグ: 差分出力の対象をラベルセレクタでフィルタする
- `kubectl run` コマンドの `--privileged` フラグ: Provileged モードでコンテナを作成する

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

- `--output` フラグの `jsonpath-as-json`: jsonpath を使うが、maps / slices / structs 型を Go シンタックスに変わりに JSON でシリアライズする

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

- `kubectl convert`（v1.17 で削除予定だったが引き続き削除されておらず）

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

- `kubectl get --export` フラグ

そのほか、細かい変更は、 https://github.com/superbrothers/kubectl-docs/compare/v1.18.0...v1.19.0 で参照できます。

## What's New (新情報)

###  廃止予定 API 利用の警告

> SIG API Machinery は、`kubectl` ユーザや API 利用者に表示される「[廃止予定 API 利用の警告](https://kubernetes.io/docs/reference/using-api/deprecation-policy/#rest-resources-aka-api-objects)」とクラスタ管理者に表示されるメトリクスを実装しました。廃止予定 API へのリクエストには、対象 の API が削除されるリリースと代替 API の情報を含む警告が返されます。警告は、[Admission Webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admissionreview-response-warning)、また[カスタムリソースの廃止予定のバージョンとして指定する](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#version-deprecation)ことで返すこともできます。

:memo: 廃止予定の API を利用していることをクラスタ利用者に通知できる機能です。Admission Webhook や CRD でも通知することができ、べんりそうです。この機能は SIG API Machinery での変更なので、SIG-CLI とは直接関係はありませんが、`kubectl` にこの機能に関する `--warnings-as-errors` という共通フラグが追加されています。このフラグを使用すると、利用した API に警告が含まれる場合にエラーとしてゼロ以外の終了コードでコマンドを終了することができるようになります。

### Pod とノードをデバッグする CLI のサポートの拡張

> SIG CLI は `kubectl` によるデバッグを拡張して、新たに2つのデバッグワークフローをサポートします。コピーの作成による Pod のデバッグとホストの namespaces でのコンテナの作成によるノードにデバッグです。これらは、次の場合に便利です。
> 
> - エフェメラルコンテナが有効になっていないクラスタにデバッグコンテナを挿入する
> - クラッシュするコンテナのイメージを変更したり、コマンドを `sleep 1d` に変更したりすることで、デバッグを容易にする
> - ノードのホストファイルシステムの構成ファイルを調べる
> 
> これらの新しいワークフローは新しいクラスタ機能を必要としないので、`kubectl alpha debug` コマンドを使って既存のクラスタで試すことができます。`kubectl` を使ったデバッグに関するフィードバックをお待ちしています。イシューの作成や Kubernetes Slack #sig-cli チャンネルへの参加、または [kubernetes/enhancements#1441](https://github.com/kubernetes/enhancements/issues/1441) イシューへのコメントで私たちに連絡してください。

:memo: `kubectl alpha debug` コマンドに新たに2つの機能が追加されました。

1つは、起動中かクラッシュしているかに関わらず対象の Pod に対してサイドカーとしてデバッグコンテナを追加、またプロセスネームスペースの共有（Pod `spec.shareProcessNamespace`)を有効にしたコピーの Pod を作成するというものです。v1.16 からアルファで提供されている[エフェメラルコンテナ](https://qiita.com/superbrothers/items/85edec4d0232e0bbe2c0)を使用したデバッグコンテナの追加機能は、v1.19 時点でもアルファのため、フェーチャゲートで明示的にクラスタ管理者が機能を有効にしている必要があり、広く使えるものではありません。このコピー Pod を作成するワークフローでは、アルファ機能を使用していないため、直近のバージョンのクラスタであればどれでも利用できます。具体的には `kubectl alpha debug` コマンドの `--copy-to` フラグを使用します。下記では、`mypod` Pod をデバッグ対象の Pod として、このオリジナル Pod のデバッグコンテナとして `busybox` をサイドカーコンテナとして追加し、プロセスネームスペースの共有を有効にしたコピーの Pod を `my-debugger` Pod として作成します。

```
# Create a debug container as a copy of the original Pod and attach to it
kubectl alpha debug mypod -it --image=busybox --copy-to=my-debugger
```

もう1つは、ノードのデバッグを目的とした Pod を作成する機能です。具体的には対象ノードのホスト OS の各 namespaces を使い（ここでの namespaces は Kubernetes のではなく、Linux namespaces のことで、ホストの IPC、ネットワーク、PID の namespaces を使います） や、ホストの `/` をコンテナの `/host` にマウントした Pod を特定のノード上で実行するというものです。かなり強い権限を必要とするため、基本的に利用するのはクラスタ管理者です。具体的には下記のように `kubectl alpha debug` コマンドをノードを対象に実行します。下記では `mynode` ノードを対象に `busybox` イメージを使ってデバッグコンテナを実行します。新機能！という感じではなく、便利なユーティリティが追加されたという感じでしょうか。

```
# Create an interactive debugging session on a node and immediately attach to it.
# The container will run in the host namespaces and the host's filesystem will be mounted at /host
kubectl alpha debug node/mynode -it --image=busybox
```

そのほか、`kubectl debug` コマンドの詳細については [KEP](https://github.com/kubernetes/enhancements/blob/af6569825edbc4f9591ac31b85c217e73e48fc06/keps/sig-cli/20190805-kubectl-debug.md) を参照ください。

## Urgent Upgrade Notes（必ず一読してからアップグレードしなければならない事項）

- `kubectl get` コマンド `--export` フラグの削除 ([#88649](https://github.com/kubernetes/kubernetes/pull/88649), [oke-py](https://github.com/oke-py)) [SIG CLI and Testing]

## API Changes（API の変更）

- `kubectl edit` コマンドでの `metadata.managedFields` フィールドの非表示 ([#91946](https://github.com/kubernetes/kubernetes/pull/91946), [soltysh](https://github.com/soltysh)) [SIG CLI]
    - :memo: `metadata.managedFields` フィールドは Server-side Apply で使用する管理用のフィールドです。ユーザが触るフィールドではないので、非表示になったことで少し便利になります。

## Feature（機能）

- `kubectl create deployment` コマンドへの `--port` フラグの追加 ([#91113](https://github.com/kubernetes/kubernetes/pull/91113), [soltysh](https://github.com/soltysh)) [SIG CLI and Testing]
    - :memo: Deployment `spec.template.spec.containers.ports` フィールドを設定します。
- `kubectl scale` コマンドの Client-side および Server-side でのドライランのサポート ([#89666](https://github.com/kubernetes/kubernetes/pull/89666), [julianvmodesto](https://github.com/julianvmodesto)) [SIG CLI and Testing]
- `kubectl diff` コマンドへの `--selector` (`-l`) フラグの追加 ([#90857](https://github.com/kubernetes/kubernetes/pull/90857), [sethpollack](https://github.com/sethpollack)) [SIG CLI]
    - :memo: `--selector` フラグで差分を検出する対象をフィルタできるようになりました。
- `kubectl run` コマンドへの `--privileged` フラグの追加 ([#90569](https://github.com/kubernetes/kubernetes/pull/90569), [brianpursley](https://github.com/brianpursley)) [SIG CLI]
    - :memo: Privileged モードでコンテナを作成できるようになりました。
- `kubectl taint` コマンドでの `no` 省略形のサポート ([#88723](https://github.com/kubernetes/kubernetes/pull/88723), [wawa0210](https://github.com/wawa0210)) [SIG CLI]
    - :memo: `kubectl taint` コマンドでは、`node` または `nodes` という完全なリソース名を指定しなければなりませんでしたが、省略形もサポートされました。
- `kubectl port-forward` コマンドが UDP をサポートしていないことを利用者に警告する ([#91616](https://github.com/kubernetes/kubernetes/pull/91616), [knight42](https://github.com/knight42)) [SIG CLI]
    - :memo: UDP をサポートしていないことに利用者が気づかずにデバッグに時間を浪費しないようにするための変更です。
- `kubectl alpha debug` コマンドがオリジナルのコピーによる Pods のデバッグをサポート ([#90094](https://github.com/kubernetes/kubernetes/pull/90094), [aylei](https://github.com/aylei)) [SIG CLI]
    - :memo: デバッグ対象の Pod に対してデバッグコンテナのサイドカーコンテナとしての追加とプロセスネームスペースの共有（Pod `spec.shareProcessNamespaces`）を有効にしたコピーを追加で作成する
- `kubectl alpha debug` コマンドがノードのホスト namespaces で実行されるデバッグコンテナの作成によるノードのデバッグをサポート ([#92310](https://github.com/kubernetes/kubernetes/pull/92310), [verb](https://github.com/verb)) [SIG CLI]
    - :memo: ホスト OS の各 namespaces を使い、ホストの `/` をコンテナの `/host` にマウントした Pod を特定のノード上で実行する

## Bug or Regression（バグまたはリグレッション）

- `kubectl cluster-info dump` コマンドの `namespaces` フラグが機能していないバグの修正 ([#91890](https://github.com/kubernetes/kubernetes/pull/91890), [zhouya0](https://github.com/zhouya0)) [SIG CLI]
    - :memo: クラスタ情報をダンプするコマンドで、`--namespaces` フラグはダンプする Namespace を指定するフラグですが（デフォルトは `kube-system` Namespace）、このフラグを処理するコードがどこかで削除されてしまったようで、全く機能していなかったようです。
- `kubectl create` コマンドの `--dry-run=client` フラグが `--namespace` フラグを無視するバグを修正 ([#90502](https://github.com/kubernetes/kubernetes/pull/90502), [zhouya0](https://github.com/zhouya0))
    - :memo: `kubectl create` コマンドのなかでも `role/job/cronjob` の場合にだけ `--namespace` フラグが機能していなかったようです。
- `kubectl create secret docker-registry` コマンドで `--from-file` オプションが使えなかったバグを修正 ([#90960](https://github.com/kubernetes/kubernetes/pull/90960), [zhouya0](https://github.com/zhouya0)) [SIG CLI and Testing]
    - :memo: このコマンドは、`--from-file` オプションが存在しているにも関わらず、`--docker-password` と `--docker-username` のオプションが必須扱いになっていました。
    - :memo: この PR によって、`--from-file` オプションによって`docker-registry` タイプの Secret オブジェクトも作成できるように修正されています。
- `kubectl describe CSINode` コマンドの `nil pointer error` を修正 ([#89646](https://github.com/kubernetes/kubernetes/pull/89646), [zhouya0](https://github.com/zhouya0)) [SIG CLI]
    - :memo: CSINode オブジェクトの `spec.drivers.allocatable.count` フィールドは `*int32` で定義されているため、`nil` じゃないかの確認が必要だったということでした。
    - https://github.com/kubernetes/api/blob/v0.19.0/storage/v1/types.go#L481
- `lease` 情報へのアクセス権限を持たないユーザが `kubectl describe node` コマンドを使えるように修正 ([#90469](https://github.com/kubernetes/kubernetes/pull/90469), [uthark](https://github.com/uthark)) [SIG CLI]
    - :memo: v1.17.0 から `kubectl describe node` コマンドで coordination.k8s.io/v1.Lease オブジェクトの情報を出力するように変更されましたが、RBAC 等で Lease オブジェクトへの参照権限を持たないユーザでコマンドの実行が失敗するようになってしまっていたようです。
    - :memo: Lease オブジェクトは、Node ハートビート機能の1つで、巨大なクラスタにおいて Node ステータスの更新によるハートビートの負荷軽減を目的に導入された機能で v1.17 で GA しました。詳しくは [KEP](https://github.com/kubernetes/enhancements/blob/0460fcf4637d440ce7d539a931e44dae931f9849/keps/sig-node/0009-node-heartbeat.md) を参照してください。
- `kubectl describe` コマンドにおけて anntations が空の場合の出力形式を修正 ([#91405](https://github.com/kubernetes/kubernetes/pull/91405), [iyashu](https://github.com/iyashu)) [SIG CLI]
    - :memo: annotations が空の場合に `<none>` と出力されることが望まれていたが、実際には何も出力されていなかったようです。
- `kubectl diff` コマンドがパッチを永続化してしまうバグを修正 ([#89795](https://github.com/kubernetes/kubernetes/pull/89795), [julianvmodesto](https://github.com/julianvmodesto)) [SIG CLI and Testing]
    - :memo: `kubectl diff` コマンドを実行すると指定したマニフェストファイルとクラスタに記録されたオブジェクトの差分を出力してほしいだけのところ、1.18 の `kubectl` コマンドと 1.17 の API サーバの組み合わせで差分をクラスタに適用してしまうというバグがありました。
    - :memo: この修正は v1.18 に cherry-pick されており、v1.18.1 のパッチリリースに含まれています。
- `kubectl run` コマンドの `--dry-run=client` フラグが `--namespace` フラグの指定を無視するバグを修正 ([#90785](https://github.com/kubernetes/kubernetes/pull/90785), [zhouya0](https://github.com/zhouya0)) [SIG CLI]
- `kubectl version` コマンドで kubeconfig ファイルがない場合にもバージョン情報を出力するように修正 ([#89913](https://github.com/kubernetes/kubernetes/pull/89913), [zhouya0](https://github.com/zhouya0)) [SIG API Machinery and CLI]
    - :memo: `--client=true` の有無に関わらず kubeconfig ファイルが存在しないとクライアントの情報でさえ出力されない状態でした。
- `kubectl alpha debug` コマンドの `--container` フラグに `-c` の省略形が設定されていないのを修正 ([#89674](https://github.com/kubernetes/kubernetes/pull/89674), [superbrothers](https://github.com/superbrothers)) [SIG CLI]
    - :memo: ヘルプメッセージ上では省略形が設定されていることになっていましたが、実際には存在しなかったため修正しました。
- kubeconfig ファイルが存在しないと `--local` または `--dry-run` フラグを使用しての `kubectl` コマンドの実行に失敗するバグを修正 ([#90243](https://github.com/kubernetes/kubernetes/pull/90243), [soltysh](https://github.com/soltysh)) [SIG API Machinery, CLI and Testing]
- ZSH の補完の初期化時に初期化に成功した場合にもゼロ以外の終了ステータスが返るバグの修正 ([#88165](https://github.com/kubernetes/kubernetes/pull/88165), [brianpursley](https://github.com/brianpursley)) [SIG CLI]
- `scale` サブリソースが有効な CustomResourceDefinition で、`replicas` フィールドのデフォルト値が定義されないバグを修正[#89833](https://github.com/kubernetes/kubernetes/pull/89833), [liggitt](https://github.com/liggitt)) [SIG API Machinery, CLI, Cloud Provider, Cluster Lifecycle and Instrumentation]
- エラーの際に止まるのではなく全ての有効なオブジェクトを適用するように `kubectl` を修正 ([#89848](https://github.com/kubernetes/kubernetes/pull/89848), [seans3](https://github.com/seans3)) [SIG CLI and Testing]
- Event オブジェクトの `firstTimestap` フィールドが設定されていない場合には、`eventTime` フィールドを使うように修正 ([#89999](https://github.com/kubernetes/kubernetes/pull/89999), [soltysh](https://github.com/soltysh)) [SIG CLI]
- `kubectl` または client-go の jsonpath は maps / slices / structs 型を Go シンタックスに変わりに JSON でのシリアライズをサポート([#89660](https://github.com/kubernetes/kubernetes/pull/89660), [pjferrell](https://github.com/pjferrell)) [SIG API Machinery, CLI and Cluster Lifecycle]
    - :memo: `kubectl` コマンドの `--output=jsonpath-as-json` フラグで使えるようです。
- `kubectl autoscale` コマンドが `--name` フラグを受け付けないバグを修正 ([#91855](https://github.com/kubernetes/kubernetes/pull/91855), [SataQiu](https://github.com/SataQiu)) [SIG CLI]
- `kubectl scale` コマンドが `--timeout` フラグを受け付けないバグを修正 ([#91858](https://github.com/kubernetes/kubernetes/pull/91858), [SataQiu](https://github.com/SataQiu)) [SIG CLI]
- v1 CSR API を提供するサーバに対する `kubectl certificate approve/deny` コマンド使用の問題を解消 ([#91691](https://github.com/kubernetes/kubernetes/pull/91691), [liggitt](https://github.com/liggitt)) [SIG Auth and CLI]
- `--namespace` フラグなしでの `kubectl apply --prune` コマンドの機能の復元。v1.17 以降、`kubectl apply --prune` は `default` Namespace (または kubeconfig から)か、コマンドラインフラグで明示的に指定された Namespace のリソースのみを prune するようになった。 しかし、これは kubectl 1.16 からの変更で、本来はマニフェストファイルのすべての Namespace のリソースに対して prune できた。このパッチは kubectl v1.16 の挙動を復元します。 ([#89551](https://github.com/kubernetes/kubernetes/pull/89551), [tatsuhiro-t](https://github.com/tatsuhiro-t)) [SIG CLI and Testing]
- `kubectl annotate` コマンドが `--list` オプションをサポート ([#92576](https://github.com/kubernetes/kubernetes/pull/92576), [zhouya0](https://github.com/zhouya0)) [SIG CLI]
    - :memo: オブジェクトの annotations がリストできるようになりました。`kubectl label` コマンドには存在していたフラグのようなので、`kubectl annotate` コマンドにも追加という感じでしょうか。

## Other (Cleanup or Flake)

- `--cache-dir` は、http とディスカバリの両方のキャッシュディレクトリを設定する。デフォルトは `$HOME/.kube/cache`。 ([#92910](https://github.com/kubernetes/kubernetes/pull/92910), [soltysh](https://github.com/soltysh)) [SIG API Machinery and CLI]
    - :memo: これまでは http のキャッシュは `$HOME/.kube/http-cache`、ディスカバリのキャッシュは `$HOME/.kube/cache/discovery` に保持されていましたが、両方で共通の親ディレクトリを持つように変更されました。
    - :memo: ディスカバリのキャッシュが保持されるディレクトリに変更はありませんが、http のキャッシュは `$HOME/.kube/cache/http` に変更されます。
- `DISABLE_KUBECONFIG_LOCK` 環境変数による kubeconfig ファイルのロックを無効にする機能の追加 ([#92513](https://github.com/kubernetes/kubernetes/pull/92513), [soltysh](https://github.com/soltysh)) [SIG API Machinery and CLI]
    - :memo: 当初、複数は `kubeconfig` ファイルの同時変更を防ぐ目的にロック機構を持つようにしていたが、現在ではそのような場合には複数の kubeconfig ファイルを持つようにすることを推奨しているとのこと。
- `kubectl get` コマンドを使用して namespaced ではないリソースを取得した際の "not found" メッセージの変更 ([#89861](https://github.com/kubernetes/kubernetes/pull/89861), [rccrdpccl](https://github.com/rccrdpccl)) [SIG CLI]
    - :memo: "namespaced" ではないリソース（not namespaced resources）というのは、クラスタレベルのリソースのことで、例えば PersistentVolume（PV）といったリソースのことです。
    - :memo: この変更では、クラスタレベルのリソースに対して `kubectl get` コマンドを使用した場合に、`No resources found in default namespace.` のような Namespace に言及するクラスタレベルのリソースに対してのふさわしくないメッセージが出力されていたところを、`No resources found.` と出力するように変更されています。
- `kubectl top` コマンドでの Heapster のサポートを削除 ([#87498](https://github.com/kubernetes/kubernetes/pull/87498), [serathius](https://github.com/serathius)) [SIG CLI]
    - :memo: `kubectl top` コマンドは、v1.8 から metrics-server による Metrics API をサポートし、Heapter によるメトリクスの提供は廃止予定となっていました。
- kubectl の各サブコマンドに専用のフィールドマネージャを設定することで、Server-side Apply での競合エラーを改善する ([#88885](https://github.com/kubernetes/kubernetes/pull/88885), [julianvmodesto](https://github.com/julianvmodesto)) [SIG CLI and Testing]
    - :memo: Server-side Apply は、`metadata.managedFields.manager` フィールドにどのコンポーネントがオブジェクトのどのフィールドを管理しているのかを記録します。もしあるコンポーネントが他のコンポーネントが管理するフィールドを操作しようとすると競合を検出します。
    - :memo: `kubectl` コマンドによるオブジェクトの変更は全て `kubectl` というフィールドマネージャに設定されていましたが、`kubectl` コマンドには annotations を操作する `kubectl annotate` コマンドなどのオブジェクトを操作する様々なサブコマンドが存在し、共通のフィールドマネージャを利用していることで、異なるコマンドによる変更にも関わらず競合を検知できていなかったようです。
    - :memo: この変更では、`kubectl` コマンドの各サブコマンドに専用のフィールドマネージャ（例えば `kubectl annotate` コマンドであれば `kubectl-annotate`）を設定することで、競合を検知できるように変更されています。
- 廃止予定だった `kubectl apply` コマンドの `--server-dry-run` フラグを削除 ([#91308](https://github.com/kubernetes/kubernetes/pull/91308), [julianvmodesto](https://github.com/julianvmodesto)) [SIG CLI and Testing]
    - :memo: 代わりに `--dry-run=server` フラグを使用します。
- `kubectl config view` がクライアント証明書のようにデフォルトで Bearer トークンを黒塗りするように変更。`--raw` フラグは引き続き内容を全て出力するのに使用できる。([#88985](https://github.com/kubernetes/kubernetes/pull/88985), [puerco](https://github.com/puerco))
    - :memo: `kubectl config view` コマンドは、デフォルトではクライアント証明書がそのまま出力されないように `REDACTED` という形で黒塗りされるようになっていますが、Bearer トークンも同じ形で黒塗りされるようになりました。

## 所感

`kubectl alpha debug` コマンドに2つの新機能が追加された以外には目新しい変更はありませんでした。廃止予定 API の警告が表示されるようになったのは便利そうです。Server-side Apply が使われるようになり、これに関する不具合の修正も目立ちます。`kubectl get` コマンドの `--export` フラグが完全に削除されました。もしスクリプトで利用している方がいれば注意してください。