05-发布与弹性
Kubernetes 滚动更新、HPA/VPA、探针管理全解析
学习目标
通过本模块学习,你将掌握:
- Kubernetes 发布策略和滚动更新
- HPA 和 VPA 自动扩缩容机制
- 探针管理和健康检查
- 蓝绿部署和金丝雀发布
- 弹性伸缩故障排查技能
一、发布策略概览
发布策略对比
策略 | 特点 | 适用场景 | 风险等级 |
---|---|---|---|
RollingUpdate | 逐步替换,零停机 | 无状态应用 | 低 |
Blue/Green | 全量切换 | 有状态应用 | 中 |
Canary | 灰度发布 | 新功能发布 | 低 |
Recreate | 先删除后创建 | 开发测试 | 高 |
发布策略选择
graph TD
A[应用类型] --> B{有状态?}
B -->|是| C[Blue/Green]
B -->|否| D{需要灰度?}
D -->|是| E[Canary]
D -->|否| F[RollingUpdate]
C --> G[生产环境]
E --> G
F --> G
二、滚动更新(RollingUpdate)
2.1 滚动更新原理
特点:逐步替换 Pod,确保服务不中断
graph TD
A[开始更新] --> B[创建新 Pod]
B --> C[等待新 Pod Ready]
C --> D[删除旧 Pod]
D --> E{还有旧 Pod?}
E -->|是| B
E -->|否| F[更新完成]
2.2 Deployment 滚动更新
基本配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 最大不可用数量
maxSurge: 1 # 最大超出数量
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
更新参数说明
- maxUnavailable:更新过程中最大不可用 Pod 数量
- maxSurge:更新过程中最大超出期望副本数
- readinessProbe:确保新 Pod 就绪后再删除旧 Pod
2.3 滚动更新控制
更新命令
# 更新镜像
kubectl set image deployment/web-deployment nginx=nginx:1.21
# 查看更新状态
kubectl rollout status deployment/web-deployment
# 查看更新历史
kubectl rollout history deployment/web-deployment
# 回滚到上一版本
kubectl rollout undo deployment/web-deployment
# 回滚到指定版本
kubectl rollout undo deployment/web-deployment --to-revision=2
暂停和恢复更新
# 暂停更新
kubectl rollout pause deployment/web-deployment
# 恢复更新
kubectl rollout resume deployment/web-deployment
2.4 滚动更新最佳实践
1. 配置合理的探针
spec:
containers:
- name: app
image: app:v2
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
2. 设置合理的更新参数
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25% # 百分比形式
maxSurge: 25% # 百分比形式
3. 使用 PodDisruptionBudget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web
三、蓝绿部署(Blue/Green)
3.1 蓝绿部署原理
特点:维护两套完全相同的生产环境
graph TD
A[蓝环境 v1] --> B[部署绿环境 v2]
B --> C[测试绿环境]
C --> D[切换流量到绿环境]
D --> E[绿环境 v2 生产]
E --> F[删除蓝环境 v1]
3.2 蓝绿部署实现
使用 Service 切换
# 蓝环境
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-blue
spec:
replicas: 3
selector:
matchLabels:
app: web
version: blue
template:
metadata:
labels:
app: web
version: blue
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
---
# 绿环境
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-green
spec:
replicas: 3
selector:
matchLabels:
app: web
version: green
template:
metadata:
labels:
app: web
version: green
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
---
# Service 切换
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
version: blue # 切换到 green 实现蓝绿切换
ports:
- port: 80
targetPort: 80
切换脚本
#!/bin/bash
# 蓝绿切换脚本
CURRENT_VERSION=$(kubectl get svc web-service -o jsonpath='{.spec.selector.version}')
if [ "$CURRENT_VERSION" = "blue" ]; then
NEW_VERSION="green"
else
NEW_VERSION="blue"
fi
echo "当前版本: $CURRENT_VERSION"
echo "切换到: $NEW_VERSION"
# 更新 Service 选择器
kubectl patch svc web-service -p '{"spec":{"selector":{"version":"'$NEW_VERSION'"}}}'
# 等待切换完成
kubectl rollout status deployment/web-$NEW_VERSION
echo "切换完成!"
四、金丝雀发布(Canary)
4.1 金丝雀发布原理
特点:逐步将流量切换到新版本
graph TD
A[100% 流量到 v1] --> B[部署 v2 副本]
B --> C[10% 流量到 v2]
C --> D[监控指标]
D --> E{指标正常?}
E -->|是| F[50% 流量到 v2]
E -->|否| G[回滚到 v1]
F --> H[100% 流量到 v2]
G --> A
H --> I[删除 v1]
4.2 使用 Argo Rollouts 实现
安装 Argo Rollouts
# 安装 Argo Rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# 安装 kubectl 插件
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x kubectl-argo-rollouts-linux-amd64
sudo mv kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
金丝雀发布配置
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: web-rollout
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 10m}
- setWeight: 40
- pause: {duration: 10m}
- setWeight: 60
- pause: {duration: 10m}
- setWeight: 80
- pause: {duration: 10m}
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
金丝雀发布操作
# 更新镜像触发金丝雀发布
kubectl argo rollouts set image web-rollout nginx=nginx:1.21
# 查看发布状态
kubectl argo rollouts get rollout web-rollout
# 手动推进到下一步
kubectl argo rollouts promote web-rollout
# 中止发布
kubectl argo rollouts abort web-rollout
五、HPA 自动扩缩容
5.1 HPA 工作原理
HPA(Horizontal Pod Autoscaler) 根据指标自动调整 Pod 副本数量
graph TD
A[监控指标] --> B[HPA Controller]
B --> C[计算期望副本数]
C --> D[调整 Deployment 副本数]
D --> E[Pod 扩缩容]
E --> F[指标变化]
F --> A
5.2 HPA 配置示例
基于 CPU 的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
基于内存的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa-memory
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
基于自定义指标的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa-custom
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "10"
5.3 HPA 行为控制
扩缩容行为配置
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa-behavior
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
minReplicas: 2
maxReplicas: 10
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
5.4 HPA 命令操作
# 创建 HPA
kubectl apply -f hpa.yaml
# 查看 HPA 状态
kubectl get hpa
kubectl describe hpa web-hpa
# 手动扩缩容
kubectl scale deployment web-deployment --replicas=5
# 删除 HPA
kubectl delete hpa web-hpa
六、VPA 垂直扩缩容
6.1 VPA 工作原理
VPA(Vertical Pod Autoscaler) 自动调整 Pod 的资源请求和限制
graph TD
A[监控资源使用] --> B[VPA Recommender]
B --> C[计算推荐资源]
C --> D[VPA Updater]
D --> E[更新 Pod 资源]
E --> F[重启 Pod]
F --> G[资源使用变化]
G --> A
6.2 VPA 安装配置
安装 VPA
# 安装 VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler/
./hack/vpa-install.sh
VPA 配置示例
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
updatePolicy:
updateMode: "Off" # Off/Auto/Initial
resourcePolicy:
containerPolicies:
- containerName: nginx
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 1000m
memory: 1Gi
VPA 模式说明
模式 | 说明 | 适用场景 |
---|---|---|
Off | 只提供建议,不自动更新 | 生产环境推荐 |
Auto | 自动更新资源并重启 Pod | 开发测试环境 |
Initial | 仅在 Pod 创建时设置资源 | 新应用部署 |
6.3 VPA 命令操作
# 创建 VPA
kubectl apply -f vpa.yaml
# 查看 VPA 状态
kubectl get vpa
kubectl describe vpa web-vpa
# 查看推荐资源
kubectl get vpa web-vpa -o yaml | grep -A 20 recommendation
# 删除 VPA
kubectl delete vpa web-vpa
七、探针管理
7.1 探针类型
探针类型 | 作用 | 失败后果 |
---|---|---|
livenessProbe | 检测容器是否存活 | 重启容器 |
readinessProbe | 检测容器是否就绪 | 从 Service 移除 |
startupProbe | 检测容器是否启动完成 | 重启容器 |
7.2 探针配置示例
HTTP 探针
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /health
port: 80
httpHeaders:
- name: Custom-Header
value: "health-check"
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /startup
port: 80
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 30
TCP 探针
apiVersion: v1
kind: Pod
metadata:
name: tcp-pod
spec:
containers:
- name: app
image: app:latest
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
命令探针
apiVersion: v1
kind: Pod
metadata:
name: cmd-pod
spec:
containers:
- name: app
image: app:latest
livenessProbe:
exec:
command:
- /bin/sh
- -c
- "ps aux | grep app | grep -v grep"
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- /bin/sh
- -c
- "curl -f http://localhost:8080/health || exit 1"
initialDelaySeconds: 5
periodSeconds: 5
7.3 探针最佳实践
1. 合理设置探针参数
# 启动慢的应用
startupProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 30 # 5分钟超时
# 健康检查
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
# 就绪检查
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
2. 探针端点设计
// 健康检查端点
func healthHandler(w http.ResponseWriter, r *http.Request) {
// 检查应用状态
if isHealthy() {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
} else {
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte("Unhealthy"))
}
}
// 就绪检查端点
func readyHandler(w http.ResponseWriter, r *http.Request) {
// 检查依赖服务
if isReady() {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Ready"))
} else {
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte("Not Ready"))
}
}
️ 八、命令速记
发布相关命令
# 更新镜像
kubectl set image deployment/web-deployment nginx=nginx:1.21
# 查看发布状态
kubectl rollout status deployment/web-deployment
# 查看发布历史
kubectl rollout history deployment/web-deployment
# 回滚
kubectl rollout undo deployment/web-deployment
kubectl rollout undo deployment/web-deployment --to-revision=2
# 暂停/恢复
kubectl rollout pause deployment/web-deployment
kubectl rollout resume deployment/web-deployment
扩缩容命令
# 手动扩缩容
kubectl scale deployment web-deployment --replicas=5
# 查看 HPA
kubectl get hpa
kubectl describe hpa web-hpa
# 查看 VPA
kubectl get vpa
kubectl describe vpa web-vpa
# 查看 Pod 资源使用
kubectl top pods
kubectl top nodes
探针相关命令
# 查看 Pod 状态
kubectl get pods
kubectl describe pod <pod-name>
# 查看事件
kubectl get events --sort-by=.lastTimestamp
# 测试探针
kubectl exec <pod-name> -- curl http://localhost:8080/health
九、面试核心问答
Q1: 滚动更新的原理是什么?
答案要点:
- 逐步替换 Pod,确保服务不中断
- 通过 readinessProbe 确保新 Pod 就绪
- 通过 maxUnavailable 和 maxSurge 控制更新速度
- 支持暂停、恢复和回滚
Q2: HPA 和 VPA 的区别?
答案要点:
- HPA:水平扩缩容,调整 Pod 数量
- VPA:垂直扩缩容,调整 Pod 资源
- HPA:适用于无状态应用
- VPA:适用于有状态应用
Q3: 探针的作用和区别?
答案要点:
- livenessProbe:检测容器存活,失败重启
- readinessProbe:检测容器就绪,失败移除
- startupProbe:检测容器启动,失败重启
- 合理配置探针确保应用健康
Q4: 如何实现零停机发布?
答案要点:
- 使用滚动更新策略
- 配置 readinessProbe
- 设置 PodDisruptionBudget
- 监控发布过程
Q5: 金丝雀发布的优势?
答案要点:
- 逐步验证新版本
- 降低发布风险
- 支持快速回滚
- 适合新功能发布
十、故障排查
常见发布问题
1. 滚动更新卡住
# 查看更新状态
kubectl rollout status deployment/web-deployment
# 查看 Pod 状态
kubectl get pods -l app=web
# 查看事件
kubectl get events --sort-by=.lastTimestamp
# 检查探针
kubectl describe pod <pod-name>
2. HPA 不工作
# 检查 HPA 状态
kubectl describe hpa web-hpa
# 检查 metrics-server
kubectl get pods -n kube-system -l k8s-app=metrics-server
# 检查资源指标
kubectl top pods
kubectl top nodes
# 检查 HPA 日志
kubectl logs -n kube-system -l app=horizontal-pod-autoscaler
3. 探针失败
# 查看 Pod 状态
kubectl describe pod <pod-name>
# 检查探针配置
kubectl get pod <pod-name> -o yaml | grep -A 20 probes
# 测试探针端点
kubectl exec <pod-name> -- curl http://localhost:8080/health
# 查看应用日志
kubectl logs <pod-name>
4. VPA 不生效
# 检查 VPA 状态
kubectl describe vpa web-vpa
# 查看推荐资源
kubectl get vpa web-vpa -o yaml | grep -A 20 recommendation
# 检查 VPA 组件
kubectl get pods -n kube-system -l app=vpa-recommender
kubectl get pods -n kube-system -l app=vpa-updater
十一、最佳实践
发布策略建议
滚动更新
- 配置合理的探针
- 设置合适的更新参数
- 使用 PodDisruptionBudget
蓝绿部署
- 维护两套环境
- 使用 Service 切换流量
- 自动化切换脚本
金丝雀发布
- 使用 Argo Rollouts
- 配置监控指标
- 支持快速回滚
扩缩容建议
HPA 配置
- 合理设置扩缩容阈值
- 配置扩缩容行为
- 监控扩缩容效果
VPA 配置
- 生产环境使用 Off 模式
- 设置资源限制
- 定期审查推荐值
探针建议
探针设计
- 实现独立的健康检查端点
- 区分存活和就绪检查
- 合理设置探针参数
监控告警
- 监控探针失败率
- 设置告警规则
- 建立故障处理流程
十二、总结
通过本模块学习,你已经掌握了:
- Kubernetes 发布策略和滚动更新
- HPA 和 VPA 自动扩缩容机制
- 探针管理和健康检查
- 蓝绿部署和金丝雀发布
- 弹性伸缩故障排查技能
- 发布和扩缩容最佳实践
下一步建议:继续学习 06-安全与治理,深入了解 Kubernetes 安全机制和治理策略。