Kubernetes 1.16: SIG Cluster Lifecycle の変更内容

## はじめに

[Kubernetes 1.16 の CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.16.md) から SIG Cluster Lifecycle の取り組みについてにピックアップしました。3行でまとめると、「リリースノートに掲載される量は多い代わりにあまり面白い変更はありませんでした」です :grimacing: 。

## 注目機能 (Notable Features)

### Beta

- なし

### Alpha

- なし

### CLI Improvements

- なし

### Misc

- **kubeadm: 複数の etcd のメンバの追加/削除処理が同時に行えるようになりました。([#79677](https://github.com/kubernetes/kubernetes/pull/79677), [@neolit123](https://github.com/neolit123))**
    - :pencil: 同時にetcdのメンバを追加した場合、今までは一台のメンバ追加時にetcdクラスタがvoteの状態へと移行し、他のメンバの追加でエラーが発生していましたが、リトライするように実装されたようです。
- **kubeadm: Linux Kernel 3.10 以上のカーネル全てをサポートするようになりました。([#81623](https://github.com/kubernetes/kubernetes/pull/81623), [@neolit123](https://github.com/neolit123))**
    - :pencil: カーネルバージョンのバリデーションに利用していた正規表現が以下のように修正されたようです。
      <pre>- Versions: []string{`3\.[1-9][0-9].*`, `4\..*`, `5\..*`}, // Requires 3.10+, 4+ or 5+
\+ Versions: []string{`^3\.[1-9][0-9].*$`, `^([4-9]|[1-9][0-9]+)\.([0-9]+)\.([0-9]+).*$`}, // Requires 3.10+, or newer</pre>
- **kubeadm の `ClusterConfiguration` が featureGates: `IPv6DualStack: true` に対応しました。([#80145](https://github.com/kubernetes/kubernetes/pull/80145), [@Arvinderpal](https://github.com/Arvinderpal)) ([#80531](https://github.com/kubernetes/kubernetes/pull/80531), [@Arvinderpal](https://github.com/Arvinderpal))**
    - :pencil: kubeadm を利用して、kubernetes の IPv6 デュアルスタックを有効化するためには、`ClusterConfiguration` の設定ファイル中で `IPv6DualStack=true` を設定したのちに、各ノードの kubelet の設定で `nodeRegistration.kubeletExtraArgs` か、`KUBELET_EXTRA_ARGS` を利用して FeatureGate を有効化する必要があります。

## その他の注目すべき変更 (Other notable changes)

### Cluster Lifecycle
- **kubeadm upgrade diff 時に、潜在的に null pointer exception が発生する問題を修正しました。([#80648](https://github.com/kubernetes/kubernetes/pull/80648), [@odinuge](https://github.com/@odinuge))**
- **kubeadm: HTTPのエラーが発生した場合、kubeadm のクライアントのバージョンにフォールバックするようになりました。([#80024](https://github.com/kubernetes/kubernetes/pull/80024), [@RainbowMango](https://github.com/@RainbowMango))**
    - :pencil: kubeadm はコマンドの実行時に毎回、Kubernetes のリリースサーバーからリリースバージョンの取得を試みているようですが、インターネットアクセスに失敗した場合、必ずしも最新のリリースバージョンを取得する必要がないにも関わらず、コマンドの実行が失敗していたようです。この修正により、リリースサーバからのバージョンの取得に失敗した場合、クライアントのバージョンを利用するようになったようです。
- **kubeadm: 不正な kubeconfig ファイルが存在した場合に、kubeadmがパニックを発生する問題を修正しました。([#79165](https://github.com/kubernetes/kubernetes/pull/79165), [@neolit123](https://github.com/@neolit123))**
- **kubeadm: reset 時に致命的でない問題が発生した場合、警告として取り扱うよう修正しました。([#80862](https://github.com/kubernetes/kubernetes/pull/80862), [@drpaneas](https://github.com/@drpaneas))**
- **kubeadm: non-root ユーザで prepull することで、PSPがブロッキングしているイメージのアップグレードを解除しました。([#77792](https://github.com/kubernetes/kubernetes/pull/77792), [@neolit123](https://github.com/@neolit123))**
    - :pencil: kubeadm によるコンテナイメージのprepullを[rootユーザで行なっていたため](https://github.com/kubernetes/kubernetes/pull/77792/files#diff-0b4cd877b72b2bea06bf1568379c5fc8R187-R191)、PSP によりrootユーザのコンテナイメージの実行が禁止されていた場合 prepull が失敗していたようです。
    - :pencil: 解決策として prepull を non-root ユーザ (ID: 999) で行うようにしたようです。
- **kubeadm: ファイルディスカバリを利用するときに"certificate-authority" ファイルがプレロードされない問題を修正しました。([#80966](https://github.com/kubernetes/kubernetes/pull/80966), [@neolit123](https://github.com/@neolit123))**
    - :pencil: `kubeadm join` 時に、ジョインするクラスタを discovery file を指定して指定することができるのですが、その discovery file 内で指定する CA のファイルが、base64 でエンコードされた CA ファイルではなく、ファイルパスで指定していた場合、ディスカバリ時に CA ファイルが無視されてしまうという問題が修正された、ということらしいです。
- **GCE Windows e2eテストをローカルで実行する際に、"Application Default Credentials"をセットアップする手順を追加しました。([#81337](https://github.com/kubernetes/kubernetes/pull/81337), [@YangLu1031](https://github.com/@YangLu1031))**
    - :pencil: kube-up.sh スクリプトを使った GCE/Windows でのローカル環境からのe2e テスト実行時の話らしいです。
- **認証情報を含んだ discovery file を利用した時に、 `kubeadm join --discovery-file` がエラーを発生させていた問題を修正しました。([#80675](https://github.com/kubernetes/kubernetes/pull/80675), [@fabriziopandini](https://github.com/@fabriziopandini))**
    - :pencil: 今までもdiscovery fileに認証情報を含めることはできましたが、その認証情報は join 中に cluster-info を取得するのに利用されるのみで、その後は anonymous ユーザにロールバックされてしまい、想定したワークフローを実行できなかった問題が修正されたようです。
- **kubeadm reset時における、クラスターからのetcdのメンバの削除に関わる問題が修正されました。([#79326](https://github.com/kubernetes/kubernetes/pull/79326), [@bradbeam](https://github.com/@bradbeam))**
    - :pencil: `kubeadm reset remove-etcd-member` がちゃんと動いていなかったようです。
- **kubeadm: 生成された CSR のパーミッションを 0644 から 0600 に変更しました。([#81217](https://github.com/kubernetes/kubernetes/pull/81217), [@SataQiu](https://github.com/@SataQiu))**
- **kubeadm: `upgrade-prepull-` DaemonSetを二重削除することを防ぐように変更しました。([#80798](https://github.com/kubernetes/kubernetes/pull/80798), [@xlgao-zju](https://github.com/@xlgao-zju))**
- **`kubeadm init phase certs` コマンド時の証明書の生成の順番が決定論的になりました。([#78556](https://github.com/kubernetes/kubernetes/pull/78556), [@neolit123](https://github.com/@neolit123))**
    - :pencil: Sub phase 生成時の順番が Map を使っていたため順不同であったのをソートされた順番に変更した、ということらしいです。
- **kubeadm: ノードにジョインする際の明白なConfigMapのエラーについてリトライを試みるようになりました。([#78915](https://github.com/kubernetes/kubernetes/pull/78915), [@ereslibre](https://github.com/@ereslibre))**
    - :pencil: `kubeadm-config` ConfigMaps を join 時にダウンロードする際に、失敗してもリトライするようになったようです。
    - :pencil: こういう分散システムの場合はいろんなところにリトライが入るんですなあ、という感想。
- **kubeadm: etcdのヘルスチェックのために、etcdctlの使用をやめ、/health エンドポイントを参照するようになりました。([#81385](https://github.com/kubernetes/kubernetes/pull/81385), [@neolit123](https://github.com/@neolit123))**
- **kubeadm reset: Linux の場合、`/var/lib/kubelet` をアンマウントするようになりました。([#81494](https://github.com/kubernetes/kubernetes/pull/81494), [@Klaven](https://github.com/@Klaven))**
    - :pencil: このリリースノートだけではわかりませんが、今までも `kubeadm reset` 時に`/var/lib/kubelet` のアンマウントは行われていました。
    - :pencil: 今回変わったのは、アンマウントの方法で、`/proc/mounts` をawk で走査して、umount コマンドを発行していた手順が、golang のネイティブな API コールでアンマウントするようになった、ということらしいです。
- **kubeadm: `--cri-socket` フラグが kubeadm reset 時に効いていいなかった問題が修正されました。([#79498](https://github.com/kubernetes/kubernetes/pull/79498), [@SataQiu](https://github.com/@SataQiu))**
- **コントロールプレーンノードにおいて cluster status リセット時にエラーハンドリングするようになりました。([#80573](https://github.com/kubernetes/kubernetes/pull/80573), [@bart0sh](https://github.com/@bart0sh))**
- **外部のetcdを利用する際に、ローカルのetcdのための証明書と同じフォルダの同じ名前で証明書を保存するとエラーが発生していた問題を修正しました。古いバージョンのkubeadmを利用している場合はファイル名の衝突を避ける必要があります。([#80867](https://github.com/kubernetes/kubernetes/pull/80867), [@fabriziopandini](https://github.com/@fabriziopandini))**
- **デフォルトタイムアウト5分で、ファイルベースのディスカバリを使用した `kubeadm join` が失敗するようになりました。([#80804](https://github.com/kubernetes/kubernetes/pull/80804), [@olivierlemasle](https://github.com/@olivierlemasle))**
    - :pencil: 今まではタイムアウトが指定されていなかったため、延々とコマンドが実行されてしまっていたようです。`--discovery-file` 関連のバグ多いなしかし。
- **kubeadm: コントロールプレーンのコンテナイメージをpullする際にエラーが無視されていた問題が修正されました。([#80529](https://github.com/kubernetes/kubernetes/pull/80529), [@bart0sh](https://github.com/@bart0sh))**
    - :pencil: なんか `err` を無視しているコードも多くてその修正PRも多いな。
- **kube-addon-managerのリーダーエレクションのロジックに問題があり、すべてのレプリカがアクティブになってしまっていた問題が修正されました。([#80575](https://github.com/kubernetes/kubernetes/pull/80575), [@mborsz](https://github.com/@mborsz))**
    - :pencil: kube-addon-managerのリーダーエレクションはkube-controller-managerのリーダーエレクションに相乗りしているのですが、kube-controller-managerのendpointを確認するために1.15で削除された insecure な kube-apiserverのエンドポイント(localhost:8080)に問い合わせを行なっていたようです。
    - :pencil: この問題は Kubernetes 1.15 にも影響があるため、1.15 で kube-addon-manager を利用している場合は最新の kube-addon-manager を利用したほうが良さそうです。
- **kubeadm: ユーザが変更したkubeletのセキュリティ設定を上書きしないようになりました。([#81903](https://github.com/kubernetes/kubernetes/pull/81903), [@jfbai](https://github.com/@jfbai))**
    - :pencil: kubeadm は kubelet のいくつかの設定をユーザ設定にかかわらずハードコードされた値に設定していましたが、この変更によりユーザ設定を上書きしないようになりました。
- **kubeadm は preflight チェックの一環として IPVS のチェックを行わないようになりました。([#81791](https://github.com/kubernetes/kubernetes/pull/81791), [@yastij](https://github.com/@yastij))**
- **kubeadm: IPv6アドレスのためのHTTPProxyチェックを修正しました。([#82267](https://github.com/kubernetes/kubernetes/pull/82267), [@kad](https://github.com/@kad))**
- **kubeadm: ユーザに kube-proxy init addonのフェーズをスキップさせてクラスターにジョインする前にいくつかのオペレーションを可能とするように修正しました。([#82248](https://github.com/kubernetes/kubernetes/pull/82248), [@rosti](https://github.com/@rosti))**
    - :pencil: kube-proxy はオプショナルなコンポーネントであるため、インストール時にスキップできるべきであるが、kubeadm はインストールをスキップしたにも関わらず、ノードのジョイン時にkube-proxyの設定をダウンロードしようとし、エラーのためジョインが失敗していたようです。
    - :pencil: この変更で、kube-proxy のインストールはオプショナルとなりました。
    - :pencil: [Cilium](https://cilium.io) を試そうとして気づいた仕様のバグ感がある。
- **ホストの `/home/kubernetes/bin/nvidia/vulkan/icd.d` をGPUをリクエストするコンテナ中の `/etc/vulkan/icd.d` にマウントするように変更しました。([#78868](https://github.com/kubernetes/kubernetes/pull/78868), [@chardch](https://github.com/@chardch))**
    - :pencil: [cluster/addon](https://github.com/kubernetes/kubernetes/tree/v1.16.1/cluster/addons/device-plugins/nvidia-gpu) 中の nvidia-gpu サポートの話らしい。
- **kubeadm: カンマで区切られた podCIDR のリストをkubeadmの設定中のpodSubnetに利用、もしくは初期化するために `--pod-network-cidr` フラグを使うようになりました。([#79033](https://github.com/kubernetes/kubernetes/pull/79033), [@Arvinderpal](https://github.com/@Arvinderpal))**
    - :pencil: IPv6DualStack 対応のためには podCIDR を二つ受け付ける必要があるため、`--pod-network-cidr` フラグがその対応をした、と言うことらしいです。
- **kubeadm: `controlPlaneEndpoint` のために、`--control-plane-endpoint` フラグを追加しました。([#79270](https://github.com/kubernetes/kubernetes/pull/79270), [@SataQiu](https://github.com/@SataQiu))**
    - :pencil: コントロールプレーンのエンドポイントの指定は、これまでは設定ファイルを作成しないければ指定できなかったようです。
- **kubeadm: kube-scheduler のTLSが有効化されました。([#80951](https://github.com/kubernetes/kubernetes/pull/80951), [@neolit123](https://github.com/@neolit123))**
- **kubeadm: ログレベルが5以上の場合、スタックトレースを出力するようになりました。([#80937](https://github.com/kubernetes/kubernetes/pull/80937), [@neolit123](https://github.com/@neolit123))**
- **`kubeadm init phase certs ca` と `kubeadm init phase kubeconfig` に `--kubernetes-version` フラグが追加されました。([#80115](https://github.com/kubernetes/kubernetes/pull/80115), [@gyuho](https://github.com/@gyuho))**
    - :pencil: [#80115](https://github.com/kubernetes/kubernetes/pull/80115) と関連して、内部バージョンにフォールバックするだけではなく、ユーザが Kubernetes のバージョンを指定できるようにした、と言う変更のようです。
- **kubeadm: `upgrade diff` のためにオリジナルのクラスターへ設定を問い合わせるようになりました。([#80025](https://github.com/kubernetes/kubernetes/pull/80025), [@SataQiu](https://github.com/@SataQiu))**
- **コンフォーマンステスト用のイメージを利用時に、`E2E_USE_GO_RUNNER` という新しい環境変数が導入されました。これは、テスト実行時に今までの bash のラッパーではなく、go言語ベースのランナーを利用するようにするためのものです。([#79284](https://github.com/kubernetes/kubernetes/pull/79284), [@johnSchnake](https://github.com/@johnSchnake))**
    - :pencil: 今まで、bash で書かれていた e2e テストのラッパーが go で書き直されているようです。
    - :pencil: ってか、コンフォーマンステスト用のイメージも SIG Cluster Lifecyle なんですなー。
- **kubeadm: kubeadm が生成した static pod のマニフェストに、kustomize の patch を当てる機能が追加されました。([#80905](https://github.com/kubernetes/kubernetes/pull/80905), [@fabriziopandini](https://github.com/@fabriziopandini))**
    - :pencil: このPRではコア部分が実装されたのみで、UX部分(フラグや設定ファイル)が実装されていないため、実際にはまだ利用することはできなさそうです。
    - :pencil: kubeadm 1.16.1 では以下のフラグが確認できました。
      <pre>$ ./kubeadm init -h | grep kus
  -k, --experimental-kustomize string        The path where kustomize patches for static pod manifests are stored.</pre>
- **GCE Ingress load balancer の 404 リクエストハンドラーが prometheus の以下のメトリクスを出力するようになりました。パーセンタイルのグルーピングも含まれています。デフォルトの 404 リクエストハンドラのためのディレクトリには、どのように Prometheus のモニタリングを有効化するかについての手順があります。**
    - **`http_404_request_total` (the number of 404 requests handled)**
    - **`http_404_request_duration_ms` (the amount of time the server took to respond in ms)**
    - :pencil: [GCE Load-Balancer Controller (GLBC) Cluster Addon](https://github.com/kubernetes/kubernetes/tree/v1.16.1/cluster/addons/cluster-loadbalancing/glbc) これかな？