工作负载概述
工作负载是在Kubernetes上运行的应用程序。无论您的工作负载是单个组件还是协同工作的多个组件,您都可以在Kubernetes上的一组Pod中运行它。在Kubernetes中,工作负载是对一组Pod的抽象模型,用于描述业务的运行载体,包括Deployment、StatefulSet、DaemonSet、Job、CronJob等多种类型。
云容器引擎CCE提供基于Kubernetes原生类型的容器部署和管理能力,支持容器工作负载部署、配置、监控、扩容、升级、卸载、服务发现及负载均衡等生命周期管理。
容器组(Pod)
容器组(Pod)是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器(Container)、存储资源(Volume)、一个独立的网络IP以及管理控制容器运行方式的策略选项。
Pod使用主要分为两种方式:
- Pod中运行一个容器。这是Kubernetes最常见的用法,您可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。
- Pod中运行多个需要耦合在一起工作、需要共享资源的容器。通常这种场景下应用包含一个主容器和几个辅助容器(SideCar Container),如图1所示,例如主容器为一个web服务器,从一个固定目录下对外提供文件服务,而辅助容器周期性的从外部下载文件存到这个固定目录下。
实际使用中很少直接创建Pod,而是使用Kubernetes中称为Controller的抽象层来管理Pod实例,例如Deployment和Job。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和自愈能力。通常,Controller会使用Pod Template来创建相应的Pod。
无状态负载(Deployment)
Pod是Kubernetes创建或部署的最小单位,但是Pod是被设计为相对短暂的一次性实体,Pod可以被驱逐(当节点资源不足时)、随着集群的节点崩溃而消失。Kubernetes提供了Controller(控制器)来管理Pod,Controller可以创建和管理多个Pod,提供副本管理、滚动升级和自愈能力,其中最为常用的就是Deployment。
一个Deployment可以包含一个或多个Pod副本,每个Pod副本的角色相同,所以系统会自动为Deployment的多个Pod副本分发请求。
Deployment集成了上线部署、滚动升级、创建副本、恢复上线的功能,在某种程度上,Deployment实现无人值守的上线,大大降低了上线过程的复杂性和操作风险。
有状态负载(StatefulSet)
Deployment控制器下的Pod都有个共同特点,那就是每个Pod除了名称和IP地址不同,其余完全相同。需要的时候,Deployment可以通过Pod模板创建新的Pod;不需要的时候,Deployment就可以删除任意一个Pod。
但是在某些场景下,这并不满足需求,比如有些分布式的场景,要求每个Pod都有自己单独的状态时,比如分布式数据库,每个Pod要求有单独的存储,这时Deployment无法满足业务需求。
分布式有状态应用的特点主要是应用中每个部分的角色不同(即分工不同),比如数据库有主备、Pod之间有依赖,在Kubernetes中部署有状态应用对Pod有如下要求:
- Pod能够被别的Pod找到,要求Pod有固定的标识。
- 每个Pod有单独存储,Pod被删除恢复后,必须读取原来的数据,否则状态就会不一致。
Kubernetes提供了StatefulSet来解决这个问题,其具体如下:
- StatefulSet给每个Pod提供固定名称,Pod名称增加从0-N的固定后缀,Pod重新调度后Pod名称和HostName不变。
- StatefulSet通过Headless Service给每个Pod提供固定的访问域名。
- StatefulSet通过创建固定标识的PVC保证Pod重新调度后还是能访问到相同的持久化数据。
图3 StatefulSet
守护进程集(DaemonSet)
DaemonSet(守护进程集)在集群的每个节点上运行一个Pod,且保证只有一个Pod,非常适合一些系统层面的应用,例如日志收集、资源监控等,这类应用需要每个节点都运行,且不需要太多实例,一个比较好的例子就是Kubernetes的kube-proxy。
DaemonSet跟节点相关,如果节点异常,也不会在其他节点重新创建。
普通任务(Job)和定时任务(CronJob)
Job和CronJob是负责批量处理短暂的一次性任务(short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
- Job:是Kubernetes用来控制批处理型任务的资源对象。批处理业务与长期伺服业务(Deployment、StatefulSet)的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出(Pod自动删除)。
- CronJob:是基于时间的Job,就类似于Linux系统的crontab文件中的一行,在指定的时间周期运行指定的Job。
任务负载的这种用完即停止的特性特别适合一次性任务,比如持续集成。
工作负载类型对比
|
对比维度 |
Deployment(无状态负载) |
StatefulSet(有状态负载) |
DaemonSet(守护进程集) |
Job(普通任务) |
CronJob(定时任务) |
|---|---|---|---|---|---|
|
核心用途 |
部署无状态应用(如Web服务、API接口) |
部署有状态应用(如分布式数据库、集群中间件) |
部署节点级系统应用(如日志收集、资源监控) |
执行一次性批处理任务(如数据备份、文件转换) |
执行周期性批处理任务(如定时报表生成、日志清理) |
|
Pod 标识特性 |
Pod名称后缀随机,无固定标识 |
Pod名称带固定序号(如db-0、db-1) |
Pod名称后缀随机,无固定标识 |
Pod名称随机,任务完成后自动删除 |
Pod名称随机,任务完成后自动删除 |
|
网络访问能力 |
依赖Service或Ingress访问 |
依赖Headless Service,每个Pod有固定访问域名(如db-0.service-name.default.svc.cluster.local) |
通常通过节点IP + 固定端口访问,无需Service转发 |
无需长期网络访问,任务内自行处理逻辑 |
同Job,无长期网络访问需求 |
|
存储关联逻辑 |
存储数据不绑定Pod,大多使用临时存储或共享存储 |
每个Pod绑定独立PVC(持久化存储声明),Pod重建后仍挂载原PVC,数据不丢失 |
可挂载节点本地存储(如hostPath)或共享存储,随节点生命周期关联 |
临时存储(如emptyDir),任务完成后存储可清理 |
同Job,存储随任务周期清理 |
|
副本管理策略 |
支持多副本(1-N),副本无差异,可随意扩缩容、替换 |
副本按序号管理,扩缩容按序号递增 / 递减(如从db-2缩容到db-1),不可随意删除指定序号Pod |
副本数 = 集群节点数(默认每个节点 1 个),节点新增时自动部署,节点删除时Pod随之删除 |
无副本概念,按completions(完成次数)控制任务执行量 |
无副本概念,按时间周期触发Job,每次触发生成新任务Pod |
|
自愈与重建逻辑 |
Pod异常(如节点宕机)时,在其他健康节点重建Pod,IP/名称变化 |
Pod异常时,仍在原节点(或健康节点)重建,名称/HostName/PVC不变,状态可恢复 |
Pod异常时,仅在当前节点重建;节点宕机时,Pod不迁移到其他节点 |
任务失败时,按backoffLimit(重试次数)自动重试,直到成功或达到重试上限 |
基于Job的重试逻辑,周期内任务失败时重试,下周期重新触发新任务 |
|
生命周期特性 |
长期运行,除非手动删除或扩缩容到0 |
长期运行,需手动删除,存储数据长期保留 |
与节点生命周期绑定,节点存在则Pod运行 |
任务完成(Pod成功退出)后自动停止,Pod可保留或删除 |
按时间周期循环执行,每个周期任务独立,完成后停止 |
|
典型应用场景 |
Nginx 服务、Spring Boot 微服务、静态资源服务器 |
MySQL 集群、Elasticsearch 集群、ZooKeeper 集群 |
Fluentd(日志收集)、Prometheus Node Exporter(资源监控) |
数据批量导入(如Excel转数据库)、一次性脚本执行 |
每日定时数据库备份、每小时日志压缩清理、每周报表生成 |
工作负载生命周期说明
|
状态 |
说明 |
|---|---|
|
运行中 |
所有实例都处于运行中、或实例数为0时显示此状态。 |
|
未就绪 |
容器处于异常、负载下实例没有正常运行时显示此状态。 |
|
处理中 |
负载没有进入运行状态但也没有报错时显示此状态。 |
|
可用 |
当多实例无状态工作负载运行过程中部分实例异常,可用实例不为0,工作负载会处于可用状态。 |
|
执行完成 |
任务执行完成,仅普通任务存在该状态。 |
|
已停止 |
触发停止操作后,工作负载会处于停止状态,实例数变为0。v1.13之前的版本存在此状态。 |
|
删除中 |
触发删除操作后,工作负载会处于删除中状态。 |
