这个任务展示了如何使用 kubectl patch 就地更新 API 对象。这个任务中的练习演示了一个策略性合并 patch 和一个 JSON 合并 patch。
你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 Minikube 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:
要获知版本信息,请输入 kubectl version.
下面是具有两个副本的 Deployment 的配置文件。每个副本是一个 Pod,有一个容器:
application/deployment-patch.yaml
|
|---|
|
创建 Deployment:
kubectl create -f https://k8s.io/examples/application/deployment-patch.yaml查看与 Deployment 相关的 Pod:
kubectl get pods输出显示 Deployment 有两个 Pod。1/1 表示每个 Pod 有一个容器:
NAME READY STATUS RESTARTS AGE
patch-demo-28633765-670qr 1/1 Running 0 23s
patch-demo-28633765-j5qs3 1/1 Running 0 23s
把运行的 Pod 的名字记下来。稍后,您将看到这些 Pod 被终止并被新的 Pod 替换。
此时,每个 Pod 都有一个运行 nginx 镜像的容器。现在假设您希望每个 Pod 有两个容器:一个运行 nginx,另一个运行 redis。
创建一个名为 patch-file-containers.yaml 的文件。内容如下:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-2
image: redis修补您的 Deployment:
kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"查看修补后的 Deployment:
kubectl get deployment patch-demo --output yaml输出显示 Deployment 中的 PodSpec 有两个容器:
containers:
- image: redis
imagePullPolicy: Always
name: patch-demo-ctr-2
...
- image: nginx
imagePullPolicy: Always
name: patch-demo-ctr
...查看与 patch Deployment 相关的 Pod:
kubectl get pods输出显示正在运行的 Pod 与以前运行的 Pod 有不同的名称。Deployment 终止了旧的 Pod,并创建了两个
符合更新的部署规范的新 Pod。2/2 表示每个 Pod 有两个容器:
NAME READY STATUS RESTARTS AGE
patch-demo-1081991389-2wrn5 2/2 Running 0 1m
patch-demo-1081991389-jmg7b 2/2 Running 0 1m
仔细查看其中一个 patch-demo Pod:
kubectl get pod <your-pod-name> --output yaml输出显示 Pod 有两个容器:一个运行 nginx,一个运行 redis:
containers:
- image: redis
...
- image: nginx
...
您在前面的练习中所做的 patch 称为策略性合并 patch。
请注意,patch 没有替换容器列表。相反,它向列表中添加了一个新容器。换句话说,
patch 中的列表与现有列表合并。当您在列表中使用策略性合并 patch 时,并不总是这样。
在某些情况下,列表是替换的,而不是合并的。
对于策略性合并 patch,列表可以根据其 patch 策略进行替换或合并。patch 策略由 Kubernetes 源代码中字段标记中的 patchStrategy 键的值指定。
例如,PodSpec 结构体的 Containers 字段有 merge 的 patchStrategy:
type PodSpec struct {
...
Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`您还可以在 OpenApi spec 规范中看到 patch 策略:
"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"
},您可以在 Kubernetes API 文档 中看到 patch 策略
创建一个名为 patch-file-tolerations.yaml 的文件。内容如下:
spec:
template:
spec:
tolerations:
- effect: NoSchedule
key: disktype
value: ssdpatch Deployment:
kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"
kubectl patch deployment patch-demo --patch $(cat patch-file-containers.yaml)
查看 patch Deployment:
kubectl get deployment patch-demo --output yaml输出结果显示部署中的 PodSpec 只有一个默认:
containers:
- image: redis
imagePullPolicy: Always
name: patch-demo-ctr-2
...
- image: nginx
imagePullPolicy: Always
name: patch-demo-ctr
...tolerations:
- effect: NoSchedule
key: disktype
value: ssd请注意,PodSpec 中的 tolerations 列表被替换,而不是合并。这是因为 PodSpec 的 tolerance 字段的字段标签中没有
patchStrategy 键。所以策略合并 patch 使用默认的 patch 策略,也就是 replace。
type PodSpec struct {
...
Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`策略性合并 patch 不同于 JSON 合并 patch。 使用 JSON 合并 patch,如果您想更新列表,您必须指定整个新列表。新的列表完全取代了现有的列表。
kubectl patch 命令有一个 type 参数,您可以将其设置为以下值之一:
| Parameter value | Merge type |
|---|---|
| json | JSON Patch, RFC 6902 |
| merge | JSON Merge Patch, RFC 7386 |
| strategic | Strategic merge patch |
有关 JSON patch 和 JSON 合并 patch 的比较,查看 JSON patch 和 JSON 合并 patch。
type 参数的默认值是 strategic。在前面的练习中,我们做了一个策略性的合并 patch。
下一步,在相同的部署上执行 JSON 合并 patch。创建一个名为 patch-file-2 的文件。内容如下:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-3
image: gcr.io/google-samples/node-hello:1.0在 patch 命令中,将 type 设置为 merge:
kubectl patch deployment patch-demo --type merge --patch "$(cat patch-file-2.yaml)"查看 patch 部署:
kubectl get deployment patch-demo --output yamlpatch 中指定的容器列表只有一个容器。
输出显示您的一个容器列表替换了现有的容器列表。
spec:
containers:
- image: gcr.io/google-samples/node-hello:1.0
...
name: patch-demo-ctr-3列表中运行的 Pod:
kubectl get pods在输出中,您可以看到已经终止了现有的 Pod,并创建了新的 Pod。1/1 表示每个新 Pod只运行一个容器。
NAME READY STATUS RESTARTS AGE
patch-demo-1307768864-69308 1/1 Running 0 1m
patch-demo-1307768864-c86dc 1/1 Running 0 1mkubectl patch 命令使用 YAML 或 JSON。它可以将 patch 作为文件,也可以直接在命令行中使用。
创建一个文件名称是 patch-file.json 内容如下:
{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "patch-demo-ctr-2",
"image": "redis"
}
]
}
}
}
}以下命令是相同的:
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
kubectl patch deployment patch-demo --patch 'spec:\n template:\n spec:\n containers:\n - name: patch-demo-ctr-2\n image: redis'
kubectl patch deployment patch-demo --patch "$(cat patch-file.json)"
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'在本练习中,您使用 kubectl patch 更改部署对象的实时配置。您没有更改最初用于创建部署对象的配置文件。
用于更新 API 对象的其他命令包括
kubectl annotate,
kubectl edit,
kubectl replace,
kubectl scale,
和
kubectl apply。
此页是否对您有帮助?
感谢反馈。如果您有一个关于如何使用 Kubernetes 的特定的、需要答案的问题,可以访问 Stack Overflow. 在 GitHub 仓库上登记新的问题 报告问题 或者 提出改进建议.