对 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
,则主节点和节点之间的时钟偏差将使 DaemonSet 无法检测到正确的推出进度。
清理
从命名空间中删除 DaemonSet
kubectl delete ds fluentd-elasticsearch -n kube-system