Kubernetes 1.16: SIG-CLI の変更内容

## はじめに

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

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

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

- `kubectl get --output-watch-events` フラグ: イベントタイプ（ADDED, MODIFIED, DELETED）のカラムを出力に追加
- Server-Side Apply に関連する `kubectl apply` の次のフラグ
    - `--server-side`
    - `--force-conflicts`
    - `--field-manager`
- `kubectl delete --raw` フラグ: kubeconfig ファイルの認証情報を使った apiserver への DELETE メソッドでのアクセス
- `kubectl replace --raw` フラグ: kubeconfig ファイルの認証情報を使った apiserver への PUT メソッドでのアクセス

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

- `kubectl convert`（v1.17 で削除予定）
- `kubectl get --export` フラグ（v1.18 で削除予定）

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

- `kubectl get/annotate/apply/delete/describe/edit/label/set --include-uninitialized` フラグ
- Server-Side Apply に関連する `kubectl apply` の次のフラグ
    - `--experimental-server-side`
    - `--experimental-force-conflicts`
    - `--experimental-field-manager`

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

## What's New (新情報)

SIG-CLI に関する大きな変更はありません。

## Deprecations and Removals (廃止および削除）

- v1.14 から廃止予定となっていた `kubectl convert` コマンドは v1.17 で削除されます
- v1.14 から廃止予定となっていた `kubectl get` コマンドの `--export` フラグは v1.18 で削除されます
    - :memo: `--export` は YAML 形式等でマニフェストを出力した際に、`status` や `metadata.resourceVersion` といったクラスタ固有のフィールド（apiserver や Kubernetes コントローラが付与するフィールド）を除くフラグです
    - :memo: しかし既存の利用者が多く、代替手段もないことで[イシューが盛り上がっています](https://github.com/kubernetes/kubernetes/pull/73787)
- `kubectl cp` コマンドは、コンテナからのシンボリックリンクのコピーのサポートがなくなりました。このユースケースをサポートするには、`tar` コマンドを直接使用する例が `kubectl exec --help` で参照できます ([#82143](https://github.com/kubernetes/kubernetes/pull/82143), [soltysh](https://github.com/soltysh))

    ```bash
    # For advanced use cases, such as symlinks, wildcard expansion or
    # file mode preservation consider using 'kubectl exec'.
    
    # Copy /tmp/foo local file to /tmp/bar in a remote pod in namespace <some-namespace>
    tar cf - /tmp/foo | kubectl exec -i -n <some-namespace> <some-pod> -- tar xf - -C /tmp/bar
    # Copy /tmp/foo from a remote pod to /tmp/bar locally
    kubectl exec -n <some-namespace> <some-pod> -- tar cf - /tmp/foo | tar xf - -C /tmp/bar
    ```


- 廃止予定となっていた `--include-uninitialized` フラグが削除されました ([#80337](https://github.com/kubernetes/kubernetes/pull/80337), [draveness](https://github.com/draveness))
    - :memo: このフラグは、`kubectl get` や `kubectl apply` といったコマンドで初期化されていないオブジェクトを対象にするというものでした
    - :memo: 「初期化されていないオブジェクト」というのは、`metadata.initializers` が空ではないオブジェクトのことで、例えば一部の Initializer の処理がまだ完了する前のオブジェクトなどです
    - :memo: Initializer 機能は 1.14 で削除されています

## 主な機能

### ベータ

- Server-Side Apply 機能がベータになりました ([#81956](https://github.com/kubernetes/kubernetes/pull/81956), [apelisse](https://github.com/apelisse))
    - :memo: ベータ昇格により、FeatureGate `ServerSideApply` がデフォルトで有効化されます
    - :memo: 合わせて、`kubectl apply` の Server Side Apply に関連したフラグの名前が変更されます
        - `--experimental-server-side` → `--server-side`
        - `--experimental-force-conflicts` → `--force-conflicts`
        - `--experimental-field-manager` → `--field-manager`
    - :memo: `--server-side` フラグは無効のままとなっているため、デフォルトでこの機能は利用されません
    - :memo: Server Side Apply の概要については、[Kubernetes 1\.14: Server\-side Apply \(alpha\)](https://qiita.com/superbrothers/items/aeba9406691388b6a19e) を参照してください

### アルファ

- エフェメラル（揮発的な）コンテナがアルファで追加されました。この一時的なコンテナは `kubectl exec` が既存のコンテナ内でプロセスを実行するのと似て、デバッグ目的で実行中の Pods に追加されます。また、`kubectl exec` と同様にエフェメラルコンテナのリソースは確保されず、終了しても再起動されません。container namespace targeting はまだ実装されていないため、Pod 内の他のコンテナからプロセスを確認するために [PID ネームスペースの共有](https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/)を有効にしなければならないことに注意してください。([#59484](https://github.com/kubernetes/kubernetes/pull/59484), [verb](https://github.com/verb))
    - :memo: つまり、デバッグ用のコンテナを Pod の一部としてあとから実行し、実行中のコンテナをデバッグできるという機能です
    - :memo: この機能を使用するには `EphemeralContainers` Feature Gate を有効化する必要があります
    - :memo: container namespace targeting というのは、Linux namespaces を共有する Pod 内のコンテナを明示的に指定する機能のことで、この機能は 1.17 で提供予定となっています。そのため 1.16 時点では PID ネームスペースの共有（Pod `spec.shareProcessNamespace` を `true` に設定）を有効にする必要があります。
    - :memo: `kubectl` でこの機能を利用するコマンド（`kubectl debug`）は 1.16 で提供されていません。1.17 で提供予定となっていますが、[kubectl-debug プラグイン](https://github.com/verb/kubectl-debug) として PoC があります。
    - :memo: 詳しくは KEP、イシューを参照してください
        - https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190212-ephemeral-containers.md
        - https://github.com/kubernetes/enhancements/issues/277
    - :memo: [Kubernetes 1\.16: Ephemeral Containers \(alpha\) \- Qiita](https://qiita.com/superbrothers/items/85edec4d0232e0bbe2c0) で動作を検証しています 

### CLI の改善

- kubectl の `--all-namespaces`/`-A` フラグが `kubectl wait` コマンドで機能するように改善されました([#81468](https://github.com/kubernetes/kubernetes/pull/81468), [ashutoshgngwr](https://github.com/ashutoshgngwr))
- `kubectl get -w/--watch` は、イベントタイプ（ADDED, MODIFED, DELETED) を表示する `--output-watch-events` フラグを合わせて利用できるようになりました ([#72416](https://github.com/kubernetes/kubernetes/pull/72416), [liggitt](https://github.com/liggitt))
    - :memo: `kubectl get -w` とともに合わせて `--output-watch-events` を指定することでで出力されるカラムにイベントタイプが追加されます
 
        ```
        $ kubectl get ns -w --output-watch-events
        EVENT      NAME              STATUS   AGE
        ADDED      default           Active   84m
        ADDED      kube-node-lease   Active   84m
        ADDED      kube-public       Active   84m
        ADDED      kube-system       Active   84m
        ADDED      ns1               Active   0s
        MODIFIED   ns1               Terminating   5s
        MODIFIED   ns1               Terminating   10s
        DELETED    ns1               Terminating   10s
        ```

- kubectl に Endpoint Slice リソースのサポートが追加されました。この機能は discovery API グループが有効なときに機能します。 ([#81795](https://github.com/kubernetes/kubernetes/pull/81795), [robscott](https://github.com/robscott))
    - :memo: discovery API グループ（`discovery.k8s.io`）は Endpoint Slice リソースが属する API グループのことです。

## その他の主な変更

- CVE-2019-11249 の修正: kubectl cp でのディレクトリトラバーサルである CVE-2019-1002101 および CVE-2019-11246 の一時的な修正 ([#80436](https://github.com/kubernetes/kubernetes/pull/80436), [M00nF1sh](https://github.com/M00nF1sh))
- オーバーライドされるフラグに関する bash 補完のエラーの修正 ([#80802](https://github.com/kubernetes/kubernetes/pull/80802), [dtaniwaki](https://github.com/dtaniwaki))
- kube-apiserver でパニックを引き起こすサーバサイドプリントのバグを修正 ([#79349](https://github.com/kubernetes/kubernetes/pull/79349), [roycaihw](https://github.com/roycaihw))
- `kubectl cp` コマンドでコピーしたファイルでの "time stamp is the future"（タイムスタンプが未来です）エラーの修正 ([#73982](https://github.com/kubernetes/kubernetes/pull/73982), [tanshanshan](https://github.com/tanshanshan))
- 不正なプロパティ名を指定した際に `kubectl set config` コマンドがハングし、CPU を使い切ってしまうバグの修正 ([#79000](https://github.com/kubernetes/kubernetes/pull/79000), [pswica](https://github.com/pswica))
- 単一リソースをウォッチした際の `kubectl get --watch-only` の出力が修正されました ([#79345](https://github.com/kubernetes/kubernetes/pull/79345), [liggitt](https://github.com/liggitt))
    - :memo: 出力部分のロジックにバグがあったようで、単一リソースをウォッチした場合に何も出力されていなかったようです（正しくは改行のみ出力）
- `kubectl get --ignore-not-found` はエラーに遭遇しても処理を実行するように修正されました  ([#82120](https://github.com/kubernetes/kubernetes/pull/82120), [soltysh](https://github.com/soltysh))
    - :memo: `kubectl get` コマンドの `--ignore-not-found` は、指定したオブジェクトが存在しない場合でもエラーを無視する（終了コードが0になる）フラグです
    - :memo: この修正は、より正確にいうと `kubectl get -f search.yaml --ignore-not-found`（search.yaml は次のように List オブジェクト）の場合でのみエラーで処理が中断されていました
  
        ```yaml
        # search.yaml
        apiVersion: v1
        kind: List
        metadata:
          resourceVersion: ""
          selfLink: ""
        items:
        - apiVersion: v1
          kind: Secret
          metadata:
            name: attachdetach-controller-token-lkzp4
            namespace: kube-system
          type: kubernetes.io/service-account-token
        - apiVersion: v1
        ...
        ```

- kubectl が再度カスタムリソースをスケールできるようになりました ([#81342](https://github.com/kubernetes/kubernetes/pull/81342), [knight42](https://github.com/knight42))
- kubectl が PodOverhead を考慮するようになりました ([#81929](https://github.com/kubernetes/kubernetes/pull/81929), [egernst](https://github.com/egernst))
    - :memo: `kubectl describe node` の情報に PodOverhead が加わるようです

## 所感

`kubectl debug`（エフェメラルコンテナ）は、当初 v1.7 で提供される予定だったので、もう来ないものかと考えていましたが、ついに機能の提供が始まりました:tada::tada::tada: 全ての機能がアルファで揃うのは 1.18 の予定となっているので、GA になるのは最速で 1.20 です。まだまだ先は長いですが、期待して待ちます。