第一部分:Deployment资源对象的理论基础与架构剖析
1.1 为什么需要Deployment
在Kubernetes生态中,用户从不直接管理单个Pod——Pod在节点宕机、资源不足、被驱逐时会消失,Kubernetes也不会自动将其重生。因此,Kubernetes引入了“控制器”(Controller)这一核心抽象。控制器通过“声明式期望状态”与“实际状态”之间的持续比对(即调谐循环,Reconcile Loop),驱动集群不断向用户期望的目标收敛。Deployment正是Kubernetes中最常用的工作负载控制器之一,专注于管理无状态应用(Stateless Applications)的Pod副本集。
Deployment的核心价值可以概括为五大能力:
| 能力维度 | 具体说明 |
|---|---|
| 副本管理 | 始终维持指定数量的Pod副本(如replicas: 3) |
| 自愈能力 | Pod崩溃或节点故障时,控制器自动重建新Pod |
| 滚动更新 | 无缝升级镜像或配置,服务零停机 |
| 版本回滚 | 一键回退到上一个稳定版本 |
| 暂停/恢复 | 支持分阶段发布与金丝雀部署 |
适用场景包括Web服务、API网关、微服务应用、缓存代理等无状态负载;不适用于数据库、ZooKeeper、Kafka等有状态应用,后者应使用StatefulSet。
1.2 Deployment控制器的两层架构
Deployment的核心设计理念是分层控制——它并不直接管理Pod,而是通过一个中间层ReplicaSet来实现间接管控。整个控制链条如下:
Deployment(用户声明期望状态) ↕ 控制 ReplicaSet(版本管理与副本保障) ↕ 管理 Pod(实际运行实例)Deployment层的职责包括:接收用户的更新指令(如修改镜像版本)、决定滚动更新的速率(通过maxSurge与maxUnavailable参数)、维护版本历史链(每个更新操作创建一个新的ReplicaSet),以及在必要时执行回滚操作。当用户执行kubectl rollout undo时,Deployment将重新激活上一个历史ReplicaSet,而不需要保存任何Pod快照。
ReplicaSet层的职责则更加聚焦:它通过标签选择器(Label Selector)匹配Pod,持续监控符合标签的Pod数量,若实际数量少于期望,则通过Pod模板创建新Pod;若实际数量多于期望,则删除多余的Pod。
每次更新Deployment的Pod模板(例如变更镜像或环境变量)时,Deployment控制器都会创建一个新的ReplicaSet,旧ReplicaSet保留但不缩放至零,以便用户随时回滚。通过kubectl rollout history deployment/<deployment名>可查看所有历史版本(Revision)的完整列表。
1.3 控制器模式与调谐循环
Deployment(以及其他所有Kubernetes控制器)的运行基于控制器模式(Controller Pattern)。这个模式可用以下伪代码精确描述:
for { 实际状态 := 获取集群中对象 X 的实际状态 期望状态 := 获取集群中对象 X 的期望状态(来自用户提交的YAML) if 实际状态 == 期望状态 { 什么都不做 } else { 执行编排动作,将实际状态调整为期望状态 } }具体而言,Deployment控制器从etcd中获取所有携带指定标签(如app: nginx)的Pod,统计其数量作为实际状态;而Deployment对象的spec.replicas字段值即为期望状态。控制器对二者进行比较,确定是需要创建新Pod还是删除多余Pod。
这一比对过程在Kubernetes中称为调谐(Reconcile),而循环本身称为调谐循环(Reconcile Loop)或同步循环(Sync Loop)。调谐的最终结果总是对被控制对象的某种读写操作——增加Pod、删除Pod、更新Pod配置等,这也是Kubernetes“面向API对象编程”理念的直观体现。
从事件驱动的实现角度看,Deployment Controller通过Informer机制同时监听Deployment、ReplicaSet和Pod三种资源的变化事件,任一事件触发即进入syncLoop进行状态同步。
第二部分:Deployment配置清单(Manifest)字段详解
在深入YAML配置之前,有必要明确一个概念:Kubernetes配置清单(Manifest)是以YAML格式编写的声明式配置文件,用于定义集群中资源的期望状态。Kubernetes通过kubectl apply命令读取Manifest,将其写入API Server,再由各控制器驱动集群状态向该声明收敛。
2.1 基础框架与必须字段
每个部署到Kubernetes的YAML文件都必须包含四个必须字段:
| 字段 | 说明 | 本教程取值 |
|---|---|---|
apiVersion | 指定使用的Kubernetes API版本 | apps/v1 |
kind | 声明的Kubernetes对象类型 | Deployment |
metadata | 资源的元数据(名称、标签、命名空间等) | 见下方详细解析 |
spec | 资源的期望状态规格 | 见下方详细解析 |
2.2 Deployment核心YAML完整示例与逐字段解析
本章将给出一个包含Liveness、Readiness、Startup三种探针的生产级Nginx Deployment配置,然后对每一个字段展开深度解释。请注意本教程基于openEuler 24.03 SP3系统,因此containerd作为默认的容器运行时,CRI交互方式与Docker有所不同,但用户几乎感知不到,所有kubectl命令行为完全一致。
生产环境提示:在生产级别部署中,建议将容器镜像标签固定为精确版本(如
nginx:1.25.3)而非latest,以确保部署的可重复性、审计能力与回滚精准性。
创建文件nginx-production-deployment.yaml,内容如下:
--- # 文档分隔符:YAML支持多个文档合并,此符号将同一文件中的多个资源定义分开 # 以下为Deployment资源定义 apiVersion: apps/v1 # Kubernetes API的apps组v1稳定版本 kind: Deployment # 资源类型为Deployment metadata: name: nginx-production # Deployment的名称,集群内唯一标识 namespace: default # 命名空间,逻辑隔离单位 labels: # 标签:用于组织、筛选和关联资源 app: nginx-production # 应用标签(kv键值对,下同) tier: frontend # 层级标签 version: v1 # 版本标签 annotations: # 注解:记录非标识性元数据(如描述、维护人等) description: "Production-grade Nginx Deployment with health probes" maintainer: "devops-team" # --- spec开始:Deployment的期望状态定义 --- spec: replicas: 3 # (重要)期望的Pod副本数量 revisionHistoryLimit: 10 # 保留的历史ReplicaSet数量上限,用于回滚 minReadySeconds: 30 # Pod就绪后等待30秒才标记为Available # --- selector:选择器,用于建立Deployment与Pod的关联关系 --- selector: matchLabels: # 等值匹配:必须选择标签 app: nginx-production # 此处的键值必须与template中定义的标签一致 tier: frontend # --- strategy:更新策略配置 --- strategy: type: RollingUpdate # 滚动更新策略(默认值),另一种为Recreate rollingUpdate: maxSurge: 1 # 更新期间允许超出期望副本数的最大Pod数 maxUnavailable: 1 # 更新期间允许不可用的最大Pod数 # --- template:Pod模板定义(核心字段)--- template: metadata: labels: # Pod模板的标签,必须包含selector.matchLabels的所有键值 app: nginx-production tier: frontend version: v1 spec: # Pod规格 terminationGracePeriodSeconds: 60 # 优雅终止等待时间 # --- containers:容器列表定义 (数组类型)--- containers: - name: nginx # 容器名称 image: nginx:1.25.3 # 容器镜像及具体版本标签 imagePullPolicy: IfNotPresent # 镜像拉取策略 # ---- 端口定义 ---- ports: - name: http # 端口名称(用于Service引用) containerPort: 80 # 容器内监听的端口号 protocol: TCP # 传输层协议 # ---- 资源请求与限制 ---- resources: requests: # 调度器保证分配的最小资源 cpu: "100m" # 100毫核CPU (0.1核) memory: "128Mi" # 128兆字节内存 limits: # 容器能使用的最大资源上限 cpu: "500m" # 500毫核CPU (0.5核) memory: "512Mi" # 512兆字节内存 # ---- 启动探针 ---- # 作用:检测应用是否已完成启动。配置了startupProbe后, # liveness和readiness探针将被禁用, # 直到startupProbe首次成功为止 startupProbe: httpGet: # 检查方式:HTTP GET请求 path: /healthz # 健康检查的URI路径 port: 80 # 目标端口 scheme: HTTP # HTTP协议 initialDelaySeconds: 10 # 容器启动后等待10秒再执行第一次探测 periodSeconds: 10 # 探测间隔:每10秒执行一次 timeoutSeconds: 3 # 单次探测超时时间3秒 failureThreshold: 30 # 连续失败30次(即30×10=300秒)才判定失败 successThreshold: 1 # 成功1次即视为启动成功 # ---- 存活探针 ---- # 作用:检测容器是否正常运行,失败则触发容器重启 livenessProbe: httpGet: path: /healthz # 存活检测路径 port: 80 scheme: HTTP initialDelaySeconds: 15 # 启动后首次探测延迟 periodSeconds: 20 # 探测间隔:每20秒一次 timeoutSeconds: 5 # 超时时间5秒 failureThreshold: 3 # 连续3次失败触发重启 successThreshold: 1 # 成功1次即视为存活 # ---- 就绪探针 ---- # 作用:检测容器是否准备好接收客户端流量,失败则从Service端点移除 readinessProbe: httpGet: path: /ready # 就绪检测路径 port: 80 scheme: HTTP initialDelaySeconds: 5 # 启动后5秒首次探测 periodSeconds: 5 # 探测间隔:每5秒一次 timeoutSeconds: 3 # 超时时间3秒 failureThreshold: 3 # 连续失败3次标记为未就绪 successThreshold: 1 # 成功1次即视为就绪 # ---- 生命周期钩子 ---- lifecycle: preStop: # 容器终止前执行的命令 exec: command: - "/bin/sh" - "-c" - "sleep 15" # 等待15秒让Service卸载端点2.3 各字段深度解析
2.3.1 apiVersion与kind
apiVersion: apps/v1指定了使用Apps API组的v1稳定版本。Kubernetes的API按照以下成熟度组织:
Alpha:可能包含bug,不保证未来兼容,示例格式为
object/v1alpha1Beta:仍有些不稳定,但很可能进入稳定版,示例格式为
object/v1beta1Stable:建议生产使用,示例格式为
apps/v1
Deployment自Kubernetes 1.9起使用apps/v1稳定版API,是生产环境唯一推荐使用的版本。
kind: Deployment声明了YAML文件描述的是Deployment类型的Kubernetes对象。Kubernetes支持数十种kind类型,包括但不限于Deployment、Service、ConfigMap、DaemonSet、StatefulSet、Job等。
2.3.2 metadata字段
metadata.name是Deployment在集群中的唯一标识符,同一命名空间内不可重复。命名建议:采用小写字母、数字和连字符组合,如nginx-production。
metadata.namespace用于逻辑隔离资源。若不指定,默认使用default命名空间。
metadata.labels是键值对格式的标签,用于组织和筛选资源。标签是Kubernetes中最为核心的关联机制——Deployment通过spec.selector.matchLabels筛选与管理Pod,Pod通过标签匹配所属的Service。labels可以包含多个键值对,在组织上与Selector配合使用。
metadata.annotations与标签类似(也是键值对),但用于记录非标识性元数据,如描述文字、维护者信息、构建版本号等。注解不支持选择器查询。
关键约束:
template.metadata.labels定义的标签,必须包含spec.selector.matchLabels中定义的全部标签键值对,否则API Server将在创建时直接拒绝该配置。这是因为Deployment必须能够通过选择器精确定位它所管理的Pod,任何标签不匹配都将破坏这一关联。
2.3.3 spec.replicas
replicas: 3声明期望的Pod副本数量为3。Deployment控制器将持续确保集群中有且仅有3个符合选择器匹配条件的Pod在运行。
副本数的选择须考虑以下因素:
高可用性:至少2个副本可承受单Pod故障;3个副本可承受单节点宕机
资源约束:每个Pod的资源请求量 × 副本数 < 集群可用资源
负载分散:副本数越多,单个Pod承受的负载越低
2.3.4 spec.revisionHistoryLimit
revisionHistoryLimit: 10限制Deployment保留的历史ReplicaSet数量为10。每次更新Deployment时都会创建一个新的ReplicaSet,旧的ReplicaSet保留用于回滚操作。该字段的值直接控制了可回滚的版本总数。
如果将此值设置为0,Deployment将清理所有历史ReplicaSet,从而无法执行回滚操作。生产环境中通常保留5~10个版本,以在存储开销与回滚灵活性之间取得平衡。
2.3.5 spec.minReadySeconds
minReadySeconds: 30指定新创建的Pod在变为“就绪”状态后,必须持续就绪至少30秒,才能被Deployment标记为“可用”(Available)。这个字段的主要价值在于缓冲——避免Pod短时间内就绪又变为未就绪的“抖动”问题(快速就绪-未就绪交替),减少流量波动。
2.3.6 spec.selector
selector定义了Deployment用于识别其所管理Pod的标签选择器。matchLabels使用等值匹配方式——Pod的标签键值必须完全匹配此处定义的键值,才能被该Deployment管理。Kubernetes还支持matchExpressions进行集合式选择,但matchLabels的等值匹配是最常用模式。
2.3.7 spec.strategy
strategy控制Deployment的更新行为。Kubernetes支持两种策略:
| 策略类型 | 行为描述 | 适用场景 |
|---|---|---|
RollingUpdate(默认) | 逐步创建新Pod再删除旧Pod,保证服务不中断 | 绝大多数Web服务、API应用 |
Recreate | 先删除所有旧Pod,再重新创建新Pod | 不支持多版本的数据库应用、一次性批量任务 |
滚动更新参数详解
maxSurge:更新期间允许超过期望副本数的最大Pod数量。取值可以是绝对值(如maxSurge: 1)或百分比(如maxSurge: 25%)。当期望副本数为3、maxSurge为1时,更新过程中最多允许4个Pod同时存在;若maxSurge为25%,计算方式为3 × 25% = 0.75,向上取整得1(但严格数学公式因实现而异)。
maxUnavailable:更新期间允许不可用的最大Pod数量。取值同样可以是绝对值或百分比。例如maxUnavailable: 1表示更新过程中最多允许1个Pod处于不可用状态。
这两个参数共同构成了滚动更新的速率窗口:
maxSurge控制“能超前创建多少新Pod”maxUnavailable控制“能超前删除多少旧Pod”
Kubernetes默认值均为25%,已足够满足绝大多数集群的需求。
滚动更新数学演示(期望副本=3):
| 参数组合 | 含义 | 更新步进 |
|---|---|---|
maxSurge:1, maxUnavailable:0 | 允许1个额外Pod,不允许任何Pod不可用 | 先创建1个新Pod→就绪后删除1个旧Pod→重复3次 |
maxSurge:1, maxUnavailable:1 | 允许1个额外Pod和1个Pod不可用 | 创建1新→删除1旧→创建1新→删除1旧→创建1新→完成 |
maxSurge:0, maxUnavailable:1 | 不允许额外Pod,允许1个不可用 | 删除1旧→创建1新→就绪→删除1旧→创建1新→就绪→删除1旧→创建1新 |
maxSurge:25%, maxUnavailable:25%(默认) | 3×25%=0.75→向上取整≈1个额外与1个不可用 | 相当于1和1,创建1新→删除1旧→重复 |
简单说:surge大→速度快但耗资源多,unavailable大→速度快但可用副本少,策略选取本质是在部署速度 vs 服务质量之间做权衡。
2.3.8 spec.template
template是Deployment中最重要的字段——它定义了待创建的Pod的完整规格。template本身是一个Pod模板对象,包含metadata和spec两个子字段。
Pod模板的metadata通常只包含labels字段。需要注意的是,Pod模板的metadata不应包含name或namespace字段——Pod的名称由ReplicaSet自动生成(格式为<Deployment名>-<ReplicaSet哈希>-<Pod随机后缀>),命名空间也必须与Deployment保持一致,不能跨命名空间管理Pod。
2.3.9 spec.template.spec.terminationGracePeriodSeconds
terminationGracePeriodSeconds: 60定义Pod收到SIGTERM信号后,在被强制SIGKILL终止之前等待的秒数,默认值为30秒。对于需要优雅关闭的应用程序(如正在处理HTTP长连接或事务的Web服务),应适当增大该值,以确保容器有足够时间完成正在处理的请求。
2.3.10 containers详解
containers字段是Pod模板的核心,定义了Pod中运行的容器列表。每个容器支持以下关键子字段:
name:容器的唯一标识名,在Pod内唯一
image:容器使用的基础镜像,建议指定精确版本标签
imagePullPolicy:镜像拉取策略
策略值 行为 Always每次启动容器时都尝试拉取镜像 IfNotPresent仅当本地不存在镜像时才拉取 Never从不拉取镜像,必须本地存在 openEuler 24.03 SP3环境推荐
IfNotPresent,以加快Pod启动速度并避免网络依赖。ports:声明容器监听的端口(数组)。各字段含义:
name:端口名称,供Service通过名称引用containerPort:容器内实际监听的端口号protocol:传输层协议(TCP/UDP/SCTP)
resources:CPU与内存的请求和限制。
requests是调度器进行Pod调度时保证分配的最小量;limits是容器允许使用的最大量。容器运行后实际占用资源随负载波动干两者之间。合理设置这两个值有助于Kubernetes做出最优的调度决策并防止单个容器耗尽节点资源。
第三部分:Pod探针体系——存活·就绪·启动三种探针详解
3.1 探针存在的必要性
在不配置任何健康检查的情况下,Kubernetes仅能判断Pod是否存在以及容器进程是否在运行,但这远远不够:
应用启动缓慢,但容器状态已为Running——此时若接入流量,请求将失败
应用线程死锁或陷入死循环,但进程依然存在——Kubernetes完全感知不到异常
依赖的数据库/Redis/消息队列不可用,但服务仍在接收外部请求——客户端将收到大量错误响应
探针正是为解决上述诊断盲区而设计的健康检查机制。
3.2 三种探针的核心定位与差异
Kubernetes通过kubelet组件对Pod中的每个容器执行探针检查。当前提供了三种探针,它们在触发时机、行为后果和适用场景上存在本质区别:
| 维度 | 存活探针(livenessProbe) | 就绪探针(readinessProbe) | 启动探针(startupProbe) |
|---|---|---|---|
| 核心问题 | “容器是否正常运行?” | “容器是否准备好接收流量?” | “应用是否已启动完成?” |
| 探测失败后果 | kubelet杀死容器并触发重启(受restartPolicy影响) | 从所有关联Service的端点列表中移除该Pod IP | kubelet杀死容器并触发重启 |
| 探测成功后 | 持续监控容器健康状态 | 将Pod IP重新加入Service端点 | 激活liveness和readiness探针 |
| 典型使用场景 | 线程死锁、内存泄漏、JVM卡死 | 启动预热、依赖不可用、负载过高 | 启动时间超过60秒的慢启动应用 |
| 是否导致重启 | 是(失败后重启容器) | 否(仅控制流量路由) | 是(失败后重启容器) |
| 不配置默认值 | Success | Success | Success |
关键认知:
readinessProbe失败只影响流量分发,并不重启容器,依赖服务恢复后探针重新成功,Pod自动回到Service端点。反之,livenessProbe失败会导致容器被直接杀死并重建——这是一个破坏性操作,必须谨慎配置,确保探针只捕获真正的不可恢复错误。
3.3 启动探针的特殊地位
startupProbe与其他两种探针之间存在关键的互斥/抑制关系:如果配置了startupProbe,那么livenessProbe和readinessProbe都将被禁用,直到startupProbe首次成功执行完毕。这一特性至关重要,因为它解决了“慢启动应用被存活探针误杀”的经典问题:
无
startupProbe时:应用正在启动(可能需要60~120秒),但livenessProbe已在不断探测、积累失败次数,一旦达到failureThreshold,kubelet就会将容器杀死有
startupProbe时:在startupProbe成功之前,livenessProbe和readinessProbe被完全禁用;startupProbe可配置较长的failureThreshold,给予慢启动应用充足的初始化时间
因此,对于启动时间较长的应用(如大型Java Spring Boot服务、需要加载机器学习模型的服务),强烈建议同时配置三种探针,其中startupProbe的failureThreshold×periodSeconds应大于应用的最长启动时间。
3.4 三种检查方式深度对比
Kubernetes为每种探针提供了四种检查机制,本章聚焦于最常用的三种:
| 检查方式 | 原理描述 | 健康判定条件 | 适用场景 |
|---|---|---|---|
| httpGet | 向容器指定端口和路径发送HTTP/HTTPS GET请求 | 响应HTTP状态码在200~399范围内 | Web服务、REST API、带健康检查端点的应用 |
| tcpSocket | 尝试与容器指定端口建立TCP连接 | 三次握手成功建立连接 | 数据库、Redis、gRPC服务、自定义TCP协议的服务 |
| exec | 在容器内执行指定命令并检查退出状态码 | 命令退出状态码为0 | 所有类型应用,需要自定义复杂健康检查逻辑的场景 |
⚠️exec探针的成本警告:
exec探针的实现在每次探测时都需要在容器内创建/复制进程。在高Pod密度的集群中,如果periodSeconds设置过短,exec探针可能显著增加节点的CPU负载。建议在高负载场景优先使用httpGet或tcpSocket。
httpGet探针还支持额外的可选字段,其含义如下:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
scheme | string | HTTP | 连接方案(HTTP或HTTPS) |
host | string | Pod IP | 请求的主机名,默认使用Pod IP |
path | string | / | HTTP请求的URL路径 |
httpHeaders | []Object | 无 | 自定义HTTP请求头(列表) |
3.5 探针公共参数详解
所有三种探针和三种检查方式均共享以下公共参数:
| 参数 | 类型 | 默认值 | 说明 | 最小/最大值 |
|---|---|---|---|---|
initialDelaySeconds | int32 | 0 | 容器启动后等待多少秒再发起第一次探测 | ≥0 |
periodSeconds | int32 | 10 | 两次探测之间的间隔秒数 | ≥1 |
timeoutSeconds | int32 | 1 | 单次探测的超时秒数 | ≥1 |
failureThreshold | int32 | 3 | 连续失败多少次才判定为失败 | ≥1 |
successThreshold | int32 | 1 | 连续成功多少次才判定为成功 | ≥1(liveness/startup必须为1) |
失效时间窗口推导:可以推导容器被视为不健康的总耗时窗口如下:
失效确认时间 = failureThreshold × periodSeconds + timeoutSeconds×(failureThreshold)参数调优建议:
initialDelaySeconds:应设置为大于应用的实际启动时间。对于快速启动应用(如Nginx),可设置为5~15秒;对于Java服务,建议设置为30~60秒periodSeconds:生产环境中建议不低于5秒。过低会增加API Server和kubelet的负载timeoutSeconds:建议小于periodSeconds,避免探测请求堆积failureThreshold:存活探针建议3~5次,避免偶发网络抖动触发重启;启动探针可设置较高值(如30)以适应慢启动应用
3.6 httpGet探针示例详解
回到本章YAML示例中的配置:
startupProbe: httpGet: path: /healthz # 向容器发送 GET /healthz 请求 port: 80 # 目标端口80 scheme: HTTP # 使用HTTP协议 initialDelaySeconds: 10 # 容器启动后等10秒 periodSeconds: 10 # 每10秒探测一次 timeoutSeconds: 3 # 单次探测超时3秒 failureThreshold: 30 # 连续失败30次才判定失败 successThreshold: 1 # 成功1次即视为启动完成此配置的含义为:容器启动10秒后,kubelet开始每10秒向Pod的80端口发送GET /healthz请求;如果HTTP响应的状态码在200~399之间(即2xx或3xx),记为一次成功;只要成功1次,即视为启动完成,随后liveness和readiness探针被激活;如果连续30次(即30×10秒=300秒窗口)探测均失败,则kubelet判定容器启动失败,杀死容器并根据重启策略重启。
该设计适用于启动时间较长但非极端的应用(例如启动时间在60~240秒区间内)。
3.7 tcpSocket探针示例
对于不暴露HTTP接口的数据库类服务(如PostgreSQL、MySQL、Redis),tcpSocket是最自然的选择:
livenessProbe: tcpSocket: port: 5432 # 尝试在端口5432建立TCP连接 initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 3 readinessProbe: tcpSocket: port: 5432 # 就绪探测使用相同的TCP端口检查 initialDelaySeconds: 5 periodSeconds: 5kubelet将尝试与Pod IP的端口5432进行TCP三次握手。只要TCP连接建立成功(即服务器端口开放并监听),即判定为健康。
3.8 exec探针示例
exec探针是灵活度最高的检查方式,适合需要复杂业务逻辑的健康检查(代码摘选自Kubernetes官方文档示例):
livenessProbe: exec: command: - cat - /tmp/healthy # 检查/tmp/healthy文件是否存在 initialDelaySeconds: 5 periodSeconds: 5 failureThreshold: 3该探针在容器内执行cat /tmp/healthy命令。若文件存在且读取成功,命令退出码为0,判定为健康;若文件被删除(如某些健康检测脚本会在异常时清除状态文件),命令返回非零码,判定为失败。系统内可通过配合启动脚本控制该文件的存在与否,从而间接控制探针结果。
⚠️ 请注意:若执行的探测命令是Shell脚本,必须显式指定Shell解析器,例如
sh /data/scripts/health_check.sh,而不能直接指定脚本路径。
第四部分:openEuler 24.03 SP3环境下的实战部署
4.1 系统环境说明
参考openEuler官方文档及社区实践所述,本教程的部署环境基于openEuler 24.03 LTS SP3操作系统,Kubernetes v1.28,容器运行时为containerd。openEuler 24.03 LTS SP3是华为主导的开源Linux发行版,“24.03 LTS SP3”代表2024年3月发布的长期支持版第3次服务包更新,适配x86与鲲鹏等国产硬件架构,稳定性强,适合企业级部署与学习场景。
4.2 环境前置条件(checklist)
在部署之前,确保已经完成以下所有前置步骤(详见本系列第二篇文章):
[ ] 关闭防火墙(systemctl disable --now firewalld)
[ ] 关闭SELinux(setenforce 0,并修改/etc/selinux/config永久关闭)
[ ] 关闭Swap交换空间(swapoff -a,并注释/etc/fstab中的swap行)
[ ] 配置主机名和/etc/hosts文件
[ ] 启用内核IP转发参数(net.ipv4.ip_forward=1)
[ ] 安装并启动containerd容器运行时
[ ] 安装kubeadm、kubelet、kubectl组件
[ ] 使用kubeadm完成集群初始化
[ ] 部署CNI网络插件(Calico或Flannel)
[ ] Worker节点已加入集群
验证集群状态:
# 检查所有节点是否均已处于Ready状态 kubectl get nodes # 检查kube-system命名空间下所有系统Pod是否正常运行 kubectl get pods -n kube-system预期输出中所有节点STATUS应为Ready,所有系统Pod的READY应为1/1且STATUS为Running。
4.3 部署第一个Deployment
将本章第二部分给出的完整YAML保存为nginx-production-deployment.yaml,然后执行以下命令:
kubectl apply -f nginx-production-deployment.yaml命令行说明:
kubectl apply -f命令读取指定的YAML文件,通过API Server将资源定义写入etcd。若该资源已存在,则以声明式方式更新现有配置;若尚未创建,则新建资源。这是Kubernetes推荐的标准管理方式。
预期输出:
deployment.apps/nginx-production created4.4 验证部署状态
4条命令即可快速检查Deployment全貌,各条命令用途如下:
1) 查看Deployment状态:
kubectl get deployment nginx-production输出解读:
NAME READY UP-TO-DATE AVAILABLE AGE nginx-production 3/3 3 3 45sREADY 3/3:3个期望副本全部就绪UP-TO-DATE 3:3个Pod已更新到最新版本AVAILABLE 3:3个Pod已就绪超过minReadySeconds时间
2) 查看ReplicaSet:
kubectl get rs -l app=nginx-production此命令通过标签筛选输出,可确认Deployment创建的ReplicaSet及其副本数状态。
3) 查看所有Pod及探针计时器初始化情况:
kubectl get pods -l app=nginx-production注意Pod名称格式为nginx-production-<ReplicaSet哈希>-<随机后缀>,这是由ReplicaSet自动生成的唯一标识符。
4) 查看某个Pod的详细描述(含探针配置及其当前状态):
kubectl describe pod <pod-name>在输出的Containers.nginx部分,可看到探针配置的完整回显及各探针的延迟参数、失败计数等信息。
# 便捷写法——直接获取Pod名并传入describe: kubectl describe pod "$(kubectl get pods -l app=nginx-production -o jsonpath='{.items[0].metadata.name}')"4.5 查看Pod内部健康检查端点
对于httpGet探针,可以直接在所有节点上使用curl测试健康检查端点是否正常响应(注意Pod内不一定安装curl,以下命令在其所在节点上执行):
# 获取Pod IP kubectl get pod <pod-name> -o wide # 在集群节点上测试存活探针端点 curl -v http://<Pod-IP>/healthz # 测试就绪探针端点 curl -v http://<Pod-IP>/readyNginx默认不提供/healthz和/ready端点,因此在生产环境中需要配置Nginx返回这些路径。对于学习和测试,可通过进入Pod添加自定义配置,或使用支持内置健康检查端点的镜像(如各类微服务框架的应用镜像)。
4.6 验证探针行为
场景一——就绪探针测试:如果/ready端点返回非2xx/3xx状态码,Pod的READY列将显示0/1,且Service将不再向该Pod发送流量(Pod仍然Running,仅接收流量的条件被关闭):
# 就绪探针失败后查看Pod状态 kubectl get pods -l app=nginx-production -w场景二——存活探针重启测试:如果/healthz端点返回失败,连续失败次数达到failureThreshold后,Pod的RESTARTS计数将增加,且STATUS会经历短暂的Error→Running状态变迁:
kubectl get pods -l app=nginx-production # 观察RESTARTS列的变化4.7 滚动更新实战
更新镜像版本为nginx:1.25.4:
kubectl set image deployment/nginx-production nginx=nginx:1.25.4命令解析:
kubectl set image deployment/<Deployment名称> <容器名称>=<新镜像>直接更新指定Deployment中指定容器的镜像版本,无需手动编辑YAML文件。此命令会触发Deployment控制器的滚动更新流程。
监控滚动更新进度:
kubectl rollout status deployment/nginx-production预期输出:
Waiting for deployment "nginx-production" rollout to finish: 1 out of 3 new replicas have been updated... Waiting for deployment "nginx-production" rollout to finish: 2 out of 3 new replicas have been updated... deployment "nginx-production" successfully rolled out查看更新历史版本:
kubectl rollout history deployment/nginx-production此命令列出Deployment的所有历史REVISION及其对应的镜像变更记录。
4.8 版本回滚操作
回滚到上一稳定版本:
kubectl rollout undo deployment/nginx-production命令解析:
kubectl rollout undo deployment/<Deployment名>自动将Deployment恢复到上一个历史ReplicaSet的配置状态,包括镜像版本、环境变量等所有Pod模板内容。
回滚到指定的历史版本(先查看历史记录,获取REVISION编号):
kubectl rollout undo deployment/nginx-production --to-revision=24.9 查看实时日志
kubectl logs -f deployment/nginx-production命令解析:
kubectl logs -f deployment/<Deployment名>以follow模式实时查看该Deployment下所有Pod的日志流(控制台合并输出)。若Deployment有多个副本,此命令会从其中一个Pod流式输出。
若Pod中不存在curl但需要执行临时网络调试,可启动一个临时容器:
kubectl run debug-pod --image=busybox:1.28 --rm -it --restart=Never -- sh第五部分:Deployment进阶话题
5.1 资源限制优化(Guaranteed/ Burstable/Best-Effort QoS类)
Kubernetes根据Pod中容器设置的resources.requests和resources.limits为Pod分配三种QoS(Quality of Service)等级:
Guaranteed:每个容器的CPU和内存都设置了
requests和limits,且两者数值相等(requests == limits)。Guaranteed Pod具有最高优先级,在节点资源紧张时最不容易被驱逐。Burstable:至少一个容器设置了
requests,但requests与limits不完全相等。Burstable Pod具有中等优先级。Best-Effort:未设置任何
requests和limits。Best-Effort Pod优先级最低,节点资源紧张时会被首先驱逐。
生产环境中建议使用Burstable或Guaranteed,以实现更稳定的服务质量。
5.2 revisionHistoryLimit的运维意义
revisionHistoryLimit控制了历史ReplicaSet的保留数量,直接影响可回滚的版本数。如果该值设为0,所有历史ReplicaSet将被清理,kubectl rollout undo将彻底失效。在频繁更新的CI/CD流水线中,建议将revisionHistoryLimit设置为10~20,以在存储开销与回滚能力之间取得平衡。
5.3 批量重启Pod(使用rollout restart)
在某些场景下(如ConfigMap更新后需要重新加载配置,或在开发/测试环境中快速测试),可能需要在不修改任何YAML内容的前提下统一重启Deployment管理的所有Pod。
传统做法需要首先触发滚动更新(如修改环境变量),而这会在Deployment历史中留下一条无意义的变更记录。自Kubernetes v1.15起,引入了一条更干净的指令:
kubectl rollout restart deployment/nginx-production命令解析:
kubectl rollout restart deployment/<Deployment名>通过为Pod模板注入一个时间戳注解,触发一次滚动更新,所有Pod将按顺序被重建。该操作会引起短暂的服务中断(视maxUnavailable参数而定),但只需一条命令、不影响回滚历史,在运维中极为常用。
5.4 水平自动扩缩容(HPA)简介
Deployment支持通过Horizontal Pod Autoscaler(HPA)实现基于CPU/内存利用率的自动扩缩容。以下命令创建一个HPA,使Deployment在CPU达到50%时在3~10个副本之间动态扩展:
kubectl autoscale deployment nginx-production --min=3 --max=10 --cpu-percent=50命令解析:
kubectl autoscale deployment命令根据指定的最小/最大副本数和目标CPU使用率,自动创建HorizontalPodAutoscaler资源。HPA控制器会定期查询Metrics API获取Pod的CPU指标,并据此计算期望副本数。
5.5 生产环境探针最佳实践总结
务必配置三种探针:生产环境中所有Pod均应配置健康检查。至少配置
readinessProbe和livenessProbe;启动时间较长的应用还需添加startupProbe。就绪探针应包含依赖检查:如果应用依赖数据库、Redis、消息队列等外部服务,
readinessProbe应能真实反映这些依赖的可用性——依赖不可用时标记为未就绪,等待依赖恢复后流量自动恢复,而非重启容器。存活探针应仅检查自身状态:
livenessProbe只应检查容器自身的内部状态(如死锁、死循环等不可恢复错误)。不要将外部依赖的可用性纳入livenessProbe——外部依赖不可用不应导致容器重启。启动探针应足够宽松:
startupProbe的failureThreshold×periodSeconds必须大于应用的最长启动时间。对于启动时间不确定的应用,宁可配置更长的窗口,也不要冒险误杀。为探针设置合理的资源开销:
periodSeconds不宜低于5秒;exec探针在高密度集群中应谨慎使用。配合preStop钩子实现优雅下线:
terminationGracePeriodSeconds应大于preStop钩子的执行时间,确保容器有足够时间完成清理工作(如关闭数据库连接、完成正在处理的请求等)。
结语
本文以openEuler 24.03 LTS SP3为运行环境,从Deployment的控制器模式原理出发,深入讲解了Deployment YAML清单的全部核心字段(包括apiVersion/kind/metadata/spec/strategy/template及其子字段),同时结合三种Pod探针的类型区分、检查机制与参数调优,给出了可直接应用于生产环境的完整配置示例。通过将理论原理与逐字段注释相结合,读者应当能够扎实掌握Deployment与Pod探针的核心概念,并构建起从环境初始化到应用部署、探针验证、实时监控、滚动更新与版本回滚的完整操作闭环。
Kubernetes的Deployment控制器与Pod探针机制是构建云原生应用的基石。掌握这些知识后,读者将有能力在生产环境中自信地部署、监控和维护无状态应用,为后续学习Service流量调度、Ingress路由规则、ConfigMap/Secret配置注入、StatefulSet有状态编排等更深层次的云原生技术打下坚实基础。