使用 kubectl patch 更新 API 对象

    你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 Minikube 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

    要获知版本信息,请输入 kubectl version.

    使用策略合并 patch 更新 Deployment

    下面是具有两个副本的 Deployment 的配置文件。每个副本是一个 Pod,有一个容器:

    创建 Deployment:

    1. kubectl create -f https://k8s.io/examples/application/deployment-patch.yaml

    查看与 Deployment 相关的 Pod:

    1. kubectl get pods

    输出显示 Deployment 有两个 Pod。1/1 表示每个 Pod 有一个容器:

    1. NAME READY STATUS RESTARTS AGE
    2. patch-demo-28633765-670qr 1/1 Running 0 23s
    3. patch-demo-28633765-j5qs3 1/1 Running 0 23s

    把运行的 Pod 的名字记下来。稍后,您将看到这些 Pod 被终止并被新的 Pod 替换。

    此时,每个 Pod 都有一个运行 nginx 镜像的容器。现在假设您希望每个 Pod 有两个容器:一个运行 nginx,另一个运行 redis。

    创建一个名为 patch-file-containers.yaml 的文件。内容如下:

    1. spec:
    2. template:
    3. spec:
    4. containers:
    5. - name: patch-demo-ctr-2
    6. image: redis

    修补您的 Deployment:

    1. kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"

    查看修补后的 Deployment:

    1. kubectl get deployment patch-demo --output yaml

    输出显示 Deployment 中的 PodSpec 有两个容器:

    1. containers:
    2. - image: redis
    3. imagePullPolicy: Always
    4. name: patch-demo-ctr-2
    5. ...
    6. - image: nginx
    7. imagePullPolicy: Always
    8. name: patch-demo-ctr
    9. ...

      输出显示正在运行的 Pod 与以前运行的 Pod 有不同的名称。Deployment 终止了旧的 Pod,并创建了两个 符合更新的部署规范的新 Pod。2/2 表示每个 Pod 有两个容器:

      仔细查看其中一个 patch-demo Pod:

      1. kubectl get pod <your-pod-name> --output yaml

      输出显示 Pod 有两个容器:一个运行 nginx,一个运行 redis:

      1. containers:
      2. - image: redis
      3. ...
      4. - image: nginx
      5. ...

      您在前面的练习中所做的 patch 称为策略性合并 patch。 请注意,patch 没有替换容器列表。相反,它向列表中添加了一个新容器。换句话说, patch 中的列表与现有列表合并。当您在列表中使用策略性合并 patch 时,并不总是这样。 在某些情况下,列表是替换的,而不是合并的。

      对于策略性合并 patch,列表可以根据其 patch 策略进行替换或合并。patch 策略由 Kubernetes 源代码中字段标记中的 键的值指定。 例如,PodSpec 结构体的 Containers 字段有 mergepatchStrategy

      1. type PodSpec struct {
      2. ...
      3. Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`

      您还可以在 OpenApi spec 规范中看到 patch 策略:

      1. "io.k8s.api.core.v1.PodSpec": {
      2. ...
      3. "containers": {
      4. "description": "List of containers belonging to the pod. ...
      5. },
      6. "x-kubernetes-patch-merge-key": "name",
      7. "x-kubernetes-patch-strategy": "merge"
      8. },

      您可以在 中看到 patch 策略

      创建一个名为 patch-file-tolerations.yaml 的文件。内容如下:

      1. spec:
      2. template:
      3. spec:
      4. tolerations:
      5. - effect: NoSchedule
      6. key: disktype
      7. value: ssd

      patch Deployment:

      1. kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"
      1. kubectl patch deployment patch-demo --patch $(cat patch-file-containers.yaml)

      查看 patch Deployment:

      1. kubectl get deployment patch-demo --output yaml

      输出结果显示部署中的 PodSpec 只有一个默认:

      1. - effect: NoSchedule
      2. key: disktype
      3. value: ssd

      请注意,PodSpec 中的 tolerations 列表被替换,而不是合并。这是因为 PodSpec 的 tolerance 字段的字段标签中没有 patchStrategy 键。所以策略合并 patch 使用默认的 patch 策略,也就是 replace

      1. type PodSpec struct {
      2. Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`

      kubectl patch 命令有一个 type 参数,您可以将其设置为以下值之一:

      Parameter valueMerge type
      jsonJSON Patch, RFC 6902
      merge
      strategicStrategic merge patch

      有关 JSON patch 和 JSON 合并 patch 的比较,查看 JSON patch 和 JSON 合并 patch

      type 参数的默认值是 strategic。在前面的练习中,我们做了一个策略性的合并 patch。

      下一步,在相同的部署上执行 JSON 合并 patch。创建一个名为 patch-file-2 的文件。内容如下:

      1. spec:
      2. template:
      3. spec:
      4. containers:
      5. - name: patch-demo-ctr-3
      6. image: gcr.io/google-samples/node-hello:1.0

      在 patch 命令中,将 type 设置为 merge

      1. kubectl patch deployment patch-demo --type merge --patch "$(cat patch-file-2.yaml)"

      查看 patch 部署:

      1. kubectl get deployment patch-demo --output yaml

      patch 中指定的容器列表只有一个容器。 输出显示您的一个容器列表替换了现有的容器列表。

      1. spec:
      2. containers:
      3. - image: gcr.io/google-samples/node-hello:1.0
      4. ...
      5. name: patch-demo-ctr-3

      列表中运行的 Pod:

      1. kubectl get pods

      在输出中,您可以看到已经终止了现有的 Pod,并创建了新的 Pod。1/1 表示每个新 Pod只运行一个容器。

      1. NAME READY STATUS RESTARTS AGE
      2. patch-demo-1307768864-69308 1/1 Running 0 1m
      3. patch-demo-1307768864-c86dc 1/1 Running 0 1m

      kubectl patch 命令的其他形式

      kubectl patch 命令使用 YAML 或 JSON。它可以将 patch 作为文件,也可以直接在命令行中使用。

      创建一个文件名称是 patch-file.json 内容如下:

      以下命令是相同的:

      1. kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
      2. kubectl patch deployment patch-demo --patch 'spec:\n template:\n spec:\n containers:\n - name: patch-demo-ctr-2\n image: redis'
      3. kubectl patch deployment patch-demo --patch "$(cat patch-file.json)"
      4. kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'

      接下来