K8S蓝绿发布

在 Kubernetes(K8S)中,蓝绿发布 是一种零停机的发布策略,核心思路是同时维护两套完全相同的环境(蓝环境 = 旧版本,绿环境 = 新版本),先部署绿环境并验证,验证通过后将流量从蓝环境切换到绿环境,最后销毁蓝环境。以下是详细的实现步骤、核心资源和实操示例:

一、蓝绿发布核心原理

  1. 环境隔离:蓝、绿环境使用独立的 Deployment(或 StatefulSet),但共享同一个 Service(通过标签选择器控制流量指向)。
  2. 流量切换 :通过修改 Service 的 selector 标签,将流量从旧版本(蓝)切换到新版本(绿)。
  3. 回滚机制:若绿环境异常,只需将 Service 的 selector 切回蓝环境标签,即可快速回滚。

二、前置条件

  1. 已部署 K8S 集群(单节点 / 多节点均可)。
  2. 已准备好新旧版本的应用镜像(例如:app:v1= 蓝,app:v2= 绿)。
  3. 熟悉 K8S 的 Deployment、Service、Label 核心概念。

三、分步实现蓝绿发布

步骤 1:部署蓝环境(旧版本)

首先部署旧版本应用(蓝环境),并通过 Service 暴露流量。

1.1 蓝环境 Deployment(app-v1.yaml)

yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue  # 蓝环境 Deployment 名称
spec:
  replicas: 3  # 副本数,根据业务调整
  selector:
    matchLabels:
      app: myapp
      version: v1  # 蓝环境核心标签
  template:
    metadata:
      labels:
        app: myapp
        version: v1  # 与 selector 一致
    spec:
      containers:
      - name: myapp
        image: app:v1  # 旧版本镜像
        ports:
        - containerPort: 8080
        readinessProbe:  # 就绪探针,确保容器就绪后再接收流量
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

1.2 服务暴露 Service(app-service.yaml)

yaml

复制代码
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: ClusterIP  # 或 NodePort/LoadBalancer,根据场景选择
  selector:
    app: myapp
    version: v1  # 初始指向蓝环境
  ports:
  - port: 80
    targetPort: 8080

1.3 部署蓝环境

bash

运行

复制代码
kubectl apply -f app-v1.yaml
kubectl apply -f app-service.yaml

# 验证蓝环境运行正常
kubectl get pods -l version=v1
kubectl port-forward service/myapp-service 8080:80  # 本地访问验证
步骤 2:部署绿环境(新版本)

部署新版本应用(绿环境),此时绿环境不接收任何流量(因为 Service 的 selector 仍指向 v1)。

2.1 绿环境 Deployment(app-v2.yaml)

yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green  # 绿环境 Deployment 名称
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: v2  # 绿环境核心标签
  template:
    metadata:
      labels:
        app: myapp
        version: v2
    spec:
      containers:
      - name: myapp
        image: app:v2  # 新版本镜像
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

2.2 部署绿环境并验证

bash

运行

复制代码
kubectl apply -f app-v2.yaml

# 验证绿环境 Pod 正常运行(此时无流量)
kubectl get pods -l version=v2
# 可选:直接访问绿环境 Pod IP 验证新版本功能
kubectl exec -it <蓝环境Pod> -- curl <绿环境PodIP>:8080
步骤 3:切换流量到绿环境

修改 Service 的 selector,将流量从 version: v1 切换到 version: v2

方式 1:编辑 Service(交互式)

bash

运行

复制代码
kubectl edit service myapp-service
# 将 spec.selector.version 从 v1 改为 v2,保存退出

方式 2:命令行替换(推荐,可自动化)

bash

运行

复制代码
kubectl patch service myapp-service -p '{"spec":{"selector":{"version":"v2"}}}'

验证流量切换

bash

运行

复制代码
# 本地访问 Service,确认返回新版本内容
kubectl port-forward service/myapp-service 8080:80
# 查看 Service 端点(已指向绿环境 Pod)
kubectl describe service myapp-service | grep Endpoints
步骤 4:确认无误后清理蓝环境

若绿环境运行稳定,删除蓝环境 Deployment:

bash

运行

复制代码
kubectl delete deployment app-blue
回滚操作(若绿环境异常)

只需将 Service 的 selector 切回 version: v1 即可:

bash

运行

复制代码
kubectl patch service myapp-service -p '{"spec":{"selector":{"version":"v1"}}}'
# 之后可删除绿环境 Deployment
kubectl delete deployment app-green

四、进阶优化

  1. 使用 Label 而非 Deployment 名称 :确保蓝绿环境的核心区别是 version 标签,而非 Deployment 名称,降低维护成本。
  2. 自动化验证:在切换流量前,通过脚本 / CI 验证绿环境的健康检查、接口可用性。
  3. 结合 Ingress :若对外暴露服务,可通过 Ingress 的 backend.service.selector 切换流量,支持域名 / 路径级别的蓝绿发布。
  4. 扩缩容策略:切换前可先扩绿环境副本数至与蓝环境一致,切换后缩容蓝环境,避免资源浪费。
  5. 使用 Argo Rollouts/Flagger:若需更完善的发布策略(如金丝雀、自动回滚),可集成 K8S 原生的发布控制器(Argo Rollouts 支持蓝绿 / 金丝雀发布)。

五、注意事项

  1. 资源占用:蓝绿发布需同时运行两套环境,集群资源需预留足够容量。
  2. 状态应用处理:若应用有状态(如数据库),需确保蓝绿环境数据一致性(如使用共享存储、数据库迁移脚本)。
  3. 长连接处理:若应用有长连接(如 TCP),切换流量后旧连接可能持续到超时,需在应用层处理连接优雅关闭。

总结

K8S 蓝绿发布的核心是标签隔离 + Service 流量切换,流程简单、回滚成本低,适合对可用性要求高、版本差异较大的场景。核心步骤:部署蓝环境 → 部署绿环境 → 验证绿环境 → 切换流量 → 清理蓝环境,全程零停机,是生产环境中最常用的发布策略之一。

相关推荐
一周困⁸天.2 小时前
K8S-Helm
容器·kubernetes
DeepFlow 零侵扰全栈可观测2 小时前
金山办公基于 DeepFlow docker 模式的可观测性实践
运维·docker·容器
盛世宏博北京2 小时前
弹药库房 “感知 - 传输 - 平台 - 应用” 四层架构温湿度监控方案
java·大数据·人工智能·弹药库房温湿度监控
珂玥c2 小时前
Rook部署——k8s集群中使用ceph
运维·ceph·kubernetes
深兰科技2 小时前
坦桑尼亚与新加坡代表团到访深兰科技,促进AI在多领域的应用落地
java·人工智能·typescript·scala·perl·ai大模型·深兰科技
a努力。2 小时前
阿里Java面试被问:如何分析Full GC的原因?jmap -histo和jmap -dump区别?
java·开发语言·后端·面试·架构
我笔记3 小时前
.net4和core的差异与iis部署差异
java
白宇横流学长4 小时前
基于SpringBoot实现的垃圾分类管理系统
java·spring boot·后端
45288655上山打老虎10 小时前
C++完美转发
java·jvm·c++