Kubernetes のバージョンアップに伴う Kustomizeの差異(Kubernetes v1.21~v1.22)

## 始めに
Kubernetes のサポート期間は直近では1年ほどとなっておりますが、バージョンアップは数ヶ月おきに行われています。
定期的な更新が求められており、私たちも定期的な更新を実施していましたが、バージョンアップを行っていた際に1つ気になる点が発生しました。

kubectl のバージョン v1.21 から Kustomize のバージョンが v2.0.3 から一気に v4.0.5 へとアップデートが実施されていたのです。
kubectl のバージョンは kube-apiserver(Kubernetes) のバージョンの±1のバージョン差異までは許容されてはいます。
Kustomize は Kubernetes のマニフェストファイルを管理する部分のため Kubernetes 側への影響が発生するかもしれません。
メジャーバージョンが一気に2バージョン上がっていると破壊的な変更により動作が変わってしまう可能性もあるため調査しました。

kubectl で対応される Kustomize のバージョンのリストは下記となります。

|kubectl version | kustomize version |
|:-:|:-:|
|v1.14 - v1.20|v2.0.3|
|v1.21|v4.0.5|
|v1.22|v4.2.0|

## Kubernetes v1.21 での変更
#### Kustomize v2.1.0 での変更
**Go モジュール**
トップレベルの go.mod ファイルで依存関係を定義するように変更されたようです。
kubectl や kubebuilder、kustomize などで使用するためとなります。

**Resource ordering**
要望の多かったリソースの読み取り時の深さの優先順位を保持するように変更。
kustomize のファイルを変更することでリソースの順序を制御できるようになったので、ユーザー定義のプラグインを特定の順番で実行できるようになりました。
この機能自体は何もしなくても有効になるようです。
ビルドコマンドで、--reorder フラグに legacy と none の値を指定できるようになりました（デフォルト値は legacy）

**generator や transformer  の仕組みが導入**
v2.1.0 から プラグインの仕組みが導入され、generator や transformer が自作できるようになりました。
kustomize には kustomize build 時にリソース定義の生成を行う generator や、変換処理などを行う transformer が用意されています。
今回の追加によって、generator や transformer に処理を追加したい、振る舞いを変更したいっということがあった場合に変更することができるようになっています。

**Remove load restrictions**

```
kustomize build --load_restrictor none $target
```
上記のような指定をすると、kustomize build で使用される kustomization.yaml ファイルが、自分のディレクトリの外（つまりルートの外）のファイルを参照することを許可できるようです

**pruningのためのインベントリ作成**
kustomization ファイルに inventory stanza を追加して、ビルド結果に特別な inventory オブジェクトを追加することができるようになった。
クラスタに適用され、クラスタリソースをインテリジェントに削除するために使用できるよう。
詳しくは[こちら](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/inventory_object.md)

**フィールドの変更 / 非推奨事項**
**resources expanded, bases deprecated**
basesがdeprecatedになり、かわりにresourcesを使うように変更
この変更はユーザーがリソースの処理順番を細かく制御できるようにするために行われたようです。
別々のbaseフィールドを使っていた場合には別にロードする必要がありましたが、カレントディレクトリからのリソースファイルの読み込みと必要に応じて並行して行うことができるようになったよう
bases は将来のメジャーアップデートで削除される。
bases　の内容を resources に好きな順番で移動すれば対応は完了

**replicas field**
deployment.yaml　の中に記載していた replicas の値に関して、負荷が大きく発生しそう、それほどでもなかったからなどで Pod数を変更したい事があると思いますが kustomization.yaml　のなかで replicas を設定できるようになったよう

下記のように書くことで count で変更可能になった

```
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

replicas:
- name: deployment-name
  count: 5
```

**envs field**
configMapGenerator と secretGenerator にて、env でフィールドが envs フィールドへと名称が変更されました。
env フィールドが deprecated になったので、 envs に変更していく必要がある

#### Kustomize v3.0.0 での変更
基本的には、 v2.1.0 とは変わらないようです
v2.1.0 以降の多くのバグの修正と Go のパッケージパスを v3 に変更

**Why so soon after v2.1.0**
Goモジュールのドキュメントに準拠すると、 v2.1.0 こそが v3.0.0 に変更するべきであった。
v2.1.0とv2.0.3の間の非互換性に起因するものがあるため v3.0.0 にすることによって混乱を避ける目的があるようです。

#### Kustomize v3.1.0 での変更
**Extended patches**
このバージョンから、kustomize が1つのパッチを複数のリソースに適用できるようになった。
複数のリソースを適応する方法に関しては[こちら](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/patchMultipleObjects.md)

**Improved Resource Matching**
リソース分離のために、name suffix/prefix　と合わせて、 namespace も利用できるようになった

**Patch resolution improvement**
下記のような形で、Patch 定義にて、nameは同じ deploy1 だけれども namespace が違うことによって、2つの異なるPatch定義を行うことができる
もしもnamespaceを指定しない場合にはデフォルトのnamespaceになる

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy1
  namespace: main
spec:
  template:
    spec:
      containers:
      - name: nginx
        env:
        - name: ANOTHERENV
          value: TESTVALUE
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy1
  namespace: production
spec:
  template:
    spec:
      containers:
      - name: main
        env:
        - name: ANOTHERENV
          value: PRODVALUE
```

**Variable resolution improvement**
vars にも namespace を追加することができるようになった。
これによって同じ name であっても namespace を使用して検索を実施することができるようになった

**Simultaneous change of names and namespaces**
name と namespace の同時変更に対応できるようになった

**Other improvements**
- 画像の変換が改善
- 複数のデフォルトのトランスフォーマー設定エントリが追加
- kustomize のヘルプコマンドが整理

#### Kustomize v3.2.0 での変更
**Inline Patch**
patchesStrategicMerge、patchesJson6902、patchesの3つすべてでインラインパッチが可能になる

**New Subcommand**
下記のような形で、 create コマンドが追加され、こちらを実行することによって、kustomization.yamlファイルを作成できるようになった

```
kustomize create --resources ../base
```

**New Example Generator**
go-getterを使ってリソースをダウンロードするジェネレーターが追加された
詳細は[こちら](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/goGetterGeneratorPlugin.md)

#### Kustomize v3.2.1 での変更
3.2.0からの新機能は特になし
依存関係の変更がメイン

#### Kustomize v3.3.0 での変更
**First release of the Go API-only module**
こちらも特に新機能の追加はなし
sigs.k8s.io/kustomize リポジトリを 1 つの Go モジュールではなく 3 つの Go モジュールに再構築するように変更

#### Kustomize v3.4.0 での変更
kubernetes/kubernetes repo から kustomize が分離される
kustomize api v0.2.0を使用するようにバージョンアップ

#### Kustomize v3.5.2 での変更
v3.5.0 は名前づけ失敗で作成されていない。
v3.5.1は上記のために、v3.4.0と同等の内容で作成されている。

kustomize api v0.3.0を使用するように変更

新しいアルファ版の機能を表示するには、KUSTOMIZE_ENABLE_ALPHA_COMMANDSをtrueに設定する必要がある

```
KUSTOMIZE_ENABLE_ALPHA_COMMANDS=true ./kustomize help 
```

#### Kustomize v3.6.0 での変更
kubectl のバージョンが v0.1.0を使用するようになったよう
初期状態では相対パス置換ディレクティブが誤って残っているようなので、v3.6.1で修正されたものがアップロードされている
v3.6.0 ではなく、v3.6.1を使ってくださいとアナウンス

#### Kustomize v3.7.0 での変更
v3.6.1 以降に出たバグフィックスが実施
yamlライブラリの修正

kustomizeがkptと機能を共有することを可能にする初期の（アルファ）フレームワークが追加

#### Kustomize v3.8.0 での変更
新機能はなし
v3.7.0 からAPIも追加なしだけれども出力が少し変わっている
オブジェクト内のフィールドの順序が変わったり、空のフィールドの削除がうまく行われたりする
クラスタの動作やオブジェクト間の比較には影響しない
テキストベースのYAML比較テストが失敗する可能性がある

#### Kustomize v3.9.1 での変更
kubernetesのapimachineryモジュールの代わりに、kyamlモジュールを使ってYAMLを操作するように変更
今後はkyamlを使用していくとのこと

#### Kustomize v3.10.0 での変更
kustomize api v0.8.0を使用するように変更
--enable_kyaml フラグがデフォルトでtrueになっており、これはv4.0.0では削除されるので上記の変更に合わせて今後の進み方での変更

#### Kustomize v4.0.0 での変更
kustomize build で受け付けるURLセットが減る
ファイルシステムのパスや git clone と互換性のある値のみに変更
上記は、resources フィールドの要素についても同様なので、リソースフィールドの特別なURLに依存しているユーザーはチェックする必要がある

上記が破壊的変更なので、メジャーバージョンが上がっている

## Kubernetes v1.22 での変更
#### Kustomize v4.1.0 での変更
**Patch kind and metadata/name**
Patch でリソースの種類や名前を変更できるようになった
Deployment -> StatefulSet へなどの変更が行えるようになる。

**labels without selectors**
ラベルフィールドにて対応するセレクタを自動的追加できるようになった

```
labels:
  pairs
    fruit: peach
    car: model-T
  includeSelectors: true # <-- false by default
```

**Updated helm generator**
kustomization.yaml ファイルに新しい2つのフィールドが追加

```
helmGlobals *HelmGlobals  // helm config that's not chart specific.
helmCharts []HelmChart    // Chart instances.
```

上記は非推奨になった helmChartInflationGenerator フィールドの代わりになるものとなるようです。

***Use a custom OpenAPI schema file***
Kustomize はマージキーに関する情報を得るために OpenAPI データを使用するように追加
openapiフィールドで使用するファイルを指定する必要がある

#### Kustomize v4.2.0 での変更
vars を 自動的にreplacementに移行させる実験的なコマンドを追加
vars を replacements に変換してしまうと多くのリソースファイルが上書きされる可能性があり、kustomize build　を実行したときの結果が変わってしまう場合があるので注意が必要

## 最後に
直近の Kustomize 変更内容はGithubのreleaseに書かれているようでしたので、最初はどこに記載されているのか探し回ってしまいました。
Kustomize 自体はリリースごとの変更は小さく、また破壊的な変更もメジャーバージョンが上がらない場合には行わないようになっているため、ある程度安心して使っていけるのではないかと思いました。

## 参考リンク
[kustomize v2.1.0](https://kubernetes-sigs.github.io/kustomize/blog/2019/06/18/v2.1.0/)
[kustomize の generator / transformer の振る舞いを変えてみる](https://www.techscore.com/blog/2019/08/01/change-kustomize-build-behavior/)
[kustomize 2.1.0の変更点](https://shepherdmaster.hateblo.jp/entry/2019/12/13/124908)
[kustomize v3.0.0](https://kubernetes-sigs.github.io/kustomize/blog/2019/07/03/v3.0.0/)
[kustomize v3.1.0](https://kubernetes-sigs.github.io/kustomize/blog/2019/07/26/v3.1.0/)
[kustomize v3.2.0](https://kubernetes-sigs.github.io/kustomize/blog/2019/09/17/v3.2.0/)
[kustomize v3.2.1](https://kubernetes-sigs.github.io/kustomize/blog/2019/09/26/v3.2.1/)
[kustomize v3.3.0](https://kubernetes-sigs.github.io/kustomize/blog/2019/10/24/v3.3.0/)
[kustomize v3.4.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.4.0)
[kustomize v3.5.2](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.5.2)
[kustomize v3.6.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.6.0)
[kustomize v3.7.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.7.0)
[kustomize v3.8.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.8.0)
[kustomize v3.9.1](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.9.1)
[kustomize v3.10.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.10.0)
[kustomize v4.0.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.0.0)
[kustomize v4.1.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.1.0)
[kustomize v4.2.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.2.0)