对 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