Kubernetes 设计模式笔记 —— Daemon Service

Daemon Service 能够向目标节点放置和运行有优先级的、面向基础设施的 Pod,通常被管理员用来部署与节点相关联的 Pod 以增强 Kubernetes 平台的功能。

从操作系统层面来看,daemon 是一类长时间运行、能够自行恢复的后台进程,通常在计算机启动时即自动加载,不会与前台进行任何交互。
这类概念也存在于应用层面。比如运行在后台的 JVM deamon 线程为用户线程提供支持服务,有着较低的优先级,执行诸如 GC 等任务。

与上述场景类似,Kubernetes 也提供了 DaemonSet 功能。
DaemonSet 与 ReplicaSet 有一个相同点,都是负责确保特定数量的 Pod 是一直运行着的。不同点在于,ReplicaSet 的具体配置通常取决于应用对于高可用和工作负载的需求,与节点数量无关;DaemonSet 则并不关注负载方面的因素,它的主要目的是在每一个节点(或部分特定的节点)上保持运行一个 Pod。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: random-refresher
spec:
selector:
matchLabels:
app: random-refresher
template:
metadata:
labels:
app: random-refresher
spec:
nodeSelector:
feature: hw-rng
containers:
- image: k8spatterns/random-generator:1.0
name: random-generator
command:
- sh
- -c
- >-
"while true; do
java -cp / RandomRunner /host_dev/random 100000;
sleep 30; done"
volumeMounts:
- mountPath: /host_dev
name: devices
volumes:
- name: devices
hostPath:
path: /dev

DaemonSet 的适用场景比如日志收集、监控数据导出甚至 kube-proxy 等。其与 ReplicaSet 的主要区别如下:

  • 默认情况下,DaemonSet 会向每一个节点都部署一个 Pod 实例,可以通过 nodeSelector 字段只选取部分节点
  • DaemonSet 创建的 Pod 能够在 Scheduler 启动之前运行,因此,节点上还没有任何其他 Pod 被部署时,DaemonSet 创建的 Pod 就已经可以运行
  • 由于 Scheduler 并没有参与 DaemonSet 的部署,节点上的 unschedulable 字段对 DaemonSet 控制器不起作用
  • DaemonSet 管理的 Pod 通常只运行在特定的节点上,因而很多控制器会对这些 Pod 区别对待,给与更高的优先级。比如 descheduler 会避免销毁这类 Pod,cluster autoscaler 会对它们独立地进行管理

DaemonSet 和 CronJob 是两个非常优秀的例子,Kubernetes 将单节点的概念比如 Crontab 和 daemon 脚本,转换成多节点的、集群化的原语,应用到分布式系统的管理中。

参考资料

Kubernetes Patterns