From e073ac38f85ad4720b1401311901a0cefe5ea902 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Wed, 12 Aug 2020 10:39:51 +0800 Subject: [PATCH] [zh] Rework kubectl patch tasks The file location has changed in English site, with two new sections added. --- .../update-api-object-kubectl-patch.md | 322 +++++++++++++----- 1 file changed, 234 insertions(+), 88 deletions(-) rename content/zh/docs/tasks/{run-application => manage-kubernetes-objects}/update-api-object-kubectl-patch.md (54%) diff --git a/content/zh/docs/tasks/run-application/update-api-object-kubectl-patch.md b/content/zh/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md similarity index 54% rename from content/zh/docs/tasks/run-application/update-api-object-kubectl-patch.md rename to content/zh/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md index 68c99d6881..6b7d13cf14 100644 --- a/content/zh/docs/tasks/run-application/update-api-object-kubectl-patch.md +++ b/content/zh/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md @@ -2,16 +2,14 @@ title: 使用 kubectl patch 更新 API 对象 description: 使用 kubectl patch 更新 Kubernetes API 对象。做一个策略性的合并 patch 或 JSON 合并 patch。 content_type: task -weight: 40 +weight: 50 --- @@ -20,31 +18,23 @@ weight: 40 This task shows how to use `kubectl patch` to update an API object in place. The exercises in this task demonstrate a strategic merge patch and a JSON merge patch. --> - -这个任务展示了如何使用 `kubectl patch` 就地更新 API 对象。这个任务中的练习演示了一个策略性合并 patch 和一个 JSON 合并 patch。 - +这个任务展示如何使用 `kubectl patch` 就地更新 API 对象。 +这个任务中的练习演示了一个策略性合并 patch 和一个 JSON 合并 patch。 ## {{% heading "prerequisites" %}} - {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - - - -## 使用策略合并 patch 更新 Deployment - - +## 使用策略合并 patch 更新 Deployment 下面是具有两个副本的 Deployment 的配置文件。每个副本是一个 Pod,有一个容器: @@ -53,7 +43,6 @@ is a Pod that has one container: - 创建 Deployment: ```shell @@ -85,13 +74,13 @@ patch-demo-28633765-j5qs3 1/1 Running 0 23s Make a note of the names of the running Pods. Later, you will see that these Pods get terminated and replaced by new ones. --> -把运行的 Pod 的名字记下来。稍后,您将看到这些 Pod 被终止并被新的 Pod 替换。 +把运行的 Pod 的名字记下来。稍后,你将看到这些 Pod 被终止并被新的 Pod 替换。 -此时,每个 Pod 都有一个运行 nginx 镜像的容器。现在假设您希望每个 Pod 有两个容器:一个运行 nginx,另一个运行 redis。 +此时,每个 Pod 都有一个运行 nginx 镜像的容器。现在假设你希望每个 Pod 有两个容器:一个运行 nginx,另一个运行 redis。 -修补您的 Deployment: +修补你的 Deployment: ```shell kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)" @@ -129,7 +118,7 @@ The output shows that the PodSpec in the Deployment has two Containers: --> 输出显示 Deployment 中的 PodSpec 有两个容器: -```shell +```yaml containers: - image: redis imagePullPolicy: Always @@ -189,20 +178,18 @@ containers: -### 策略性合并类的 patch - - -您在前面的练习中所做的 patch 称为`策略性合并 patch`。 -请注意,patch 没有替换`容器`列表。相反,它向列表中添加了一个新容器。换句话说, -patch 中的列表与现有列表合并。当您在列表中使用策略性合并 patch 时,并不总是这样。 +### 策略性合并类的 patch 的说明 + +你在前面的练习中所做的 patch 称为`策略性合并 patch(Strategic Merge Patch)`。 +请注意,patch 没有替换`containers` 列表。相反,它向列表中添加了一个新 Container。换句话说, +patch 中的列表与现有列表合并。当你在列表中使用策略性合并 patch 时,并不总是这样。 在某些情况下,列表是替换的,而不是合并的。 -对于策略性合并 patch,列表可以根据其 patch 策略进行替换或合并。patch 策略由 Kubernetes 源代码中字段标记中的 `patchStrategy` 键的值指定。 -例如,`PodSpec` 结构体的 `Containers` 字段有 `merge` 的 `patchStrategy`: +对于策略性合并 patch,列表可以根据其 patch 策略进行替换或合并。 +patch 策略由 Kubernetes 源代码中字段标记中的 `patchStrategy` 键的值指定。 +例如,`PodSpec` 结构体的 `Containers` 字段的 `patchStrategy` 为 `merge`: ```go type PodSpec struct { @@ -224,8 +212,7 @@ type PodSpec struct { You can also see the patch strategy in the [OpenApi spec](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json): --> - -您还可以在 [OpenApi spec](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json) +你还可以在 [OpenApi spec](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json) 规范中看到 patch 策略: ```json @@ -243,8 +230,8 @@ You can also see the patch strategy in the And you can see the patch strategy in the [Kubernetes API documentation](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core). --> -您可以在 [Kubernetes API 文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core) -中看到 patch 策略 +你可以在 [Kubernetes API 文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core) +中看到 patch 策略。 -patch Deployment: +对 Deployment 执行 patch 操作: - -{{< tabs name="kubectl_patch_example" >}} -{{{< tab name="Bash" codelang="bash" >}} +``` kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)" -{{< /tab >}} -{{< tab name="PowerShell" codelang="posh" >}} -kubectl patch deployment patch-demo --patch $(cat patch-file-containers.yaml) -{{< /tab >}}} -{{< /tabs >}} +``` -查看 patch Deployment: +查看修补后的 Deployment: ```shell kubectl get deployment patch-demo --output yaml @@ -288,7 +269,7 @@ kubectl get deployment patch-demo --output yaml -输出结果显示部署中的 PodSpec 只有一个默认: +输出结果显示 Deployment 中的 PodSpec 只有一个容忍度设置: ```shell @@ -316,8 +297,8 @@ Notice that the `tolerations` list in the PodSpec was replaced, not merged. This 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`. --> -请注意,PodSpec 中的 `tolerations` 列表被替换,而不是合并。这是因为 PodSpec 的 tolerance 字段的字段标签中没有 -`patchStrategy` 键。所以策略合并 patch 使用默认的 patch 策略,也就是 `replace`。 +请注意,PodSpec 中的 `tolerations` 列表被替换,而不是合并。这是因为 PodSpec 的 `tolerations` +的字段标签中没有 `patchStrategy` 键。所以策略合并 patch 操作使用默认的 patch 策略,也就是 `replace`。 ```go type PodSpec struct { @@ -327,36 +308,38 @@ type PodSpec struct { -## 使用 JSON 合并 patch 更新部署 - +## 使用 JSON 合并 patch 更新 Deployment + 策略性合并 patch 不同于 [JSON 合并 patch](https://tools.ietf.org/html/rfc7386)。 -使用 JSON 合并 patch,如果您想更新列表,您必须指定整个新列表。新的列表完全取代了现有的列表。 +使用 JSON 合并 patch,如果你想更新列表,你必须指定整个新列表。新的列表完全取代现有的列表。 -`kubectl patch` 命令有一个 `type` 参数,您可以将其设置为以下值之一: +`kubectl patch` 命令有一个 `type` 参数,你可以将其设置为以下值之一: - + + - + +
Parameter valueMerge type
参数值合并类型
jsonJSON Patch, RFC 6902
mergeJSON Merge Patch, RFC 7386
strategicStrategic merge patch
strategic策略合并 patch
-有关 JSON patch 和 JSON 合并 patch 的比较,查看[ JSON patch 和 JSON 合并 patch](http://erosb.github.io/post/json-patch-vs-merge-patch/)。 +有关 JSON patch 和 JSON 合并 patch 的比较,查看 +[JSON patch 和 JSON 合并 patch](https://erosb.github.io/post/json-patch-vs-merge-patch/)。 -下一步,在相同的部署上执行 JSON 合并 patch。创建一个名为 `patch-file-2` 的文件。内容如下: +下一步,在相同的 Deployment 上执行 JSON 合并 patch。创建一个名为 `patch-file-2` 的文件。内容如下: ```yaml spec: @@ -391,7 +374,7 @@ kubectl patch deployment patch-demo --type merge --patch "$(cat patch-file-2.yam -查看 patch 部署: +查看修补后的 Deployment: ```shell kubectl get deployment patch-demo --output yaml @@ -401,10 +384,10 @@ kubectl get deployment patch-demo --output yaml The `containers` list that you specified in the patch has only one Container. The output shows that your list of one Container replaced the existing `containers` list. --> -patch 中指定的`容器`列表只有一个容器。 -输出显示您的一个容器列表替换了现有的`容器`列表。 +patch 中指定的`containers`列表只有一个 Container。 +输出显示你所给出的 Contaier 列表替换了现有的 `containers` 列表。 -```shell +```yaml spec: containers: - image: gcr.io/google-samples/node-hello:1.0 @@ -425,7 +408,7 @@ kubectl get pods In the output, you can see that the existing Pods were terminated, and new Pods were created. The `1/1` indicates that each new Pod is running only one Container. --> -在输出中,您可以看到已经终止了现有的 Pod,并创建了新的 Pod。`1/1` 表示每个新 Pod只运行一个容器。 +在输出中,你可以看到已经终止了现有的 Pod,并创建了新的 Pod。`1/1` 表示每个新 Pod只运行一个容器。 ```shell NAME READY STATUS RESTARTS AGE @@ -434,16 +417,185 @@ patch-demo-1307768864-c86dc 1/1 Running 0 1m ``` +## Use strategic merge patch to update a Deployment using the retainKeys strategy -## kubectl patch 命令的其他形式 +Here's the configuration file for a Deployment that uses the `RollingUpdate` strategy: +--> +## 使用带 retainKeys 策略的策略合并 patch 更新 Deployment + +{{< codenew file="application/deployment-retainkeys.yaml" >}} + + +创建 Deployment: + +```shell +kubectl apply -f https://k8s.io/examples/application/deployment-retainkeys.yaml +``` +这时,Deployment 被创建,并使用 `RollingUpdate` 策略。 + +创建一个名为 `patch-file-no-retainkeys.yaml` 的文件,内容如下: + +```yaml +spec: + strategy: + type: Recreate +``` + + +修补你的 Deployment: + +{{< tabs name="kubectl_retainkeys_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 >}} + + +在输出中,你可以看到,当 `spec.strategy.rollingUpdate` 已经拥有取值定义时, +将其 `type` 设置为 `Recreate` 是不可能的。 + +```shell +The Deployment "retainkeys-demo" is invalid: spec.strategy.rollingUpdate: Forbidden: may not be specified when strategy `type` is 'Recreate' +``` + + +更新 `type` 取值的同时移除 `spec.strategy.rollingUpdate` 现有值的方法是 +为策略性合并操作设置 `retainKeys` 策略: + +创建另一个名为 `patch-file-retainkeys.yaml` 的文件,内容如下: + +```yaml +spec: + strategy: + $retainKeys: + - type + type: Recreate +``` + + +使用此 patch,我们表达了希望只保留 `strategy` 对象的 `type` 键。 +这样,在 patch 操作期间 `rollingUpdate` 会被删除。 + +使用新的 patch 重新修补 Deployment: + +{{< tabs name="kubectl_retainkeys2_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 >}} + + +检查 Deployment 的内容: + +```shell +kubectl get deployment retainkeys-demo --output yaml +``` + + +输出显示 Deployment 中的 `strategy` 对象不再包含 `rollingUpdate` 键: + +```shell +spec: + strategy: + type: Recreate + template: +``` + + +### 关于使用 retainKeys 策略的策略合并 patch 操作的说明 + +在前文练习中所执行的称作 *带 retainKeys` 策略的策略合并 patch(Strategic Merge +Patch with retainKeys Strategy)*。 +这种方法引入了一种新的 `$retainKey` 指令,具有如下策略: + +- 其中包含一个字符串列表; +- 所有需要被保留的字段必须在 `$retainKeys` 列表中给出; +- 对于已有的字段,会和对象上对应的内容合并; +- 在修补操作期间,未找到的字段都会被清除; +- 列表 `$retainKeys` 中的所有字段必须 patch 操作所给字段的超集,或者与之完全一致。 + + +策略 `retainKeys` 并不能对所有对象都起作用。它仅对那些 Kubernetes 源码中 +`patchStrategy` 字段标志值包含 `retainKeys` 的字段有用。 +例如 `DeploymentSpec` 结构的 `Strategy` 字段就包含了 `patchStrategy` 为 +`retainKeys` 的标志。 + +```go +type DeploymentSpec struct { + ... + // +patchStrategy=retainKeys + Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" ...` +``` + + +你也可以查看 [OpenAPI 规范](https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json)中的 `retainKeys` 策略: + +```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" + }, +``` + + +而且你也可以在 +[Kubernetes API 文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deploymentspec-v1-apps). +中看到 `retainKey` 策略。 + + - `kubectl patch` 命令使用 YAML 或 JSON。它可以将 patch 作为文件,也可以直接在命令行中使用。 +## kubectl patch 命令的其他形式 + +`kubectl patch` 命令使用 YAML 或 JSON。它可以接受以文件形式提供的补丁,也可以 +接受直接在命令行中给出的补丁。 -以下命令是相同的: +以下命令是等价的: ```shell kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)" @@ -482,11 +634,7 @@ kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"co -## 总结 - - -在本练习中,您使用 `kubectl patch` 更改部署对象的实时配置。您没有更改最初用于创建部署对象的配置文件。 +## 总结 + +在本练习中,你使用 `kubectl patch` 更改了 Deployment 对象的当前配置。 +你没有更改最初用于创建 Deployment 对象的配置文件。 用于更新 API 对象的其他命令包括 -[kubectl annotate](/docs/reference/generated/kubectl/kubectl-commands/#annotate), -[kubectl edit](/docs/reference/generated/kubectl/kubectl-commands/#edit), -[kubectl replace](/docs/reference/generated/kubectl/kubectl-commands/#replace), -[kubectl scale](/docs/reference/generated/kubectl/kubectl-commands/#scale), +[`kubectl annotate`](/docs/reference/generated/kubectl/kubectl-commands/#annotate), +[`kubectl edit](/docs/reference/generated/kubectl/kubectl-commands/#edit), +[`kubectl replace`](/docs/reference/generated/kubectl/kubectl-commands/#replace), +[`kubectl scale`](/docs/reference/generated/kubectl/kubectl-commands/#scale), 和 -[kubectl apply](/docs/reference/generated/kubectl/kubectl-commands/#apply)。 - - - +[`kubectl apply`](/docs/reference/generated/kubectl/kubectl-commands/#apply)。 ## {{% heading "whatsnext" %}} - - -* [Kubernetes 对象管理器](/docs/concepts/overview/object-management-kubectl/overview/) -* [使用命令管理 Kubernetes 对象](/docs/concepts/overview/object-management-kubectl/imperative-command/) -* [使用配置文件强制管理 Kubernetes 对象](/docs/concepts/overview/object-management-kubectl/imperative-config/) -* [使用配置文件对 Kubernetes 对象进行声明式管理](/docs/concepts/overview/object-management-kubectl/declarative-config/) +* [Kubernetes 对象管理](/zh/docs/concepts/overview/working-with-objects/object-management/) +* [使用指令式命令管理 Kubernetes 对象](/zh/docs/tasks/manage-kubernetes-objects/imperative-command/) +* [使用配置文件执行 Kubernetes 对象的指令式管理](/zh/docs/tasks/manage-kubernetes-objects/imperative-config) +* [使用配置文件对 Kubernetes 对象进行声明式管理](/zh/docs/tasks/manage-kubernetes-objects/declarative-config/)