HiHuo
首页
博客
手册
工具
首页
博客
手册
工具
  • Kubernetes 进阶

    • /books/k8s/
    • Kubernetes 高阶学习手册
    • 01-架构与核心概念
    • 02-网络体系
    • 03-存储管理
    • 04-调度控制
    • 05-发布与弹性
    • 06-安全与治理
    • 07-观测与SRE
    • 08-可靠性运维
    • 09-成本与容量
    • 10-故障排查
    • 11-运维工具
    • 12-生产清单
    • 13-AI平台集成

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

十一、最佳实践

发布策略建议

  1. 滚动更新

    • 配置合理的探针
    • 设置合适的更新参数
    • 使用 PodDisruptionBudget
  2. 蓝绿部署

    • 维护两套环境
    • 使用 Service 切换流量
    • 自动化切换脚本
  3. 金丝雀发布

    • 使用 Argo Rollouts
    • 配置监控指标
    • 支持快速回滚

扩缩容建议

  1. HPA 配置

    • 合理设置扩缩容阈值
    • 配置扩缩容行为
    • 监控扩缩容效果
  2. VPA 配置

    • 生产环境使用 Off 模式
    • 设置资源限制
    • 定期审查推荐值

探针建议

  1. 探针设计

    • 实现独立的健康检查端点
    • 区分存活和就绪检查
    • 合理设置探针参数
  2. 监控告警

    • 监控探针失败率
    • 设置告警规则
    • 建立故障处理流程

十二、总结

通过本模块学习,你已经掌握了:

  • Kubernetes 发布策略和滚动更新
  • HPA 和 VPA 自动扩缩容机制
  • 探针管理和健康检查
  • 蓝绿部署和金丝雀发布
  • 弹性伸缩故障排查技能
  • 发布和扩缩容最佳实践

下一步建议:继续学习 06-安全与治理,深入了解 Kubernetes 安全机制和治理策略。

Prev
04-调度控制
Next
06-安全与治理