蓝绿部署与金丝雀发布实战:Kubernetes流量切换与自动回滚策略

蓝绿部署金丝雀发布是DevOps实践中两种核心的零停机发布策略。在Kubernetes容器编排环境下,通过Service资源与多版本Deployment的配合,可以实现流量在版本间的精确切换。蓝绿部署适合需要快速回滚的场景,金丝雀发布适合需要渐进式验证的场景。两者结合健康检查与自动回滚机制,能够将发布事故的影响范围控制在最小。

蓝绿部署原理与Kubernetes实现方式

蓝绿部署维护两套完全相同的环境(Blue和Green),任意时刻只有一个环境接收生产流量。发布时将新版本部署到非活动环境,验证通过后通过Service的selector切换流量,旧版本保留作为回滚备份。

Kubernetes中蓝绿部署的实现方式:

# blue-deployment.yaml - 当前生产版本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
  labels:
    app: webapp
    version: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
      version: blue
  template:
    metadata:
      labels:
        app: webapp
        version: blue
    spec:
      containers:
      - name: webapp
        image: registry.yunthe.com/webapp:v1.2
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
# green-deployment.yaml - 新版本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
  labels:
    app: webapp
    version: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
      version: green
  template:
    metadata:
      labels:
        app: webapp
        version: green
    spec:
      containers:
      - name: webapp
        image: registry.yunthe.com/webapp:v1.3
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10

Service通过selector指向当前活动版本,切换时只需修改selector中的version标签:

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  selector:
    app: webapp
    version: blue    # 切换到green即完成发布
  ports:
  - port: 80
    targetPort: 8080
# 执行蓝绿切换
kubectl apply -f green-deployment.yaml
# 等待green环境所有Pod就绪
kubectl rollout status deployment/app-green

# 验证green环境(通过临时Service或端口转发)
kubectl port-forward svc/webapp-service-green 8080:80

# 确认无误后切换流量
kubectl patch svc webapp-service -p '{"spec":{"selector":{"version":"green"}}}'

# 如需回滚,切回blue
kubectl patch svc webapp-service -p '{"spec":{"selector":{"version":"blue"}}}'

金丝雀发布的流量分割策略配置

金丝雀发布将新版本逐步暴露给部分用户,通过监控指标判断是否继续扩大流量比例。Kubernetes原生支持通过调整新旧Deployment的副本数实现粗粒度的流量分割。

#!/bin/bash
# 金丝雀发布脚本 - 逐步增加新版本流量比例

NAMESPACE="production"
DEPLOYMENT="webapp"
NEW_VERSION="v1.3"
STAGES=(10 25 50 100)
HEALTH_CHECK_URL="http://webapp-service/health"

for percentage in "${STAGES[@]}"; do
    echo "=== 金丝雀阶段: ${percentage}% ==="

    TOTAL=10
    NEW_REPLICAS=$((TOTAL * percentage / 100))
    OLD_REPLICAS=$((TOTAL - NEW_REPLICAS))

    kubectl scale deployment/${DEPLOYMENT}-canary --replicas=${NEW_REPLICAS} -n ${NAMESPACE}
    kubectl scale deployment/${DEPLOYMENT}-stable --replicas=${OLD_REPLICAS} -n ${NAMESPACE}

    kubectl rollout status deployment/${DEPLOYMENT}-canary -n ${NAMESPACE}

    echo "观察期 120 秒..."
    sleep 120

    ERROR_RATE=$(curl -s "${HEALTH_CHECK_URL}/metrics" | grep error_rate | awk '{print $2}')

    if (( $(echo "${ERROR_RATE} > 0.05" | bc -l) )); then
        echo "错误率 ${ERROR_RATE} 超过阈值,自动回滚"
        kubectl scale deployment/${DEPLOYMENT}-canary --replicas=0 -n ${NAMESPACE}
        kubectl scale deployment/${DEPLOYMENT}-stable --replicas=${TOTAL} -n ${NAMESPACE}
        exit 1
    fi

    echo "阶段 ${percentage}% 通过,继续下一阶段"
done

echo "金丝雀发布完成"
kubectl delete deployment ${DEPLOYMENT}-stable -n ${NAMESPACE}
kubectl label deployment ${DEPLOYMENT}-canary version=stable -n ${NAMESPACE}

Istio流量管理实现精确灰度

基于副本数的流量分割粒度较粗(最小10%),使用Istio的VirtualService和DestinationRule可以实现1%级别的精确流量控制。

# DestinationRule - 定义两个子集
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: webapp-dr
spec:
  host: webapp-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

---
# VirtualService - 按权重分流
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: webapp-vs
spec:
  hosts:
  - webapp-service
  http:
  - route:
    - destination:
        host: webapp-service
        subset: v1
      weight: 90
    - destination:
        host: webapp-service
        subset: v2
      weight: 10
# 通过kubectl逐步调整流量权重
kubectl patch virtualservice webapp-vs --type='json'   -p='[{"op":"replace","path":"/spec/http/0/route/0/weight","value":70},{"op":"replace","path":"/spec/http/0/route/1/weight","value":30}]'

健康检查与自动回滚机制

自动回滚是发布安全的关键保障。Kubernetes的readiness探针在Pod级别提供健康检查,结合Prometheus指标可以实现应用级别的自动回滚。

# Argo Rollouts - 金丝雀自动回滚配置
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: webapp-rollout
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10
      - pause: { duration: 2m }
      - setWeight: 30
      - pause: { duration: 5m }
      - setWeight: 50
      - pause: { duration: 5m }
      - setWeight: 100
      analysis:
        templates:
        - templateName: success-rate
        args:
        - name: service-name
          value: webapp-service
  selector:
    matchLabels:
      app: webapp
  template:
    spec:
      containers:
      - name: webapp
        image: registry.yunthe.com/webapp:v1.3
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          failureThreshold: 3
          periodSeconds: 10

---
# AnalysisTemplate - Prometheus成功率分析
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
  - name: service-name
  metrics:
  - name: success-rate
    interval: 30s
    successCondition: result[0] >= 0.95
    failureLimit: 3
    provider:
      prometheus:
        address: http://prometheus:9090
        query: |
          sum(rate(http_requests_total{service="{{args.service-name}}",code!~"5.."}[1m]))
          /
          sum(rate(http_requests_total{service="{{args.service-name}}"}[1m]))

当Prometheus查询的请求成功率低于95%且连续3次失败时,Argo Rollouts自动中止金丝雀发布并回滚到稳定版本,无需人工介入。

部署策略选型与生产环境注意事项

蓝绿部署适合版本变更大、需要快速全量回滚的场景;金丝雀发布适合增量变更、需要渐进验证的场景。生产环境中需要注意数据库迁移与部署顺序的配合:Schema变更应保证向后兼容(先加列不加约束、后删旧列),避免新旧版本同时运行时出现兼容性问题。

资源规划方面,蓝绿部署需要2倍于正常运行的资源,金丝雀发布根据灰度比例需要额外10%~50%的资源。在集群资源紧张时,可以通过HPA(水平Pod自动扩缩容)在发布期间临时增加节点,发布完成后缩回。日志和监控在发布期间应切换到DEBUG级别,便于追踪新旧版本的请求链路。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/lan-lyu-bu-shu-yu-jin-si-que-fa-bu-shi-zhan-kubernetes-liu/

(0)
小编小编
上一篇 5小时前
下一篇 5小时前

相关推荐