W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
這個任務(wù)展示如何使用 ?kubectl patch
? 就地更新 API 對象。 這個任務(wù)中的練習(xí)演示了一個策略性合并 patch 和一個 JSON 合并 patch。
你必須擁有一個 Kubernetes 的集群,同時你的 Kubernetes 集群必須帶有 kubectl 命令行工具。 建議在至少有兩個節(jié)點的集群上運行本教程,且這些節(jié)點不作為控制平面主機。 如果你還沒有集群,你可以通過 Minikube 構(gòu)建一個你自己的集群,或者你可以使用下面任意一個 Kubernetes 工具構(gòu)建:
要獲知版本信息,請輸入 ?kubectl version
?。
下面是具有兩個副本的 Deployment 的配置文件。每個副本是一個 Pod,有一個容器:
apiVersion: apps/v1
kind: Deployment
metadata:
name: patch-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: patch-demo-ctr
image: nginx
tolerations:
- effect: NoSchedule
key: dedicated
value: test-team
創(chuàng)建 Deployment:
kubectl apply -f https://k8s.io/examples/application/deployment-patch.yaml
查看與 Deployment 相關(guān)的 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 鏡像的容器?,F(xiàn)在假設(shè)你希望每個 Pod 有兩個容器:一個運行 nginx,另一個運行 redis。
創(chuàng)建一個名為 ?patch-file.yaml
? 的文件。內(nèi)容如下:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-2
image: redis
修補你的 Deployment:
kubectl patch deployment patch-demo --patch-file patch-file.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 相關(guān)的 Pod:
kubectl get pods
輸出顯示正在運行的 Pod 與以前運行的 Pod 有不同的名稱。Deployment 終止了舊的 Pod,并創(chuàng)建了兩個 符合更新的部署規(guī)范的新 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
仔細(xì)查看其中一個 patch-demo Pod:
kubectl get pod <your-pod-name> --output yaml
輸出顯示 Pod 有兩個容器:一個運行 nginx,一個運行 redis:
containers:
- image: redis
...
- image: nginx
...
你在前面的練習(xí)中所做的 patch 稱為 ?策略性合并 patch(Strategic Merge Patch)
?。 請注意,patch 沒有替換 ?containers
?列表。相反,它向列表中添加了一個新 Container。換句話說, patch 中的列表與現(xiàn)有列表合并。當(dāng)你在列表中使用策略性合并 patch 時,并不總是這樣。 在某些情況下,列表是替換的,而不是合并的。
對于策略性合并 patch,列表可以根據(jù)其 patch 策略進(jìn)行替換或合并。 patch 策略由 Kubernetes 源代碼中字段標(biāo)記中的 ?patchStrategy
?鍵的值指定。 例如,?PodSpec
?結(jié)構(gòu)體的 ?Containers
? 字段的 ?patchStrategy
?為 ?merge
?:
type PodSpec struct {
...
Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`
你還可以在 OpenApi spec 規(guī)范中看到 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 策略。
創(chuàng)建一個名為 ?patch-file-tolerations.yaml
? 的文件。內(nèi)容如下:
spec:
template:
spec:
tolerations:
- effect: NoSchedule
key: disktype
value: ssd
對 Deployment 執(zhí)行 patch 操作:
kubectl patch deployment patch-demo --patch-file patch-file-tolerations.yaml
查看修補后的 Deployment:
kubectl get deployment patch-demo --output yaml
輸出結(jié)果顯示 Deployment 中的 PodSpec 只有一個容忍度設(shè)置:
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 的 ?tolerations
?的字段標(biāo)簽中沒有 ?patchStrategy
?鍵。所以策略合并 patch 操作使用默認(rèn)的 patch 策略,也就是 ?replace
?。
type PodSpec struct {
...
Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`
策略性合并 patch 不同于 JSON 合并 patch。 使用 JSON 合并 patch,如果你想更新列表,你必須指定整個新列表。新的列表完全取代現(xiàn)有的列表。
?kubectl patch
? 命令有一個 ?type
?參數(shù),你可以將其設(shè)置為以下值之一:
參數(shù)值 | 合并類型 |
---|---|
json | JSON Patch, RFC 6902 |
merge | JSON Merge Patch, RFC 7386 |
strategic | 策略合并 patch |
有關(guān) JSON patch 和 JSON 合并 patch 的比較,查看 JSON patch 和 JSON 合并 patch。
?type
?參數(shù)的默認(rèn)值是 ?strategic
?。在前面的練習(xí)中,我們做了一個策略性的合并 patch。
下一步,在相同的 Deployment 上執(zhí)行 JSON 合并 patch。創(chuàng)建一個名為 ?patch-file-2
? 的文件。內(nèi)容如下:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-3
image: gcr.io/google-samples/node-hello:1.0
在 patch 命令中,將 ?type
?設(shè)置為 ?merge
?:
kubectl patch deployment patch-demo --type merge --patch-file patch-file-2.yaml
查看修補后的 Deployment:
kubectl get deployment patch-demo --output yaml
patch 中指定的 ?containers
?列表只有一個 Container。 輸出顯示你所給出的 Contaier 列表替換了現(xiàn)有的 ?containers
?列表。
spec:
containers:
- image: gcr.io/google-samples/node-hello:1.0
...
name: patch-demo-ctr-3
列表中運行的 Pod:
kubectl get pods
在輸出中,你可以看到已經(jīng)終止了現(xiàn)有的 Pod,并創(chuàng)建了新的 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 1m
apiVersion: apps/v1
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
創(chuàng)建 Deployment:
kubectl apply -f https://k8s.io/examples/application/deployment-retainkeys.yaml
這時,Deployment 被創(chuàng)建,并使用 ?RollingUpdate
?策略。
創(chuàng)建一個名為 ?patch-file-no-retainkeys.yaml
? 的文件,內(nèi)容如下:
spec:
strategy:
type: Recreate
修補你的 Deployment:
kubectl patch deployment retainkeys-demo --type merge --patch-file patch-file-no-retainkeys.yaml
在輸出中,你可以看到,當(dāng) ?spec.strategy.rollingUpdate
? 已經(jīng)擁有取值定義時, 將其 ?type
?設(shè)置為 ?Recreate
?是不可能的。
The Deployment "retainkeys-demo" is invalid: spec.strategy.rollingUpdate: Forbidden: may not be specified when strategy `type` is 'Recreate'
更新 ?type
?取值的同時移除 ?spec.strategy.rollingUpdate
? 現(xiàn)有值的方法是 為策略性合并操作設(shè)置 ?retainKeys
?策略:
創(chuàng)建另一個名為 ?patch-file-retainkeys.yaml
? 的文件,內(nèi)容如下:
spec:
strategy:
$retainKeys:
- type
type: Recreate
使用此 patch,我們表達(dá)了希望只保留 ?strategy
?對象的 ?type
?鍵。 這樣,在 patch 操作期間 ?rollingUpdate
?會被刪除。
使用新的 patch 重新修補 Deployment:
kubectl patch deployment retainkeys-demo --type merge --patch-file patch-file-retainkeys.yaml
檢查 Deployment 的內(nèi)容:
kubectl get deployment retainkeys-demo --output yaml
輸出顯示 Deployment 中的 ?strategy
?對象不再包含 ?rollingUpdate
?鍵:
spec:
strategy:
type: Recreate
template:
在前文練習(xí)中所執(zhí)行的稱作 帶 ?retainKeys
?策略的策略合并 patch(Strategic Merge Patch with retainKeys Strategy)。 這種方法引入了一種新的 ?$retainKey
? 指令,具有如下策略:
$retainKeys
? 列表中給出;
$retainKeys
? 中的所有字段必須 patch 操作所給字段的超集,或者與之完全一致。
策略 ?retainKeys
?并不能對所有對象都起作用。它僅對那些 Kubernetes 源碼中 ?patchStrategy
?字段標(biāo)志值包含 ?retainKeys
?的字段有用。 例如 ?DeploymentSpec
?結(jié)構(gòu)的 ?Strategy
?字段就包含了 ?patchStrategy
?為 ?retainKeys
?的標(biāo)志。
type DeploymentSpec struct {
...
// +patchStrategy=retainKeys
Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" ...`
你也可以查看 OpenAPI 規(guī)范中的 ?retainKeys
?策略:
"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 文檔中看到 ?retainKey
?策略。
?kubectl patch
? 命令使用 YAML 或 JSON。它可以接受以文件形式提供的補丁,也可以 接受直接在命令行中給出的補丁。
創(chuàng)建一個文件名稱是 ?patch-file.json
? 內(nèi)容如下:
{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "patch-demo-ctr-2",
"image": "redis"
}
]
}
}
}
}
以下命令是等價的:
kubectl patch deployment patch-demo --patch-file 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-file patch-file.json
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'
在本練習(xí)中,你使用 ?kubectl patch
? 更改了 Deployment 對象的當(dāng)前配置。 你沒有更改最初用于創(chuàng)建 Deployment 對象的配置文件。 用于更新 API 對象的其他命令包括 ?kubectl annotate
?、 ?kubectl edit
?、 ?kubectl replace
?、 ?kubectl scale
? 和 ?kubectl apply
?。
說明: 定制資源不支持策略性合并 patch。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: