又到了 Demo 環節 ( ´ ▽ ` )ノ
修改 Deployment 的 yaml 設定:
把版本從 1.14.2
換成 1.11.5
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx
image: nginx:1.11.5
ports:
- containerPort: 80
執行更新指令
kubectl apply -f <deployment yaml file>
利用 describe
指令確認目前的 Pod 版本:
kubectl describe pod nginx-deployment-756c76457c-mr79z
可以從 image 的內容看出 Pod 已經被更新成後來設定的 1.11.5
版囉!
再看看 Deployment 的資訊:
從 OldReplicaSets
和 NewReplicaSet
也可以看出版本已經更新。
執行過程中,可能會出現一段提醒訊息:
Warning: resource deployments/nginx-deployment is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. deployment.apps/nginx-deployment configured
蛤?什麼意思?
kubectl.kubernetes.io/last-applied-configuration
是 Kubernetes 中的重要annotation
。
它有兩個用途:
apply
指令時,kubectl 會比較新的設定、目前的資源狀態和這個註解中的前一次配置共三種版本,並判斷正確的部署。kubectl apply
),這個註解的紀錄就可能會與實際狀態不同步,在這種情況下,後續執行 apply 操作可能會產生意外的結果。舉個 🌰:
如果部署一個沒有設定 replicas
的 Deployment 會發生什麼事?
部署成功啦 (´・Д・)」
這時候如果使用 kubectl apply
修改 image 版本,也可以正常更新且不影響目前的 replicas
設定。
這是因為 replicas 其實不屬 kubectl管理範圍,展開 last-applied-configuration:
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"annotations": {},
"name": "demo-deployment",
"namespace": "default"
},
"spec": {
"selector": {
"matchLabels": {
"app": "demo"
}
},
"template": {
"metadata": {
"labels": {
"app": "demo"
}
},
"spec": {
"containers": [
{
"image": "nginx:1.14.2",
"name": "nginx",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}
從標注內容就可以清楚識別哪些資訊才是屬於 kubectl apply
的比對範圍囉!
總之,這段訊息只是提醒這個 Deployment 沒有執行 apply
指令需要的 last-applied-configuration
,而這個遺失的標注(annotation)將會被自動補上。
我們可以透過指令來確認:
kubectl get deployment nginx-deployment -o yaml
可以看見 Deployment 的 metadata
的確是被補上 kubectl.kubernetes.io/last-applied-configuration
了。
之後再次執行 apply
就不會再跳出訊息啦!
如果記得的話,也可以在 create
的時候加上 --save-config
去建立標注:
kubectl create --save-config -f <deployment yaml file>
補充資訊:
kubectl apply
&kubectl replace
在 kubectl 指令中,
apply
和replace
都可以更新資源,兩者的差別在Day-11:kubectl 中提過的命令式和宣告式。
kubectl apply
是宣告式,它會保留未變更的內容,僅修改配置中更新的部分。kubectl replace
則是命令式,它會無視原有配置並完全按照新設定重新建立資源。
也就是說,如果發生 🌰 中誤刪資訊的情況又使用kubectl replace
做更新,就很有可能會建置出與預期不符的資源。
在實務管理上建議使用
apply
,避免直接針對資源做異動(比如直接去改 Pod 的內容)。
咳咳,扯遠了。
如果覺得要下一大堆指令去確認更新狀態很麻煩,可以透過指令:
kubectl rollout history deployment/<deployment name>
來確認更新紀錄。
再次修改 Deployment 的 yaml 設定:
把版本從 1.11.5
換回 1.14.2
,並再次執行 kubectl apply
指令。
(這次的確沒有再出現 Warning)
然後調閱更新紀錄:
kubectl rollout history deployment/<deployment name>
revision
:修訂版本revisionHistoryLimit
,未指定時預設為 10,超過這個數量的舊版本將會被自動刪除。revisionHistoryLimit
就可以設定要保留的歷史修訂版本數量囉!透過--revision
指令可以看到每一個版本的部署內容:
kubectl rollout history deployment/nginx-deployment --revision=<欲調閱的版本號>
用這個方式可以快速的確認異動紀錄。
對了,要更新 image 除了修改 yaml 再執行 apply
更新之外,其實也可以使用指令調整:
kubectl set image deployment <deployment-name> <container-name>=<new image>
# 範例
kubectl set image deployment nginx-deployment nginx=nginx:1.17
不過,這種透過指令直接修改元件的方式並不利於後續維護,相關的操作並不會同步回 yaml 設定上,往後在部署新版本的時候也難以查詢異動軌跡,很容易就會把改動過的內容覆蓋掉了。
用在測試或自行練習的時候倒是很方便。
最後補充幾個操作指令:
kubectl rollout status deployment <deployment-name>
kubectl rollout pause deployment <deployment-name>
kubectl rollout resume deployment <deployment-name>
雖說一般執行 Deployment 更新,都會建議使用 apply
比較保險,但也不是說 replace
就沒用處了。在 Kubernetes 的預設值中,有些資訊是不能透過 apply
指令做修改的。這時候,就需要使用 replace
讓資源刪除後重新建立才能順利更新。