【k8s】Deployment、StatefulSet、DaemonSet
请你讲一下 Kubernetes 中 Deployment、StatefulSet、DaemonSet 的区别/适用场景,并说明它们和 Pod 的关系。
回答:首先,在 Kubernetes 中 Pod 是最基本的运行单元,一个 Pod 封装一个或多个容器。但在生产环境中我们几乎不会直接创建单个 Pod 来部署服务,因为这样 Pod 崩溃后不会自动恢复,也无法滚动更新或扩缩容,而是通过控制器(controller)来管理 Pod 的生命周期、数量、更新、扩缩等,以实现声明式管理、自动修复等能力。常见的工作负载控制器包括 Deployment、StatefulSet 和 DaemonSet。
Deployment 适用于无状态应用(stateless)。使用 Deployment 时,你定义 replicas (期望副本数)、Pod 模板、更新策略等,系统会保证始终有指定数量的这些 Pod 运行、自动替换失败的 Pod 、支持滚动更新和回滚。因为 Pod 之间没有固定身份、可以互换、也不依赖于本地存储,所以 Deployment 是最通用的选择。例如:用户服务、前端、后端微服务、API,能快速水平扩缩容并支持无缝滚动更新
StatefulSet 适用于有状态应用(stateful):这些应用每个实例可能都有固定身份(例如 数据库主从、Kafka broker 等)、需要稳定网络标识(hostname、DNS 名)和持久化存储。StatefulSet 为每个 Pod 提供稳定的 ordinal 索引(例如 app-0、app-1)、稳定主机名、各自的 PersistentVolumeClaim 、并且支持按序创建与销毁。因为这些特性,StatefulSet 比 Deployment 更适合那类需要状态和身份的服务。例如:想部署一个数据库集群(Postgres、MySQL)、消息队列(Kafka)、分布式存储(Etcd、Cassandra)——— 需要稳定 ID、稳定存储、顺序启动/下线。
DaemonSet 的用途则不同:它保证在集群中每个(或符合条件的)节点上都运行一个 Pod 副本。换句话说,当你需要在每一台节点上统一部署一个节点代理、日志收集器、监控 agent 、网络插件等时,就用 DaemonSet。加入新的节点时,DaemonSet 会自动在该节点上创建 Pod;节点移除时,Pod 也自动回收。例如:想在每一台节点安装日志收集或监控 agent,用 DaemonSet。
总结一下它们与 Pod 的关系:我们通过控制器指定 Pod 模板与期望状态,控制器负责 Pod 的实际创建、删除、更新、调度逻辑,从而让 Pod 不再是孤立管理。选择哪一个控制器,取决于你的 Pod 是否需要固定身份/持久存储/节点级别部署。
通过deployment部署服务,如何保证零宕机的更新?
回答:在生产环境中,我们一般通过 Deployment 的滚动更新(RollingUpdate)策略 实现零宕机。
通常配置 maxSurge=1、maxUnavailable=0,保证更新时先启动一个新 Pod,待其通过 readinessProbe 后才删除旧 Pod,整个过程中副本数始终不变。
readinessProbe 控制流量接入,确保服务依赖加载、初始化完成后才接收请求;
preStop 钩子 和 terminationGracePeriodSeconds 实现优雅下线,让旧 Pod 在退出前处理完正在执行的请求;
多副本(replicas≥2)和 PodDisruptionBudget 则保证即使节点维护或批量更新,也不会影响整体可用性。
实际上线我们常采用 分批滚动(系统不会一次性替换所有 Pod,而是按批次逐步替换)或金丝雀发布(先小部分 Pod + 少量流量,逐步扩大),通过监控指标(如 QPS、错误率、延迟)判断稳定后再继续推广,如有异常可快速 rollout undo 回滚。
整个过程中新 Pod 就绪后接流量,旧 Pod 完成请求后退出,对外请求无感知,从而实现真正的零宕机更新。
那 readinessProbe 是怎么影响 Service 流量的?
回答:readinessProbe 的核心作用是控制 Pod 是否接收流量。
Kubernetes 的 kubelet 会根据 readinessProbe 的结果更新 Pod 的就绪状态,如果探针未通过,Pod 状态变为 NotReady,Service 控制器就会自动将该 Pod 从 endpoints 中移除,新的请求不会再打到它。
当探针恢复通过后,Pod 会重新加入到 endpoints 列表,开始接收流量。
这种机制让我们在滚动更新、新版本上线或服务初始化期间能够优雅地控制流量分配,实现真正的零宕机更新。
生产环境中,readinessProbe 通常会配合 preStop 钩子、terminationGracePeriodSeconds 一起使用,确保旧实例优雅退出、新实例准备就绪后再接入流量。
通过daemonset部署的服务,添加新结点没有自动在新结点上创建pod,可能是什么原因?
回答:DaemonSet 的目标是:每个符合调度条件的节点上都运行一个 Pod 副本。
(1)新节点标签不匹配 DaemonSet 的 nodeSelector ,不满足调度条件。
(2)节点被标记为不可调度(cordon)或有污点(taint)但 Pod 没有对应 toleration;
(3)节点资源不足导致调度失败。
