PUT操作 /<资源名复数形式>/<名字> 通过给出的资源名和客户端提供的json对象来更新或创建资源
PATCH操作 /<资源名复数形式>/<名字> 选择修改资源详细指定的域
PATCH API对象的三种方式
JSON Patch,Content-Type: application/json-patch+json
在RFC6902定义中,JSON Patch是执行在资源对象上的一系列操作,进行局部更新。例如:
{"op":"add", "path": "/a/b/c", "value": ["foo", "bar"]}
Merge Patch,Content-Type: application/merge-json-patch+json。
Merge Patch必须包含一个对资源对象的部分描述,json对象。该json对象被提交到服务端,并和服务端的当前对象进行合并,从而创建新的对象。完整的替换列表,也就是说,新的列表定义会替换原有的定义。
JSON strategic merge patch,这种补丁是以增量的形式来对已有的定义进行修改,可以理解为类似于linux diff
创建的补丁。
PATCH 示例
// 示例1
{
"a":{
"b":{
"c":"foo"
}
}
}
// JSON Patch 操作
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", www.tianhengyl1.com/ "value": [ "foo", "bar" ] },
{ "op": "replace", "path":www.ysgj1688.com "/a/b/c", "value": 42 },
{ "op": "move", "from": www.baohuayule.net "www.089188.cn /a/b/c"www.taohuayuan178.com , "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d",www.qinlinyule.cn "path": "/a/b/e" }
]
// 示例2
{
"users" : [
{ "name" : "Alice" , "email" : "[email protected]" },
{ "name" : "Bob" , "email" : "[email protected]" }
]
}
patch操作
[
{
"op" : "replace" ,
"path" : "/users/0/email" ,
"value" : "[email protected]"
},
{
"op" : "add" ,
"path" : "/users/-" ,
"value" : {
"name" : "Christine",
"email" : "[email protected]"
}
}
]
结果
{
"users" : [
{ "name" : "Alice" , "email" : "[email protected]" },
{ "name" : "Bob" , "email" : "[email protected]" },
{ "name" : "Christine" , "email" : "[email protected]" }
]
}
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: patch-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: patch-demo-ctr
image: nginx
tolerations:
- effect: NoSchedule
key: dedicated
value: test-team
创建deployment
kubectl apply -f deployment-patch.yaml
每个pod运行一个容器。现在patch操作使pod 运行两个容器: nginx和redis
patch-file-containers.yaml
文件内容:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-2
image: redis
kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"
kubectl get deployment patch-demo -o yaml
containers:
- image: redis
imagePullPolicy: Always
name: patch-demo-ctr-2
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- image: nginx
imagePullPolicy: Always
name: patch-demo-ctr
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
上述操作 patch
称为 a strategic merge patch
。patch操作没有替换 containers
列表,相反在列表中添加新的容器。merge
进patch操作进入存在的列表中。 可能在某些情况下会进行替换,而不是merge列表操作。a strategic merge patch
列表要么被替换要么被merge取决于patch
策略。源码中通过 patchStrategy
键值指定。如下示:
type PodSpec struct {
...
Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`
Tolerations []Toleration `json:"tolerations,omitempty" opt,name=tolerations"`
上述可以看出Tolerations
列表就会被替换,而不是merge操作
。原因是没有patchStrategy
键值,所有the strategic merge patch 使用默认的replace patch策略。
示例省略,详细的toleration patch可参考官网示例。
A strategic merge patch 与 JSON merge patch有所不同。a JSON merge patch,如果你想去更新列表必须指定完整的新列表,新列表将进行完全替换。
kubectl patch xxxx --type xxxx --patch xxxx
默认的type
参数是strategic
。
创建文件patch-file-2.yaml
spec:
template:
spec:
containers:
- name: patch-demo-ctr-3
image: gcr.io/google-samples/node-hello:1.0 // redis
kubectl patch deployment patch-demo --type merge --patch "$(cat patch-file-2.yaml)"
注:镜像拉取可能会产生问题,换个redis镜像。
kubectl get deployment patch-demo --output yaml
spec:
containers:
- image: redis
imagePullPolicy: Always
name: patch-demo-ctr-3
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
json格式的更新 patch-file.json
{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "patch-demo-ctr-2",
"image": "redis"
}
]
}
}
}
}
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
kubectl patch deployment patch-demo --patch 'spec:\n template:\n spec:\n containers:\n - name: patch-demo-ctr-2\n image: redis'
kubectl patch deployment patch-demo --patch "$(cat patch-file.json)"
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'
kubectl patch
用于更改Deployment对象的实时配置,并没有更改最初用于创建Deployment对象的配置文件。用于更新API对象的其他命令包括 kubectl annotate, kubectl edit, kubectl replace, kubectl scale和kubectl apply。
本文主要是介绍patch操作及put操作区别,kubernetes几种patch操作,以及后续我们在接口中如何使用patch操作实时更新对象。
JSON Patch: https://blog.csdn.net/li123128/article/details/80321815
PATCH和PUT方法的区别?: https://blog.csdn.net/varyall/article/details/80895945
JSON Patch and JSON Merge Patch: http://erosb.github.io/post/json-patch-vs-merge-patch/
Update API Objects in Place Using kubectl patch: https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/