【Kubernetes】Strategic 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/strategic-merge-patch.md at master · kubernetes/community
Kubernetescommunitycontent.Contributetokubernetes/communitydevelopmentbycreatinganaccountonGitHub.

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

patchesStrategicMerge
Patchresourcesusingthestrategicmergepatchstandard.

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
Author:DanielSmith(Google)Server-sideapply(SSA)hasnowbeenGAforafewreleases,andIhavefoundmyselfinanumberofconversations,recommendingthatpeople/teamsinvarioussitu...

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
tree:.├──base│├──kafka.yaml│└──kustomization.yaml└──overlays├──kustomization.yaml├──output.yaml└──patch.yamlbasecontent:#kustomization.yamlresources:-kafka.yaml...
kustomize/smpdirective.go at master · kubernetes-sigs/kustomize
CustomizationofkubernetesYAMLconfigurations.Contributetokubernetes-sigs/kustomizedevelopmentbycreatinganaccountonGitHub.

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

replace

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

$patch: replace

試してみる

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

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

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

resources:
- deployment.yaml

patchesStrategicMerge:
- replace.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        ver: 1.0.0
    spec:
      containers:
      - name: nginx
        image: nginx:latest
      - name: redis
        image: redis:latest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    metadata:
      $patch: replace # 下の階層が置換対象
      labels:
        app: myapp
        ver: 2.0.0
    spec:
      containers:
      - name: busybox
        image: busybox:latest
      - $patch: replace # リストが置換対象

ビルドしてみます。

kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels: # labelsの中の要素が置換
        app: myapp
        ver: 2.0.0
    spec:
      containers:
      - image: busybox:latest # リストが置換
        name: busybox

delete

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

$patch: delete

試してみる

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

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

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

resources:
- deployment.yaml

patchesStrategicMerge:
- delete.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  strategy:
    type: Recreat
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: nginx
        image: nginx:latest
      - name: redis
        image: redis:latest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  strategy:
    $patch: delete # strategyを削除
  template:
    spec:
      containers:
      - name: busybox
        image: busybox:latest
      - $patch: delete # nginxコンテナを削除
        name: nginx

ビルドしてみます。

kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  # strategyが削除されている
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      # nginxコンテナが削除され、busyboxコンテナがマージ
      - image: busybox:latest
        name: busybox
      - image: redis:latest
        name: redis

最後に

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

参考

タイトルとURLをコピーしました