Deployment滚动更新 + Scheduler调度算法 + HPA水平自动伸缩 + Pod生命周期 · SVG可视化
| 策略 | 类比 | 行为 | 适用场景 |
|---|---|---|---|
| RollingUpdate | 老员工培训新员工 | 逐步替换,先增后删,零停机 | Web服务、API(默认策略) |
| Recreate | 全部换血 | 先删所有旧Pod,再创建新Pod | 不能同时运行两个版本(如数据库迁移) |
kubectl rollout undo deployment/my-app 可以回滚到上一版本!K8s为每个Deployment保留历史修订(revisionHistoryLimit),回滚就是切换到旧ReplicaSet。
| 探针 | 类比 | 失败后果 | 检测方式 | 适用场景 |
|---|---|---|---|---|
| Startup | 入职体检 | 重启容器 | HTTP/TCP/Exec | 慢启动应用(JVM预热) |
| Liveness | 日常体检 | 重启容器 | HTTP/TCP/Exec | 检测死锁/僵死 |
| Readiness | 能否接活 | 从Service摘除 | HTTP/TCP/Exec | 保证新Pod就绪 |
Deployment通过ReplicaSet管理Pod。更新image时,创建新ReplicaSet(v2),按RollingUpdate策略逐步增加新Pod、减少旧Pod。
maxSurge:超出期望 replicas 的最大 Pod 数(默认25%)。值越大,更新越快但消耗资源越多。
maxUnavailable:更新期间允许不可用的最大 Pod 数(默认25%)。值越大更新越快但可用性越低。
极端配置:maxSurge=0,maxUnavailable=100% → Recreate策略(先全删再全建)。maxSurge=100%,maxUnavailable=0 → 蓝绿部署效果。
预选(Predicates):硬性过滤,排除不满足条件的Node。包括:PodFitsResources(资源够不够)、PodFitsHostPorts(端口冲不冲突)、PodMatchNodeSelector(标签匹不匹配)、CheckNodeUnschedulable(是否可调度)、TaintToleration(污点容忍)。
优选(Priorities):对通过预选的Node打分排名。包括:SelectorSpreadPriority(Pod分散)、InterPodAffinityPriority(Pod亲和)、LeastRequestedPriority(资源均衡)、NodeAffinityPriority(Node亲和)、ImageLocalityPriority(镜像本地)。
最终选择得分最高的Node绑定Pod。
扩容公式:desiredReplicas = ceil(currentReplicas × currentMetricValue / desiredMetricValue)
例如:3个Pod,CPU当前75%,目标50% → ceil(3 × 75/50) = ceil(4.5) = 5个Pod。
缩容有冷却时间(默认5分钟),防止"抖动"——流量短暂下降就缩容,流量回来又要扩容,反复折腾。冷却期内即使指标低于阈值也不缩容。
Startup Probe:判断容器是否启动完成。用于慢启动应用(如JVM需要预热),在Startup Probe成功前不会执行Liveness和Readiness。
Liveness Probe:判断容器是否还活着。失败→重启容器。用于检测死锁、僵死。注意:不要检查外部依赖(DB/Redis),否则外部挂了会反复重启容器。
Readiness Probe:判断容器是否准备好接收流量。失败→从Service的Endpoints摘除,不重启。用于滚动更新时保证新Pod就绪后才接流量。
nodeAffinity:Pod对Node的偏好——"我想去哪个Node"。基于Node的Label选择,如zone=east、gpu=true。
podAffinity:Pod对Pod的偏好——"我想和谁在同一个Node"。如前端Pod和后端Pod放在一起降低延迟。
podAntiAffinity:Pod对Pod的反感——"我不想和谁在同一个Node"。如同一Deployment的Pod分散到不同Node,避免单点故障。
每种都分required(硬性)和preferred(软性)两种约束。
Taint打在Node上,标记"这个Node有特殊属性"。格式:key=value:effect。
Toleration写在Pod上,声明"我能容忍这个Taint"。
3种effect:
• NoSchedule:只影响调度,已运行的Pod不驱逐
• PreferNoSchedule:尽量不调度,但不保证
• NoExecute:不调度+驱逐已有Pod
典型用法:Master节点打Taint node-role.kubernetes.io/master:NoSchedule,防止普通Pod调度到Master。
Always(默认):容器退出就重启。Deployment/StatefulSet/DaemonSet都用Always。
OnFailure:只有失败(非0退出码)才重启。Job用OnFailure,成功的Pod不需要重启。
Never:从不重启。某些Job用Never,失败后由Job Controller重新创建Pod。
注意:restartPolicy作用于Pod内的所有容器。重启次数有限制(Back-off: 10s→20s→40s→...最长5min)。
零停机部署需要3个条件:
1. Readiness Probe:新Pod只有通过Readiness检查才加入Service Endpoints,确保不会把流量打到未就绪的Pod。
2. preStop Hook:Pod终止前先从Service Endpoints摘除,等待已有请求处理完(graceful shutdown)。设置 terminationGracePeriodSeconds: 30。
3. 滚动更新策略:maxSurge≥1, maxUnavailable=0,保证先增后删,始终有足够的Pod在服务。
kubectl rollout undo deployment/my-app → 回滚到上一版本
kubectl rollout undo deployment/my-app --to-revision=2 → 回滚到指定版本
kubectl rollout history deployment/my-app → 查看所有修订版本
kubectl rollout status deployment/my-app → 查看当前更新状态
kubectl rollout pause deployment/my-app → 暂停更新(金丝雀发布)
原理:Deployment保留旧的ReplicaSet(revisionHistoryLimit个),回滚就是把旧RS的replicas恢复。
HPA(v2)支持3类指标:
1. Resource:CPU/内存利用率(最常用,需安装Metrics Server)
2. Pods:Pod自定义指标(如每秒请求数QPS),需Prometheus Adapter
3. Object/External:外部指标(如消息队列长度、Redis连接数),需Custom Metrics API
实际生产中常见:基于QPS扩缩容比CPU更精确(CPU可能因为GC等原因偏高但QPS并不高)。
K8s部署调度三原则:① Deployment 管 Pod 副本数,rollingUpdate 实现零停机 → ② nodeSelector/Affinity/Taint 控制调度,让 Pod 去到正确的 Node → ③ HPA 按 CPU/内存自动扩缩,别忘配 resources requests