Skip to content

Commit 2048d69

Browse files
authored
Merge pull request #21372 from feloy/retainkeys
Document retainKeys patch strategy
2 parents 18b08ea + f7a3968 commit 2048d69

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,119 @@ patch-demo-1307768864-69308 1/1 Running 0 1m
284284
patch-demo-1307768864-c86dc 1/1 Running 0 1m
285285
```
286286

287+
## Use strategic merge patch to update a Deployment using the retainKeys strategy
288+
289+
Here's the configuration file for a Deployment that uses the `RollingUpdate` strategy:
290+
291+
{{< codenew file="application/deployment-retainkeys.yaml" >}}
292+
293+
Create the deployment:
294+
295+
```shell
296+
kubectl apply -f https://k8s.io/examples/application/deployment-retainkeys.yaml
297+
```
298+
299+
At this point, the deployment is created and is using the `RollingUpdate` strategy.
300+
301+
Create a file named `patch-file-no-retainkeys.yaml` that has this content:
302+
303+
```yaml
304+
spec:
305+
strategy:
306+
type: Recreate
307+
```
308+
309+
Patch your Deployment:
310+
311+
{{< tabs name="kubectl_retainkeys_example" >}}
312+
{{{< tab name="Bash" codelang="bash" >}}
313+
kubectl patch deployment retainkeys-demo --patch "$(cat patch-file-no-retainkeys.yaml)"
314+
{{< /tab >}}
315+
{{< tab name="PowerShell" codelang="posh" >}}
316+
kubectl patch deployment retainkeys-demo --patch $(Get-Content patch-file-no-retainkeys.yaml -Raw)
317+
{{< /tab >}}}
318+
{{< /tabs >}}
319+
320+
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`:
321+
322+
```shell
323+
The Deployment "retainkeys-demo" is invalid: spec.strategy.rollingUpdate: Forbidden: may not be specified when strategy `type` is 'Recreate'
324+
```
325+
326+
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.
327+
328+
Create another file named `patch-file-retainkeys.yaml` that has this content:
329+
330+
```yaml
331+
spec:
332+
strategy:
333+
$retainKeys:
334+
- type
335+
type: Recreate
336+
```
337+
338+
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.
339+
340+
Patch your Deployment again with this new patch:
341+
342+
{{< tabs name="kubectl_retainkeys2_example" >}}
343+
{{{< tab name="Bash" codelang="bash" >}}
344+
kubectl patch deployment retainkeys-demo --patch "$(cat patch-file-retainkeys.yaml)"
345+
{{< /tab >}}
346+
{{< tab name="PowerShell" codelang="posh" >}}
347+
kubectl patch deployment retainkeys-demo --patch $(Get-Content patch-file-retainkeys.yaml -Raw)
348+
{{< /tab >}}}
349+
{{< /tabs >}}
350+
351+
Examine the content of the Deployment:
352+
353+
```shell
354+
kubectl get deployment retainkeys-demo --output yaml
355+
```
356+
357+
The output shows that the strategy object in the Deployment does not contain the `rollingUpdate` key anymore:
358+
359+
```shell
360+
spec:
361+
strategy:
362+
type: Recreate
363+
template:
364+
```
365+
366+
### Notes on the strategic merge patch using the retainKeys strategy
367+
368+
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:
369+
370+
- It contains a list of strings.
371+
- All fields needing to be preserved must be present in the `$retainKeys` list.
372+
- The fields that are present will be merged with live object.
373+
- All of the missing fields will be cleared when patching.
374+
- All fields in the `$retainKeys` list must be a superset or the same as the fields present in the patch.
375+
376+
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`:
377+
378+
```go
379+
type DeploymentSpec struct {
380+
...
381+
// +patchStrategy=retainKeys
382+
Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" ...`
383+
```
384+
385+
You can also see the `retainKeys` strategy in the [OpenApi spec](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json):
386+
387+
```json
388+
"io.k8s.api.apps.v1.DeploymentSpec": {
389+
...
390+
"strategy": {
391+
"$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStrategy",
392+
"description": "The deployment strategy to use to replace existing pods with new ones.",
393+
"x-kubernetes-patch-strategy": "retainKeys"
394+
},
395+
```
396+
397+
And you can see the `retainKeys` strategy in the
398+
[Kubernetes API documentation](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deploymentspec-v1-apps).
399+
287400
## Alternate forms of the kubectl patch command
288401
289402
The `kubectl patch` command takes YAML or JSON. It can take the patch as a file or
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
2+
kind: Deployment
3+
metadata:
4+
name: retainkeys-demo
5+
spec:
6+
selector:
7+
matchLabels:
8+
app: nginx
9+
strategy:
10+
rollingUpdate:
11+
maxSurge: 30%
12+
template:
13+
metadata:
14+
labels:
15+
app: nginx
16+
spec:
17+
containers:
18+
- name: retainkeys-demo-ctr
19+
image: nginx

0 commit comments

Comments
 (0)