kubernetes Deployment/Daemonset/StatefulSet区别
1. 区别图
对象 | 是否有状态 | POD数量 |
---|---|---|
Deployment | 无 | 按副本数 |
DaemonSet | 无 | (适合节点)每节点一个 |
StatefulSet | 有 | 按副本数 |
2. DaemonSet
DaemonSet通常用于运行需要在每个节点上运行的系统级别服务,如日志收集器、监视代理和网络代理等。
与Deployment和StatefulSet不同,DaemonSet不关心Pod的数量,而是关心Pod在每个节点上运行的情况;就是用来部署守护进程的, DaemonSet 用于在每个 Kubernetes 节点中将守护进程的副本作为后台进程运行;当节点加入到 Kubernetes 集群中,会新生成一个pod再该节点上运行,当节点从集群只能够被移除后,该节点上的这个 Pod 也会被移除,当然,如果我们删除 DaemonSet ,所有和这个对象相关的 Pods 都会被删除.
DeamonSet对于部署需要在所有或某些节点上运行且不需要用户干预的持续后台任务非常有用。
应用场景:
•集群存储守护程序,如 glusterd 、 ceph 要部署在每个节点上以提供持久性存储;
•节点监视守护进程,如 Prometheus 监控集群,可以在每个节点上运行一个 node-exporter 进程来收集监控节点的信息;
•日志收集守护程序,如 fluentd 或 logstash ,在每个节点上运行以收集容器的日志
3. Deployment与StatefulSet区别
Deployment用于部署无状态服务,StatefulSet用来部署有状态服务
具体的,什么场景需要使用StatefulSet呢?官方给出的建议是,如果你部署的应用满足以下一个或多个部署需求,则建议使用StatefulSet。
- 稳定的、唯一的网络标识。
- 稳定的、持久的存储。
- 有序的、优雅的部署和伸缩。
- 有序的、优雅的删除和停止。
- 有序的、自动的滚动更新。
稳定的主要是针对Pod发生re-schedule后仍然要保持之前的网络标识和持久化存储。这里所说的网络标识包括hostname、集群内DNS中该Pod对应的A Record,并不能保证Pod re-schedule之后IP不变。要想保持Pod IP不变,我们可以借助稳定的Pod hostname定制IPAM获取固定的Pod IP。借助StatefulSet的
稳定的唯一的网络标识
特性,我们能比较轻松的实现Pod的固定IP需求,然后如果使用Deployment,那么将会复杂的多,你需要考虑滚动更新的过程中的参数控制(maxSurge、maxUnavailable)、每个应用的IP池预留造成的IP浪费等等问题。
因此,我想再加一个StatefulSet的使用场景:
- 实现固定的Pod IP方案, 可以优先考虑基于StatefulSet;
和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
3.1. 稳定的网络标识
StatefulSet中反复强调的“稳定的网络标识”,主要指Pods的hostname以及对应的DNS Records。
- HostName:StatefulSet的Pods的hostname按照这种格式生成:
$(statefulset name)-$(ordinal), ordinal
从0 ~ N-1
(N为期望副本数)。- StatefulSet Controller在创建pods时,会给pod加上一个pod name label:
statefulset.kubernetes.io/pod-name
, 然后设置到Pod的pod name和hostname中。 -
pod name label有啥用呢?我们可以创建独立的Service匹配到这个指定的pod,然后方便我们单独对这个pod进行debug等处理。
- StatefulSet Controller在创建pods时,会给pod加上一个pod name label:
- DNS Records:
- Headless Service的DNS解析:
$(service name).$(namespace).svc.cluster.local
通过DNS RR解析到后端其中一个Pod。SRV Records只包含对应的Running and Ready的Pods,不Ready的Pods不会在对应的SRV Records中。 - Pod的DNS解析:
$(hostname).$(service name).$(namespace).svc.cluster.local
解析到对应hostname的Pod。
- Headless Service的DNS解析:
3.2.稳定的持久化存储
StatefulSet对应Pod的存储最好通过StorageClass来动态创建:每个Pod都会根据StatefulSet中定义的VolumeClaimTemplate来创建一个对应的PVC,然后PVS通过StorageClass自动创建对应的PV,并挂载给Pod。所以这种方式,需要你事先创建好对应的StorageClass。当然,你也可以通过预先由管理员手动创建好对应的PV,只要能保证自动创建的PVC能和这些PV匹配上。
- 每个Pod对应一个PVC,PVC的名称是这样组成的:$(volumeClaimTemplates.name)-$(pod's hostname),跟对应的Pod是一一对应的。
- 当Pod发生re-schedule(其实是recreate)后,它所对应的PVC所Bound的PV仍然会自动的挂载到新的Pod中。
- Kubernetes会按照VolumeClaimTemplate创建N(N为期望副本数)个PVC,由PVCs根据指定的StorageClass自动创建PVs。
- 当通过级联删除StatefulSet时并不会自动删除对应的PVCs,所以PVC需要手动删除。
- 当通过级联删除StatefulSet或者直接删除对应Pods时,对应的PVs并不会自动删除。需要你手动的去删除PV。