对 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