jsonpatch 详见: https://github.com/chinaran/jsonpatch

K8s Patch

在开发 controller/operator 时,经常会对 CR 资源进行更新操作,

可使用 update/apply 进行更新,但有可能会导致冲突 (Conflict)。

如果只是小范围更新,推荐使用 patch 操作。

kubectl patch 可参考官方示例: https://kubernetes.io/docs/reference/kubectl/cheatsheet/#patching-resources

所以基于 https://github.com/mattbaird/jsonpatch,封装了一个更易用的 jsonpatch 库,目前够用。

引用

1
go get -u github.com/chinaran/jsonpatch

示例

controller client 可用 client.RawPatch(types.JSONPatchType, patchData)

dynamic client, client set 等参考如下示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import (
	"context"

	"github.com/chinaran/jsonpatch"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/dynamic"
)

func JSONPatchResource(dyclient dynamic.NamespaceableResourceInterface) (*unstructured.Unstructured, error) {
	patchValues := []*jsonpatch.Operation{
		// patch annotations
		jsonpatch.NewAnnotationOperation(jsonpatch.OpReplace, "key-1", "value-1"),
		// patch labels
		jsonpatch.NewLabelOperation(jsonpatch.OpReplace, "key-2", "value-2"),
		// add patch
		jsonpatch.NewAddOperation("/spec/arrayx/0", "value-3"),
		// replace patch
		jsonpatch.NewReplaceOperation("/spec/arrayx", []string{"value-3", "value-4"}),
		/// remove patch
		jsonpatch.NewRemoveOperation("/spec/arrayx/0"),
	}

	patchBytes, err := jsonpatch.NewOperationData(patchValues...)
	if err != nil {
		return nil, err
	}
	return dyclient.Namespace("test-ns").Patch(context.TODO(), "test-name", types.JSONPatchType, patchBytes, metav1.PatchOptions{})
}