From c46425d76c151e70cdbcddb3fe023f2917ffae98 Mon Sep 17 00:00:00 2001 From: Steve Perry Date: Mon, 12 Feb 2018 18:14:50 -0800 Subject: [PATCH] Add info about patch strategy. (#7286) --- .../deployment-patch-demo.yaml | 4 + .../update-api-object-kubectl-patch.md | 95 ++++++++++++++++--- 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/docs/tasks/run-application/deployment-patch-demo.yaml b/docs/tasks/run-application/deployment-patch-demo.yaml index fc2bec3495..7b32e2fcae 100644 --- a/docs/tasks/run-application/deployment-patch-demo.yaml +++ b/docs/tasks/run-application/deployment-patch-demo.yaml @@ -15,3 +15,7 @@ spec: containers: - name: patch-demo-ctr image: nginx + tolerations: + - effect: NoSchedule + key: dedicated + value: test-team diff --git a/docs/tasks/run-application/update-api-object-kubectl-patch.md b/docs/tasks/run-application/update-api-object-kubectl-patch.md index ddb528880c..9750a702a5 100644 --- a/docs/tasks/run-application/update-api-object-kubectl-patch.md +++ b/docs/tasks/run-application/update-api-object-kubectl-patch.md @@ -54,9 +54,9 @@ get terminated and replaced by new ones. At this point, each Pod has one Container that runs the nginx image. Now suppose you want each Pod to have two containers: one that runs nginx and one that runs redis. -Create a file named `patch-file.yaml` that has this content: +Create a file named `patch-file-containers.yaml` that has this content: -```shell +```yaml spec: template: spec: @@ -68,7 +68,7 @@ spec: Patch your Deployment: ```shell -kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)" +kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)" ``` View the patched Deployment: @@ -126,15 +126,82 @@ containers: ### Notes on the strategic merge patch -With a patch, you do not have to specify an entire object; you specify only the portion -of the object that you want to change. For example, in the preceding exercise, you specified -one Container in the `containers` list in a `PodSpec`. - The patch you did in the preceding exercise is called a *strategic merge patch*. -With a strategic merge patch, you can update a list by specifying only the elements -that you want to add to the list. The existing list elements remain, and the new elements -are merged with the existing elements. In the preceding exercise, the resulting `containers` -list has both the original nginx Container and the new redis Container. +Notice that the patch did not replace the `containers` list. Instead it added a new +Container to the list. In other words, the list in the patch was merged with the +existing list. This is not always what happens when you use a strategic merge patch on a list. +In some cases, the list is replaced, not merged. + +With a strategic merge patch, a list is either replaced or merged depending on its +patch strategy. The patch strategy is specified by the value of the `patchStrategy` key +in a field tag in the Kubernetes source code. For example, the `Containers` field of `PodSpec` +struct has a `patchStrategy` of `merge`: + +```go +type PodSpec struct { + ... + Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...` +``` + +You can also see the patch strategy in the +[OpenApi spec](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json): + +```json +"io.k8s.api.core.v1.PodSpec": { + ... + "containers": { + "description": "List of containers belonging to the pod. ... + }, + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, +``` + +And you can see the patch strategy in the +[Kubernetes API documentation](/docs/reference/generated/kubernetes-api/v1.9/#podspec-v1-core). + +Create a file named `patch-file-tolerations.yaml` that has this content: + +```yaml +spec: + template: + spec: + tolerations: + - effect: NoSchedule + key: disktype + value: ssd +``` + +Patch your Deployment: + +```shell +kubectl patch deployment patch-demo --patch "$(cat patch-file-tolerations.yaml)" +``` + +View the patched Deployment: + +```shell +kubectl get deployment patch-demo --output yaml +``` + +The output shows that the PodSpec in the Deployment has only one Toleration: + +```shell +tolerations: + - effect: NoSchedule + key: disktype + value: ssd +``` + +Notice that the `tolerations` list in the PodSpec was replaced, not merged. This is because +the Tolerations field of PodSpec does not have a `patchStrategy` key in its field tag. So the +strategic merge patch uses the default patch strategy, which is `replace`. + +```go +type PodSpec struct { + ... + Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"` +``` ## Use a JSON merge patch to update a Deployment @@ -162,7 +229,7 @@ did a strategic merge patch. Next, do a JSON merge patch on your same Deployment. Create a file named `patch-file-2.yaml` that has this content: -```shell +```yaml spec: template: spec: @@ -216,7 +283,7 @@ directly on the command line. Create a file named `patch-file.json` that has this content: -```shell +```json { "spec": { "template": { @@ -246,7 +313,7 @@ kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"co ## Summary -In this exercise, you `kubectl patch` to change the live configuration +In this exercise, you used `kubectl patch` to change the live configuration of a Deployment object. You did not change the configuration file that you originally used to create the Deployment object. Other commands for updating API objects include [kubectl annotate](/docs/user-guide/kubectl/{{page.version}}/#annotate),