Patch K8s Objects in Place

For updating components secret or configmap, you can do complete replace:

1
2
3
4
5
6
kubectl get secret docker-registry-auth -o yaml -n default \
| sed -e "/htpasswd/c\ htpasswd: ${AUTH_BASE64}" \
| kubectl replace -f -
kubectl get configmap repl-pod-map -n $NAMESPACE -o yaml
| sed -e "/${POD_NAME}/d"
| kubectl replace -f-

For patching pod controller like deployment and statefulset, see: https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/

Strategic merge patch

For example, add one more containers in the pod, give the yaml file patch-file.yaml:

1
2
3
4
5
6
spec:
template:
spec:
containers:
- name: patch-demo-ctr-2
image: redis
1
2
# this command use default patch strategy for containers field: merge
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"

This will get merged not replaced (the original container is kept), but not all fields have merge strategy, some use default strategy that is replace, for example: tolerations field.

How to know the patch strategy of each field? see API document It seems not all fields have specified patch strategy, for example, I don’t see that on configmap.

Json merge patch

A strategic merge patch is different from a JSON merge patch. With a JSON merge patch, if you want to update a list, you have to specify the entire new list. And the new list completely replaces the existing list.

The kubectl patch command has a --type parameter that you can set to one of these values:

  1. json (json patch)
  2. merge (json merge patch)
  3. strategic (default)

这里文档有问题,如果用json merge patch on configmap,其实还是做的merge操作(之前的数据被保留),并不是replace.这个值得注意,比如以下2个commands效果是一样的:

1
2
3
4
## json merge patch
kubectl patch configmap repl-pod-map -n pines --type merge -p "{\"data\": {\"test1\":\"test1key\"}}"
## defaul strategic patch
kubectl patch configmap repl-pod-map -n pines -p "{\"data\": {\"test1\":\"test1key\"}}"

我猜可能是configmap没有明确的patch strategy定义,但对于其他有明确定义的field,则json merge patch会replace之前的数据。

0%