我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。
上一小节我们讲解的Deployment,虽然是整个k8s集群最常用的资源,并且默认的情况下他只会在node节点出现,但是我们有些业务是一个类似agent的操作,需要在每个节点都需要,并且只能有一个。这个时候使用deployment就不适合,这样的需求就更适合我们今天要讲的资源:DaemonSet,简称ds。
DaemonSet 是 Kubernetes 中的一种控制器,用于确保集群中的每个节点(或特定标签选择器匹配的节点)运行一个 Pod 的副本。与 Deployment 和 ReplicaSet 不同,DaemonSet 的主要用途是在所有节点上运行守护进程类的任务,例如日志收集、监控代理、存储卷插件等。
核心特性
节点覆盖:确保每个目标节点上都有一个 Pod 副本在运行。如果新节点加入集群并且满足标签选择器条件,DaemonSet 会自动创建一个新的 Pod 在该节点上运行。
更新策略:支持滚动更新,允许您安全地更新 DaemonSet 管理的 Pod,而不会影响整个集群的服务。可以配置最大不可用 Pod 数量来控制更新过程中的服务中断。
节点亲和性和容忍度:可以使用节点亲和性规则来指定哪些节点应该运行 DaemonSet 创建的 Pod。此外,还可以设置容忍度(Tolerations),以便 DaemonSet 的 Pod 能够调度到具有特定污点(Taints)的节点上。默认是每个节点都会有。
资源请求和限制:您可以为 DaemonSet 中的容器定义资源请求和限制,确保它们获得足够的计算资源,并避免过度消耗节点资源,后面会单独讲。
健康检查:可以为 DaemonSet 中的 Pod 配置 Liveness 和 Readiness 探针,以监控其健康状态并确保只有健康的 Pod 才会接收流量,这个后面也会单独讲。
持久化存储:如果需要,您可以为 DaemonSet 中的 Pod 配置持久卷(Persistent Volumes),以便它们能够访问持久化存储,这个后面也会单独讲。
使用场景
日志收集:如 Fluentd 或 Logstash,用于从各个节点收集日志。
监控代理:如 Prometheus Node Exporter 或 cAdvisor,用于监控节点和容器的性能指标。
网络插件:如 Calico 或 Flannel,用于提供网络功能。
存储插件:如 Ceph 或 GlusterFS 客户端,用于挂载分布式文件系统。
节点级别的任务:任何需要在每个节点上运行的任务都可以考虑使用 DaemonSet。
范例
下图是我们部署k8s的自动生成的两个ds,一个是网络插件,一个k8s的核心组件kube-proxy。这里我就没有单独额外创建ds,只把kube-proxy进行显示出来,里面的部分信息我进行删减,可以看这个配置文件并没有我们前面deployment的核心参数之一就是副本数量。

[root@master01 ~]# kubectl get ds -n kube-system kube-proxy -o yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
annotations:
deprecated.daemonset.template.generation: "1"
labels:
k8s-app: kube-proxy
name: kube-proxy
namespace: kube-system
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kube-proxy
template:
metadata:
creationTimestamp: null
labels:
k8s-app: kube-proxy
spec:
containers:
- command: #启动命令
- /usr/local/bin/kube-proxy
- --config=/var/lib/kube-proxy/config.conf
- --hostname-override=$(NODE_NAME)
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: registry.aliyuncs.com/google_containers/kube-proxy:v1.23.12
imagePullPolicy: IfNotPresent
name: kube-proxy
resources: {}
securityContext: #因为他需要操作系统的iptables,所以他这里使用了docker里面的特权模式
privileged: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts: #这里的挂载实际上和docker -v 效果一样
- mountPath: /var/lib/kube-proxy
name: kube-proxy
- mountPath: /run/xtables.lock
name: xtables-lock
- mountPath: /lib/modules
name: lib-modules
readOnly: true
dnsPolicy: ClusterFirst
hostNetwork: true #这里采用的主机网络模式
nodeSelector: #只要有这个标签才会有创建pod
kubernetes.io/os: linux
priorityClassName: system-node-critical
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: kube-proxy #pod的访问kube-apiserver的权限
serviceAccountName: kube-proxy
terminationGracePeriodSeconds: 30
tolerations:
- operator: Exists
volumes: #部分挂载信息是通过configmap进行引入的
- configMap:
defaultMode: 420
name: kube-proxy
name: kube-proxy
- hostPath:
path: /run/xtables.lock
type: FileOrCreate
name: xtables-lock
- hostPath:
path: /lib/modules
type: ""
name: lib-modules
updateStrategy: #pod的更新模式
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate一般而言ds我们更新较少,因为他主要是作为辅助程序来提高的,而非业务程序。