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

## はじめに

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

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

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

- `--show-managed-fields` フラグ: もし `true` の場合、JSON または YAML 形式でオブジェクトを出力する際に `managedFields` をそのままにする
    - :memo: これまで出力されていた `metadata.managedFields` がデフォルトでは出力されなくなりました。出力したい場合が明示的に `--show-managed-fields` フラグを使用する必要があります
    - :memo: `metadata.managedFields` は Server Side Apply で使用されるフィールドで、誰がどのフィールドを管理しているかの記録に使用されています
- `-q` ショートフラグ: `--quiet` フラグのショートフラグとして追加
- `kubectl drain --ignore-errors` フラグ: ドレインするノード群のなかで発生したエラーを無視する
    - :memo: これまでドレイン中にあるノードで失敗すると処理が中断されていましたが、この挙動は廃止予定となり、今後はエラーが発生しても対象のすべてのノードでドレインが実行されるように変更されます。このフラグを使用することで、将来的なデフォルトの挙動を先に試すことができます。
- `kubectl top --use-protocol-buffers` フラグ: 使用すると、メトリクスのリクエストに Protocol Buffers が使われる

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

- `kubectl kustomize` コマンドと `kubectl apply -k` フラグ: Kustomize バージョンが v2.0.3 から v4.0.5 に更新

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

- `kubectl run` コマンド: `--serviceaccount, --hostport, --requests, --limits` フラグ

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

- `kubectl run` コマンド: `--generator, --replicas, --service-generator, --service-overrides, --schedule` フラグ

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

## What's New (新情報)

### Kubectl の Kustomize の更新

> kubectl の [Kustomize](https://github.com/kubernetes-sigs/kustomize) バージョンが v2.0.3 から [v4.0.5](https://github.com/kubernetes/kubernetes/pull/98946) にジャンプしました。Kustomize はライブラリとして扱われるようになり、将来の更新は不定期ではなくなります。

ついに kubectl に組み込まれていた Kustomize（`kubectl kustomize`、`kubectl apply -k` など）が最新まで追従されました。v2.0.3 から v4.0.5 への更新で別物になっているため、これまで kubectl の kustomize 機能を使用していた人は十分に注意してください。

Kustomize ツールは単体で機能するツールで独自のリリースサイクルも持っているため、個人的にはこれまでもこれからも組み込まれている機能は使わないつもりです。

### デフォルトのコンテナを事前に選択できるアノテーション

> 複数のコンテナを含む Pod は、kubectl コマンドのために事前にコンテナを選択しておける `kubectl.kubernetes.io/default-container` アノテーションを使用できるようになりました。詳しくは [KEP-2227](https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/2227-kubectl-default-container/README.md) を参照してください。

これまでは kubectl で `--container` オプションを使用していなかった場合には次の挙動になっていました。

- `kubectl exec/attach/cp`: デフォルトで最初のコンテナを選択する
- `kubectl logs`: デフォルトはなく、`kubectl.kubernetes.io/default-logs-container` アノテーションがある場合はそれで指定されたコンテナを選択する

例えば Pod にサイドカーコンテナを挿入するサービスメッシュのプロダクトを採用した場合に、そのサービスメッシュがコンテナリストの先頭にサイドカーコンテナを挿入するようになっていると、これまでアプリケーションコンテナに対して実行されていたコマンドがサイドカーコンテナ内で実行されるようになってしまうという問題がありました。

`kubectl.kubernetes.io/default-container` アノテーションにより、事前にデフォルトで選択されるコンテナを指定できるようにすることで上記の課題が解決されます。

```yaml
apiVersion: v1
kind: Pod
metadata:
 annotations:
    kubectl.kubernetes.io/default-container: app
```

なお、このアノテーションが使用されていない場合は、これまでと同じリストの先頭のコンテナがデフォルトで選択されます。

このアノテーションがサポートされたことで `kubectl logs` コマンドが `kubectl.kubernetes.io/default-logs-container` アノテーションを使用してデフォルトのコンテナを事前に選択できる機能がありましたが、これは廃止予定になり v1.25 で削除される予定です。代わりに `kubectl.kubernetes.io/default-container` を使用する必要があります。

kubectl プラグイン等でこのアノテーションをサポートしたい場合には `podcmd.FindOrDefaultContainerByName` 関数が便利につかえます。

- https://github.com/kubernetes/kubectl/blob/v0.21.0/pkg/cmd/util/podcmd/podcmd.go#L53-L90

## Known Issues（既知の問題）

なし

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

なし

## Changes by Kind（種類別の変更）

### Deprecation (廃止)

- `kubecctl run` コマンドから廃止予定だった `--generator, --replicas, --service-generator, --service-overrides, --schedule` オプションが削除され、`--serviceaccount, --hostport, --requests, --limits` が廃止予定になりました ([#99732](https://github.com/kubernetes/kubernetes/pull/99732), [soltysh](https://github.com/soltysh))
- Kubectl: 廃止予定だった `kubectl alpha debug` コマンドが削除されました。代わりに `kubectl debug` を使用してください。 ([#98111](https://github.com/kubernetes/kubernetes/pull/98111), [pandaamanda](https://github.com/pandaamanda)) [SIG CLI]

### API Change (API 変更)

- コネクションを維持するために SPDY pings が有効になり、`kubectl exec` と `kubectl port-forward` が中断されないようになりました ([#97083](https://github.com/kubernetes/kubernetes/pull/97083), [knight42](https://github.com/knight42)) [SIG API Machinery and CLI]
    - :memo: SPDY pings の間隔は 5s となっており変更できません

### Feature（機能）

- `kubectl drain` コマンドをノードのリストに対して実行した際に途中で中断される挙動は廃止予定です。この新しい挙動は、ドレイン中にいくつかのノードで失敗したとしても対象のすべてのノードでコマンドが実行されるようになります。現時点では、ユーザは `--ignore-errors` フラグを使用してこの挙動を試すことができます。 ([#98203](https://github.com/kubernetes/kubernetes/pull/98203), [yuzhiquan](https://github.com/yuzhiquan))
- Kubectl コマンドヘッダのアルファ実装: クライアントのコマンドラインで KUBECTL_COMMAND_HEADERS 環境変数が設定されていると SIG CLI KEP 859 が有効になります ([#98952](https://github.com/kubernetes/kubernetes/pull/98952), [seans3](https://github.com/seans3))
    - :memo: kubectl から apiserver へのリクエストにどんなコマンド（`apply`, `delete` など）でどんなオプションを使用したのかの情報をヘッダで付与するようになる KEP です。クラスタ管理者はユーザがどのようなコマンドを使用して問題が発生したのかどうかなどを知れるようになり、問題の特定が容易になることが期待できます。
- `kubectl version` はクライアントとサーバのバージョン差異がサポートするバージョンスキュー（+/-1 マイナバージョン）を超えている場合に警告メッセージを出力するように変更されました ([#98250](https://github.com/kubernetes/kubernetes/pull/98250), [brianpursley](https://github.com/brianpursley)) [SIG CLI]
- Kubectl: `kubectl top pods/nodes` に `--use-protocol-buffers` フラグが追加されました ([#96655](https://github.com/kubernetes/kubernetes/pull/96655), [serathius](https://github.com/serathius))
    - :memo: PR のコメントによると metrics-server の CPU の 30% とメモリ の 15% は JSON のエンコードに使用されていて、それを削減できるようです
    - :memo: `--use-protocol-buffers` はデフォルト `false` のため、使用するには明示的に指定する必要があります
- Kubectl: `kubectl get` は、デフォルトで managed fields を出力しないようになりました。出力形式が `json` または `yaml` の場合に、ユーザは `--show-managed-fields` を `true` に設定することで `managedFields` を出力できます。 ([#96878](https://github.com/kubernetes/kubernetes/pull/96878), [knight42](https://github.com/knight42)) [SIG CLI and Testing]
    - :memo: `kubectl get -o yaml` で出力されてとても見にくかった `metadata.managedFields` がデフォルトで出力されないようになりました。
    - :memo: managedFields は Server Side Apply で誰がどのフィールドを管理しているのかを管理するためのフィールドです。詳しくは [Kubernetes 1\.14: Server\-side Apply \(alpha\) \- Qiita](https://qiita.com/superbrothers/items/aeba9406691388b6a19e) を参照してください。
- Kubectl: `kubectl get` でカンマで区切られたリストを bash-completion がサポートしました ([#98301](https://github.com/kubernetes/kubernetes/pull/98301), [phil9909](https://github.com/phil9909))
- ユーザは Pod で `kubectl.kubernetes.io/default-container` アノテーションを使用して kubectl コマンドで対象とするコンテナを事前に選択できるようになりました ([#99581](https://github.com/kubernetes/kubernetes/pull/99581), [mengjiao-liu](https://github.com/mengjiao-liu)) [SIG CLI]
- `kubectl wait` は、古い状態の報告を防ぐために observedGeneration >= generation を保証します。シナリオの例は、CRD のアップデートにあります。([#97408](https://github.com/kubernetes/kubernetes/pull/97408), [KnicKnic](https://github.com/KnicKnic))
    - :memo: すでにオブジェクトの spec が変更されていて、その変更により `kubectl wait` の条件にマッチしなくなるような状況で、status がまだ変更されていないことで条件に一致してしまいコマンドが終了してしまう事態を避けることができるようになるようです

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

- `--dry-run=client` で Deployment を公開（expose）する場合に Namespace の指定に効果がないバグが修正されました ([#97492](https://github.com/kubernetes/kubernetes/pull/97492), [masap](https://github.com/masap)) [SIG CLI]
- `KUBECTL_EXTERNAL_DIFF` がイコール（`=`）を追加のパラメータとして受け入れるようになりました ([#98158](https://github.com/kubernetes/kubernetes/pull/98158), [dougsland](https://github.com/dougsland)) [SIG CLI]
    - :memo: `KUBECTL_EXTERNAL_DIFF` 環境変数は `kubectl diff` コマンドで任意の `diff` コマンドとパラメータを使用できる機能ですが、これまでイコールを受け入れなかったため、`KUBECTL_EXTERNAL_DIFF="diff --color=auto"` のような指定ができなかったようです
- kubectl describe: API Group なしの Ingress backend を含む場合にパニックになるバグが修正されました ([#100505](https://github.com/kubernetes/kubernetes/pull/100505), [lauchokyip](https://github.com/lauchokyip)) [SIG CLI]
- `kubectl kustomize {arg}` と `kubectl apply -k {arg}` が kustomize CLI [v4.0.5](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.0.5) のコードを使うように更新されました ([#98946](https://github.com/kubernetes/kubernetes/pull/98946), [monopole](https://github.com/monopole))
- `kubectl exec` と `kubectl attach` は、リモートコマンド出力と混同される可能性のあるローカルバイナリからの出力を抑制する `--quiet` コマンドをサポートしました（全てのエラーでない出力が非表示）。加えて `kubectl exec` と `attach` でデフォルトのコンテナが使用された場合に、選択できるコンテナのリストが出力されるようになりました ([#99004](https://github.com/kubernetes/kubernetes/pull/99004), [smarterclayton](https://github.com/smarterclayton)) [SIG CLI]
- client-go exec credential plugins は、stdin でインタラクティブターミナルが検出された場合にのみ stdin を通過させるようになりました。これは以前は "stdout" がインタラクティブターミナルかどうかを確認していたことの修正です。 ([#99654](https://github.com/kubernetes/kubernetes/pull/99654), [ankeesler](https://github.com/ankeesler))
- Kubectl logs: `--ignore-errors` はすべてのコンテナで尊重されるようになり、`parallelConsumeRequest` の挙動と一貫性が保たれます ([#97686](https://github.com/kubernetes/kubernetes/pull/97686), [wzshiming](https://github.com/wzshiming))
- Kubectl-convert: `no kind "Ingress" is registered for version` エラーが修正されました ([#97754](https://github.com/kubernetes/kubernetes/pull/97754), [wzshiming](https://github.com/wzshiming))

### Other (そのほか)

なし

## 所感

ついに kubectl コマンドに組み込まれていた kustomize が更新されました。これはうれしいユーザが多いのではないかと思います。大きくバージョンに乖離があり、これまで使えていた `kustomization.yaml` が使えなくなっているので注意が必要です。個人的には kustomize は単体で使えるのだからビルトインしなくてよいのにという強い気持ちを持っています。

v1.21 でベータに昇格してデフォルトで有効化が予定されていた `kubectl debug` のデバッグコンテナ機能（Ephemeral Containers）は昇格が見送られました。SIG Auth が API の大幅な変更をリクエストしたためだそうです。とても強力な機能なため期待していましたが、次回に期待しましょう。なお、アルファレベルの機能として `EphemeralContainers` フィーチャゲートを有効にすることで使用することもできます。

- [Ephemeral Containers \| Kubernetes](https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/)

---

CHANGELOG でときどき SIG の指定のない変更があり、そこに SIG CLI の変更がちょくちょく含まれていて探すのが大変でした。これは困るので今後修正してもらいたい。SIG Release に言えばよいだろうか。