每日一Go-66、K8s 蓝绿发布 & 金丝雀发布实战:Service 切流量 + Ingress 灰度一次讲透

一、什么是蓝绿发布?

蓝绿发布 = 两套完整环境(Blue/Green)同时存在,通过 Service 一次性切换流量。

Blue 代表当前线上版本;Green代表新版本;切换点是 Service selector

二、蓝绿发布示例

  1. 有两套环境同时在线,Service 一刀切流量

  2. K8s资源结构

sql 复制代码
Deployment(blue) ---> Pod (v1)
Deployment(green) ---> Pod (v2)
Service ---> selector 决定流量去向
  1. 当前线上v1(Blue版)
bash 复制代码
# 部署(Deployment) - 用于管理应用程序的Pod副本
apiVersion: apps/v1 # Kubernetes应用部署的API版本
kind: Deployment # 资源类型:Deployment用于管理无状态应用的部署
metadata: # 元数据部分
  name: golang-per-day-65 # 部署名称
  namespace: codee-jun # Kubernetes命名空间
spec: # 部署规格
  # 副本数量:期望运行的Pod数量
  replicas: 3 # 运行3个Pod副本,提供高可用性
  strategy: # 策略:滚动更新策略
    type: RollingUpdate # 策略类型:滚动更新
    rollingUpdate: # 滚动更新配置
      maxSurge: 1 # 最大激增数:允许同时运行的最大Pod数量超过期望副本数
      maxUnavailable: 1 # 最大不可用数:允许同时运行的最大Pod数量低于期望副本数
  # 选择器:用于选择管理哪些Pod
  selector:
    matchLabels: # 匹配标签:选择具有特定标签的Pod
      app: golang-per-day-65 # 标签名称,用于标识应用
      version: v1 # 版本标签,用于标识应用的不同版本
  1. 新版本V2(Green版)
bash 复制代码
  selector:
    matchLabels: # 匹配标签:选择具有特定标签的Pod
      app: golang-per-day-65 # 标签名称,用于标识应用
      version: v2 # 版本标签,用于标识应用的不同版本
  1. Service 切换成v2
makefile 复制代码
# 服务(Service) - 用于暴露应用程序并提供负载均衡
apiVersion: v1 # Kubernetes API版本
kind: Service # 资源类型:Service用于暴露应用程序
metadata:
  name: golang-per-day-65 # 服务名称
  namespace: codee-jun # Kubernetes命名空间
spec: # 服务规格
  ports: # 端口配置列表
    - protocol: TCP # 协议类型:TCP
      port: 8080 # 服务端口(集群内部访问端口)
      targetPort: 8080 # 目标端口(Pod内部端口)
  sessionAffinity: ClientIP # 会话亲和性:ClientIP表示同一客户端的请求会转发到同一Pod,为了保持session一致性
  selector: # Pod选择器
    app: golang-per-day-65 # 匹配具有app=golang-per-day-65标签的Pod
    # version: v1 # 匹配具有version=v1标签的Pod
    version: v2 # 匹配具有version=v2标签的Pod
  1. 发布/回滚

6.1 发布新版本

apache 复制代码
kubectl patch svc golang-per-day-65 \
  -p '{"spec":{"selector":{"version":"v2","app":"golang-per-day-65"}}}'

6.2 秒级回滚

apache 复制代码
kubectl patch svc golang-per-day-65 \
  -p '{"spec":{"selector":{"version":"v1","app":"golang-per-day-65"}}}'

三、什么是金丝雀发布?

简单来说,金丝雀发布(Canary Deployment)就是一种"先找一小拨人试用,没问题再全量推广"的策略。

它之所以叫这个名字,是因为以前矿工下井前会先放一只金丝雀进去,如果金丝雀出了意外,说明井下有毒气,矿工就不会进去。在软件世界里,新版本就是那只金丝雀

四、金丝雀发布示例

  1. 少量流量先给新版本,逐步放量

  2. K8s资源结构

sql 复制代码
service.yaml     ---> v1
service.v2.yaml ---> v2
ingress.yaml      ---> stable
ingress.canary.yaml ---> canary
  1. service.yaml
makefile 复制代码
# 服务(Service) - 用于暴露应用程序并提供负载均衡
apiVersion: v1 # Kubernetes API版本
kind: Service # 资源类型:Service用于暴露应用程序
metadata:
  name: golang-per-day-65 # 服务名称
  namespace: codee-jun # Kubernetes命名空间
spec: # 服务规格
  ports: # 端口配置列表
    - protocol: TCP # 协议类型:TCP
      port: 8080 # 服务端口(集群内部访问端口)
      targetPort: 8080 # 目标端口(Pod内部端口)
  sessionAffinity: ClientIP # 会话亲和性:ClientIP表示同一客户端的请求会转发到同一Pod,为了保持session一致性
  selector: # Pod选择器
    app: golang-per-day-65 # 匹配具有app=golang-per-day-65标签的Pod
    version: v1 # 匹配具有version=v1标签的Pod
  1. service.v2.yaml
bash 复制代码
spec: # 服务规格
  ports: # 端口配置列表
    - protocol: TCP # 协议类型:TCP
      port: 8080 # 服务端口(集群内部访问端口)
      targetPort: 8080 # 目标端口(Pod内部端口)
  sessionAffinity: ClientIP # 会话亲和性:ClientIP表示同一客户端的请求会转发到同一Pod,为了保持session一致性
  selector: # Pod选择器
    app: golang-per-day-65 # 匹配具有app=golang-per-day-65标签的Pod
    version: v2 # 匹配具有version=v2标签的Pod
  1. ingress.yaml
bash 复制代码
# golang_per_day_65 项目的 Ingress 配置
# 用于管理外部访问集群内服务的路由规则
apiVersion: networking.k8s.io/v1
kind: Ingress
# Ingress 元数据配置
metadata:
  name: golang_per_day_65-ingress     # Ingress 资源名称
  namespace: codee_jun                # 所属命名空间
  annotations:                        # Nginx Ingress 控制器特定配置
    # CORS 配置
    nginx.ingress.kubernetes.io/enable-cors: "true"                     # 启用跨域资源共享
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://golang_per_day_65.com"  # 允许的源
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"  # 允许的HTTP方法
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization"  # 允许的请求头
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true" # 如果需要凭证
    
    # 代理配置
    nginx.ingress.kubernetes.io/proxy-body-size: "1024m"             # 允许的请求体大小
    
    # 会话亲和性配置
    nginx.ingress.kubernetes.io/affinity: "cookie"                    # 启用基于cookie的会话亲和性
    nginx.ingress.kubernetes.io/session-cookie-name: "golang_per_day_65-session"  # 会话cookie名称
    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"      # cookie过期时间(秒)
    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"      # cookie最大生存时间(秒)
# Ingress 规格配置
spec:
  ingressClassName: nginx              # 使用的Ingress控制器类名
  
  # TLS 配置(HTTPS)
  tls:
    - hosts:
        - golang_per_day_65.com # 域名
      secretName: codee-jun-tls-secret # tls证书
  
  # 路由规则
  rules:
    - host: golang_per_day_65.com # 域名
      http: # 协议
        paths: # 路径
          - path: / # 路径
            pathType: Prefix   # 路径类型
            backend: # 后端
              service: # 服务
                name: golang-per-day-65 # 服务名称
                port: # 服务端口
                  number: 8080 # 服务端口号
  1. ingress.canary.yaml
bash 复制代码
  annotations:                        # Nginx Ingress 控制器特定配置
    nginx.ingress.kubernetes.io/canary: "true"                         # 启用金丝雀发布
    nginx.ingress.kubernetes.io/canary-weight: "10"                    # 金丝雀发布权重
...
  rules:
    - host: golang_per_day_65.com # 域名
      http: # 协议
        paths: # 路径
          - path: / # 路径
            pathType: Prefix   # 路径类型
            backend: # 后端
              service: # 服务
                name: golang-per-day-65-v2 # 服务名称
                port: # 服务端口
                  number: 8080 # 服务端口号
  1. 按百分比发布
bash 复制代码
annotations:
  nginx.ingress.kubernetes.io/canary: "true"                         # 启用金丝雀发布
  nginx.ingress.kubernetes.io/canary-weight: "10"   #10%到新版本                 # 金丝雀发布权重
  1. 按 Header
bash 复制代码
annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
  nginx.ingress.kubernetes.io/canary-by-header-value: "true"
javascript 复制代码
// 请求示例
curl -H "X-Canary: true" http://golang-per-day.com/version/v2
  1. 按 Cookie
bash 复制代码
annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-cookie: "canary"
javascript 复制代码
// 请求示例
curl --cookie "canary=true" http://golang-per-day.com/version/v2
  1. 回滚
javascript 复制代码
kubectl delete -f ingress.canary.yaml

五、蓝绿和金丝雀有什么区别?

蓝绿发布:是"瞬间大切换":就像换衣服,脱掉旧的直接穿上新的。速度快,但万一新衣服不合身,那一刻所有人都看到了。

金丝雀发布:是"渐进式切换":就像试菜,先给一两个人尝尝,大家觉得好,再给全餐厅的人上菜。

总结起来,金丝雀发布是用最小的代价,在真实的战场上验证武器。



友情链接:加班费计算器(vx小程序搜索"加班计")


*源码地址*

留言给


如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!

相关推荐
SilentSamsara10 小时前
日志与可观测性:logging 进阶配置与结构化日志实战
运维·开发语言·python·青少年编程
码小猿的CPP工坊10 小时前
C++跨平台开发之基于wxWidgets开发GUI程序简介-001
开发语言·c++
csbysj202010 小时前
C# 文件的输入与输出
开发语言
口喜口喜10 小时前
K3s 安装笔记(CentOS 7.9)
kubernetes
故事和你9110 小时前
洛谷-【动态规划1】动态规划的引入4
开发语言·数据结构·c++·算法·动态规划·图论
吃好睡好便好10 小时前
创建全0矩阵和全1矩阵
开发语言·学习·线性代数·算法·matlab·信息可视化·矩阵
我还记得那天10 小时前
数组的2个应用举例
c语言·开发语言·二分查找·数组
biter down10 小时前
10:GUI的 pytest 框架
开发语言·python
Simon5231411 小时前
mybatis执行流程、关联映射、注解开发
java·开发语言·mybatis