【Kubernetes】Strategic Merge Patchについてざっくり理解する

2023.01.28
2024.03.24
Kubernetes
kubectlkustomizeStrategic Merge Patch

はじめに

Kubernetesで使われるStrategic Merge Patchについて、ざっくり理解していきます。

また、Strategic Merge Patchで使われる命令文の中からKustomizeでサポートされているものを紹介します。

Strategic Merge Patchとは

Strategic Merge PatchはKubernetesで使われているJSON merege patchをカスタマイズしたパッチ方法です。

JSON Merge Patchの場合、JSON Objectは全てマージされ、リストは全て置換されるようになっています。しかし、Kubernetesだと都合が悪い場合があるので、Strategic Merge Patchでは、Kubernetesのオブジェクトがいい感じにマージされるように制御されています。

このパッチ方法は、kubectl applykubectl editkubectl patchで使われており、専用の命令文(directive)があり、どのようにマージするかを制御することもできます。

community/contributors/devel/sig-api-machinery/strategic-merge-patch.md at master · kubernetes/community

community/contributors/devel/sig-api-machinery/strategic-merge-patch.md at master · kubernetes/community

Kubernetes community content. Contribute to kubernetes/community development by creating an account on GitHub.

また、このパッチ方法はKustomizeでもサポートされており、一部の命令文(パッチフォーマット)はKustomizeのパッチファイルの中でも利用することができます。

patchesStrategicMerge

Patch resources using the strategic merge patch standard.

Server Side Apply

先ほど載せたページに記載されているように、Strategic Merge Patchを使うClient-side Applyに代わって、現在ではServer-side Applyが新しい方法として推奨されています。

また、下記の記事では、"Old patch format"とStrategic Merge Patchが呼ばれており、いくつかバグもあるみたいです。

Server Side Apply Is Great And You Should Be Using It

Server-side apply (SSA) has now been GA for a few releases, and I have found myself in a number of conversations, recommending that people / teams in various situations use it. So I’d like to write down some of those reasons. Obvious (and not-so-obvious) benefits of SSA A list of improvements / niceties you get from switching from various things to Server-side apply! Versus client-side-apply (that is, plain kubectl apply): The system gives you conflicts when you accidentally fight with another actor over the value of a field!

Kustomizeが対応しているパッチフォーマット

Server-side Applyが新しい方法として推奨されているので、Kustomizeでサポートされているパッチフォーマットを紹介します。

Kustomizeがサポートしているフォーマットは下記の通りです。

  • replace
  • delete
  • merge

具体的にKustomizeがサポートしているフォーマットが書かれているドキュメントは見つかりませんでしたが、下記のIssueとコードを見た感じだと、replacedeletemergeだと思います。

kyaml is not respecting `$patch replace|retainKeys` directives · Issue #2037 · kubernetes-sigs/kustomize

kyaml is not respecting `$patch replace|retainKeys` directives · Issue #2037 · kubernetes-sigs/kustomize

tree: . ├── base │ ├── kafka.yaml │ └── kustomization.yaml └── overlays ├── kustomization.yaml ├── output.yaml └── patch.yaml base content: # kustomization.yaml resources: - kafka.yaml # kafka.yaml...

kustomize/kyaml/yaml/merge2/smpdirective.go at master · kubernetes-sigs/kustomize

kustomize/kyaml/yaml/merge2/smpdirective.go at master · kubernetes-sigs/kustomize

Customization of kubernetes YAML configurations. Contribute to kubernetes-sigs/kustomize development by creating an account on GitHub.

しかし、merge Directiveに書かれているとおり、mergeに関してはパッチファイルで使われるフォーマットではなさそうです。(実際に試してみましたが、挙動が変わるパターンが見つからなかったので、今回は紹介しないことにします)

replace

replaceは、その名の通り要素をマージする代わりに置き換えます。

1$patch: replace

試してみる

Kustomizeを使って試してみます。

用意するファイル(kustomization.yaml, deployment.yaml, replace.yaml)は下記の通りです。

1apiVersion: kustomize.config.k8s.io/v1beta1
2kind: Kustomization
3
4resources:
5- deployment.yaml
6
7patchesStrategicMerge:
8- replace.yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: myapp
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: myapp
10  template:
11    metadata:
12      labels:
13        app: myapp
14        ver: 1.0.0
15    spec:
16      containers:
17      - name: nginx
18        image: nginx:latest
19      - name: redis
20        image: redis:latest
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: myapp
5spec:
6  template:
7    metadata:
8      $patch: replace # 下の階層が置換対象
9      labels:
10        app: myapp
11        ver: 2.0.0
12    spec:
13      containers:
14      - name: busybox
15        image: busybox:latest
16      - $patch: replace # リストが置換対象

ビルドしてみます。

1kustomize build
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: myapp
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: myapp
10  template:
11    metadata:
12      labels: # labelsの中の要素が置換
13        app: myapp
14        ver: 2.0.0
15    spec:
16      containers:
17      - image: busybox:latest # リストが置換
18        name: busybox

delete

deleteは要素の削除をします。

1$patch: delete

試してみる

Kustomizeを使って試してみます。

用意するファイル(kustomization.yaml, deployment.yaml, delete.yaml)は下記の通りです。

1apiVersion: kustomize.config.k8s.io/v1beta1
2kind: Kustomization
3
4resources:
5- deployment.yaml
6
7patchesStrategicMerge:
8- delete.yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: myapp
5spec:
6  strategy:
7    type: Recreat
8  replicas: 1
9  selector:
10    matchLabels:
11      app: myapp
12  template:
13    metadata:
14      labels:
15        app: myapp
16    spec:
17      containers:
18      - name: nginx
19        image: nginx:latest
20      - name: redis
21        image: redis:latest
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: myapp
5spec:
6  strategy:
7    $patch: delete # strategyを削除
8  template:
9    spec:
10      containers:
11      - name: busybox
12        image: busybox:latest
13      - $patch: delete # nginxコンテナを削除
14        name: nginx

ビルドしてみます。

1kustomize build
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: myapp
5spec:
6  # strategyが削除されている
7  replicas: 1
8  selector:
9    matchLabels:
10      app: myapp
11  template:
12    metadata:
13      labels:
14        app: myapp
15    spec:
16      containers:
17      # nginxコンテナが削除され、busyboxコンテナがマージ
18      - image: busybox:latest
19        name: busybox
20      - image: redis:latest
21        name: redis

最後に

Strategic Merge Patchに関しては、ドキュメントがあまり見当たらなかったため、もし謝っている箇所があれば教えていただけるとうれしいです。

参考

Support

\ この記事が役に立ったと思ったら、サポートお願いします! /

buy me a coffee
Share

Profile

author

Masa

都内のIT企業で働くエンジニア
自分が学んだことをブログでわかりやすく発信していきながらスキルアップを目指していきます!

buy me a coffee