在 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:v2.5.2
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:v2.5.2
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 滾動更新的推出狀態
kubectl rollout status ds/fluentd-elasticsearch -n kube-system
當推出完成時,輸出會類似於這樣
daemonset "fluentd-elasticsearch" successfully rolled out
疑難排解
DaemonSet 滾動更新卡住
有時,DaemonSet 滾動更新可能會卡住。以下是一些可能的原因
某些節點資源耗盡
推出卡住的原因是新的 DaemonSet Pod 無法排程到至少一個節點上。當節點資源耗盡時,可能會發生這種情況。
當這種情況發生時,透過比較 kubectl get nodes
的輸出和以下命令的輸出,找出沒有排程 DaemonSet Pod 的節點
kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system
找到這些節點後,從節點刪除一些非 DaemonSet Pod,以便為新的 DaemonSet Pod 騰出空間。
注意
當刪除的 Pod 不受任何控制器控制或 Pod 未被複製時,這將導致服務中斷。這也不會遵守 PodDisruptionBudget。損壞的推出
如果最近的 DaemonSet 範本更新已損壞,例如,容器崩潰迴圈,或容器映像不存在(通常是由於筆誤),則 DaemonSet 推出將不會進行。
若要修正此問題,請再次更新 DaemonSet 範本。新的推出將不會被先前不健康的推出所阻擋。
時鐘偏移
如果在 DaemonSet 中指定了 .spec.minReadySeconds
,則 master 和節點之間的時鐘偏移會使 DaemonSet 無法偵測到正確的推出進度。
清理
從命名空間刪除 DaemonSet
kubectl delete ds fluentd-elasticsearch -n kube-system