對 DaemonSet 執行滾動更新
本頁面展示瞭如何對 DaemonSet 執行滾動更新。
準備工作
你需要一個 Kubernetes 叢集,並且 kubectl 命令列工具已配置為與你的叢集通訊。建議在至少有兩個節點不作為控制平面主機的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 演練場中的一個。
DaemonSet 更新策略
DaemonSet 有兩種更新策略型別
OnDelete
:使用OnDelete
更新策略,在你更新 DaemonSet 模板後,新的 DaemonSet Pod 只有在你手動刪除舊的 DaemonSet Pod 時才會被建立。這與 Kubernetes 1.5 及之前版本中 DaemonSet 的行為相同。RollingUpdate
:這是預設的更新策略。
使用RollingUpdate
更新策略,在你更新 DaemonSet 模板後,舊的 DaemonSet Pod 將被殺死,新的 DaemonSet Pod 將以受控方式自動建立。在整個更新過程中,每個節點上最多隻執行一個 DaemonSet Pod。
執行滾動更新
要啟用 DaemonSet 的滾動更新功能,你必須將其 .spec.updateStrategy.type
設定為 RollingUpdate
。
你可能還需要設定 .spec.updateStrategy.rollingUpdate.maxUnavailable
(預設為 1)、.spec.minReadySeconds
(預設為 0) 和 .spec.updateStrategy.rollingUpdate.maxSurge
(預設為 0)。
建立具有 RollingUpdate
更新策略的 DaemonSet
此 YAML 檔案指定了一個更新策略為 'RollingUpdate' 的 DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# these tolerations are to have the daemonset runnable on control plane nodes
# remove them if your control plane nodes should not run pods
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v5.0.1
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
驗證 DaemonSet 清單的更新策略後,建立 DaemonSet
kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml
或者,如果你打算使用 kubectl apply
更新 DaemonSet,則使用 kubectl apply
建立相同的 DaemonSet。
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml
檢查 DaemonSet RollingUpdate
更新策略
檢查 DaemonSet 的更新策略,並確保其設定為 RollingUpdate
kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system
如果你尚未在系統中建立 DaemonSet,請使用以下命令檢查你的 DaemonSet 清單
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'
兩個命令的輸出都應為
RollingUpdate
如果輸出不是 RollingUpdate
,請返回並相應地修改 DaemonSet 物件或清單。
更新 DaemonSet 模板
對 RollingUpdate
DaemonSet 的 .spec.template
的任何更新都將觸發滾動更新。讓我們透過應用新的 YAML 檔案來更新 DaemonSet。這可以通過幾個不同的 kubectl
命令來完成。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# these tolerations are to have the daemonset runnable on control plane nodes
# remove them if your control plane nodes should not run pods
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v5.0.1
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
宣告式命令
如果你使用配置檔案更新 DaemonSet,請使用 kubectl apply
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml
命令式命令
如果你使用命令式命令更新 DaemonSet,請使用 kubectl edit
kubectl edit ds/fluentd-elasticsearch -n kube-system
只更新容器映象
如果你只需要更新 DaemonSet 模板中的容器映象,即 .spec.template.spec.containers[*].image
,請使用 kubectl set image
kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system
檢視滾動更新狀態
最後,檢視最新 DaemonSet 滾動更新的 rollout 狀態
kubectl rollout status ds/fluentd-elasticsearch -n kube-system
當 rollout 完成時,輸出類似於此
daemonset "fluentd-elasticsearch" successfully rolled out
故障排除
DaemonSet 滾動更新停滯
有時,DaemonSet 滾動更新可能會停滯。以下是一些可能的原因
某些節點資源不足
由於新的 DaemonSet Pod 無法在至少一個節點上排程,rollout 停滯。這可能是因為節點 資源不足。
發生這種情況時,透過比較 kubectl get nodes
的輸出和以下命令的輸出來查詢沒有 DaemonSet Pod 排程的節點
kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system
找到這些節點後,從節點中刪除一些非 DaemonSet Pod 以騰出空間給新的 DaemonSet Pod。
注意
如果刪除的 Pod 不受任何控制器控制,或者 Pod 未被複制,這將導致服務中斷。這也不尊重 PodDisruptionBudget。損壞的 rollout
如果最近的 DaemonSet 模板更新已損壞,例如,容器崩潰迴圈,或者容器映象不存在(通常是由於打字錯誤),DaemonSet rollout 將無法進行。
要解決此問題,請再次更新 DaemonSet 模板。新的 rollout 不會被以前不健康的 rollout 阻塞。
時鐘偏差
如果 DaemonSet 中指定了 .spec.minReadySeconds
,則主節點和節點之間的時鐘偏差將導致 DaemonSet 無法檢測到正確的 rollout 進度。
清理
從名稱空間中刪除 DaemonSet
kubectl delete ds fluentd-elasticsearch -n kube-system