From a478fa661098e19d5f97038cfd992ac42849e2d8 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Sun, 31 May 2020 09:20:06 +0200 Subject: [PATCH 1/2] Document retainKeys patch strategy --- .../update-api-object-kubectl-patch.md | 113 ++++++++++++++++++ .../application/deployment-retainkeys.yaml | 19 +++ 2 files changed, 132 insertions(+) create mode 100644 content/en/examples/application/deployment-retainkeys.yaml diff --git a/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md b/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md index 60d6ae8099..3c7ae83ea5 100644 --- a/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md +++ b/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md @@ -284,6 +284,119 @@ patch-demo-1307768864-69308 1/1 Running 0 1m patch-demo-1307768864-c86dc 1/1 Running 0 1m ``` +## Use strategic merge patch to update a Deployment using the retainKeys strategy + +Here's the configuration file for a Deployment that uses the `RollingUpdate` strategy: + +{{< codenew file="application/deployment-retainkeys.yaml" >}} + +Create the deployment: + +```shell +kubectl apply -f https://k8s.io/examples/application/deployment-retainkeys.yaml +``` + +At this point, the deployment is created and is using the `RollingUpdate` strategy. + +Create a file named `patch-file-no-retainkeys.yaml` that has this content: + +```yaml +spec: + strategy: + type: Recreate +``` + +Patch your Deployment: + +{{< tabs name="kubectl_patch_example" >}} +{{{< tab name="Bash" codelang="bash" >}} +kubectl patch deployment retainkeys-demo --patch "$(cat patch-file-no-retainkeys.yaml)" +{{< /tab >}} +{{< tab name="PowerShell" codelang="posh" >}} +kubectl patch deployment retainkeys-demo --patch $(Get-Content patch-file-no-retainkeys.yaml -Raw) +{{< /tab >}}} +{{< /tabs >}} + +In the output, you can see that it is not possible to set `type` as `Recreate` when a value is defined for `spec.strategy.rollingUpdate`: + +```shell +The Deployment "retainkeys-demo" is invalid: spec.strategy.rollingUpdate: Forbidden: may not be specified when strategy `type` is 'Recreate' +``` + +The way to remove the value for `spec.strategy.rollingUpdate` when updating the value for `type` is to use the `retainKeys` strategy for the strategic merge. + +Create another file named `patch-file-retainkeys.yaml` that has this content: + +```yaml +spec: + strategy: + $retainKeys: + - type + type: Recreate +``` + +With this patch, we indicate that we want to retain only the `type` key of the `strategy` object. Thus, the `rollingUpdate` will be removed during the patch operation. + +Patch your Deployment again with this new patch: + +{{< tabs name="kubectl_patch_example" >}} +{{{< tab name="Bash" codelang="bash" >}} +kubectl patch deployment retainkeys-demo --patch "$(cat patch-file-retainkeys.yaml)" +{{< /tab >}} +{{< tab name="PowerShell" codelang="posh" >}} +kubectl patch deployment retainkeys-demo --patch $(Get-Content patch-file-retainkeys.yaml -Raw) +{{< /tab >}}} +{{< /tabs >}} + +Examine the content of the Deployment: + +```shell +kubectl get deployment retainkeys-demo --output yaml +``` + +The output shows that the strategy object in the Deployment does not contain the `rollingUpdate` key anymore: + +```shell +spec: + strategy: + type: Recreate + template: +``` + +### Notes on the strategic merge patch using the retainKeys strategy + +The patch you did in the preceding exercise is called a *strategic merge patch with retainKeys strategy*. This method introduces a new directive `$retainKeys` that has the following strategies: + +- It contains a list of strings. +- All fields needing to be preserved must be present in the `$retainKeys` list. +- The fields that are present will be merged with live object. +- All of the missing fields will be cleared when patching. +- All fields in the `$retainKeys` list must be a superset or the same as the fields present in the patch. + +The `retainKeys` strategy does not work for all objects. It only works when the value of the `patchStrategy` key in a field tag in the Kubernetes source code contains `retainKeys`. For example, the `Strategy` field of the `DeploymentSpec` struct has a `patchStrategy` of `retainKeys`: + +```go +type DeploymentSpec struct { + ... + // +patchStrategy=retainKeys + Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" ...` +``` + +You can also see the `retainKeys` strategy in the [OpenApi spec](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json): + +```json +"io.k8s.api.apps.v1.DeploymentSpec": { + ... + "strategy": { + "$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStrategy", + "description": "The deployment strategy to use to replace existing pods with new ones.", + "x-kubernetes-patch-strategy": "retainKeys" + }, +``` + +And you can see the `retainKeys` strategy in the +[Kubernetes API documentation](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deploymentspec-v1-apps). + ## Alternate forms of the kubectl patch command The `kubectl patch` command takes YAML or JSON. It can take the patch as a file or diff --git a/content/en/examples/application/deployment-retainkeys.yaml b/content/en/examples/application/deployment-retainkeys.yaml new file mode 100644 index 0000000000..b5e04f0cc1 --- /dev/null +++ b/content/en/examples/application/deployment-retainkeys.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 +kind: Deployment +metadata: + name: retainkeys-demo +spec: + selector: + matchLabels: + app: nginx + strategy: + rollingUpdate: + maxSurge: 30% + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: retainkeys-demo-ctr + image: nginx From f7a39682ca2b0ae2972ac64b0ea03b71481d0d30 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Thu, 11 Jun 2020 14:41:03 +0200 Subject: [PATCH 2/2] Fix tabs --- .../update-api-object-kubectl-patch.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md b/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md index 3c7ae83ea5..55d9128f20 100644 --- a/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md +++ b/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md @@ -308,7 +308,7 @@ spec: Patch your Deployment: -{{< tabs name="kubectl_patch_example" >}} +{{< tabs name="kubectl_retainkeys_example" >}} {{{< tab name="Bash" codelang="bash" >}} kubectl patch deployment retainkeys-demo --patch "$(cat patch-file-no-retainkeys.yaml)" {{< /tab >}} @@ -339,7 +339,7 @@ With this patch, we indicate that we want to retain only the `type` key of the ` Patch your Deployment again with this new patch: -{{< tabs name="kubectl_patch_example" >}} +{{< tabs name="kubectl_retainkeys2_example" >}} {{{< tab name="Bash" codelang="bash" >}} kubectl patch deployment retainkeys-demo --patch "$(cat patch-file-retainkeys.yaml)" {{< /tab >}}