在现代微服务架构中,应用的更新和发布是一个高频且关键的操作。如何在不影响用户体验的前提下,安全、平稳地将新版本应用推送到生产环境,是每个开发者和运维团队必须面对的挑战。灰度发布(Gray Release)作为一种渐进式发布策略,能够有效降低发布风险,而 Kubernetes 的 Ingress 注解功能为我们提供了一种简单而强大的实现方式。

本文将带你深入浅出地了解如何通过 Ingress 注解 在 Kubernetes 中实现灰度发布,并逐步掌握流量分割、权重控制等核心技巧。无论你是 Kubernetes 新手还是资深用户,都能从本文中获得实用的知识和操作指南。


什么是灰度发布?

灰度发布,也称为金丝雀发布(Canary Release),是一种渐进式的应用发布策略。它的核心思想是:将新版本应用逐步推送给一小部分用户,观察其运行状态,确认无误后再逐步扩大范围,最终完成全量发布

相比于全量发布,灰度发布具有以下优势:

  1. 降低风险:通过小范围验证,避免因新版本问题导致全局故障。
  2. 快速回滚:如果新版本出现问题,可以快速切换回旧版本。
  3. 用户体验优化:逐步发布可以减少对用户的影响。

Kubernetes 中的灰度发布实现方式

在 Kubernetes 中,灰度发布可以通过多种方式实现,例如:

  • Deployment + Service:手动控制流量切换。
  • Istio:通过服务网格实现高级流量管理。
  • Ingress 注解:通过 Nginx Ingress Controller 的注解功能实现流量分割。

本文将重点介绍 Ingress 注解 的实现方式,因为它简单易用,且无需引入额外的组件。


通过 Ingress 注解实现灰度发布

Nginx Ingress Controller 提供了丰富的注解(Annotations),可以轻松实现灰度发布。以下是具体步骤:

1. 部署新旧版本应用

首先,我们需要部署两个版本的应用程序:

  • 旧版本(v1):当前正在运行的生产版本。
  • 新版本(v2):待发布的新版本。

1.1 创建 v1 版本 Deployment 和 Service

# v1 版本 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v1
spec:
replicas: 3
template:
metadata:
labels:
app: my-app
version: v1
spec:
containers:
- name: my-app
image: my-app:v1
ports:
- containerPort: 80 # v1 版本 Service
apiVersion: v1
kind: Service
metadata:
name: my-app-v1
spec:
selector:
app: my-app
version: v1
ports:
- port: 80
targetPort: 80

1.2 创建 v2 版本 Deployment 和 Service

# v2 版本 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v2
spec:
replicas: 3
template:
metadata:
labels:
app: my-app
version: v2
spec:
containers:
- name: my-app
image: my-app:v2
ports:
- containerPort: 80 # v2 版本 Service
apiVersion: v1
kind: Service
metadata:
name: my-app-v2
spec:
selector:
app: my-app
version: v2
ports:
- port: 80
targetPort: 80

2. 配置 Ingress 实现灰度发布

通过 Nginx Ingress Controller 的 canary 注解,我们可以轻松实现流量分割。

2.1 创建 Ingress 资源

以下是一个示例配置:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true" # 启用灰度发布
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% 流量到新版本
spec:
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v2 # 新版本服务
port:
number: 80
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v1 # 旧版本服务
port:
number: 80

2.2 关键注解说明

  • nginx.ingress.kubernetes.io/canary: "true":启用灰度发布功能。
  • nginx.ingress.kubernetes.io/canary-weight: "10":将 10% 的流量分配到新版本(v2),剩余 90% 的流量继续使用旧版本(v1)。

3. 逐步调整流量权重

在灰度发布过程中,可以逐步增加新版本的流量比例。例如:

  • 初始阶段:10% 流量到 v2。
  • 验证通过后:将权重调整为 50%。
  • 最终阶段:将权重调整为 100%,完成全量发布。

只需修改 canary-weight 注解的值即可:

nginx.ingress.kubernetes.io/canary-weight: "50"  # 50% 流量到新版本

4. 监控与回滚

在灰度发布过程中,务必监控新版本的运行状态,包括:

  • 应用日志:检查是否有错误或异常。
  • 性能指标:如响应时间、错误率等。
  • 用户反馈:收集用户的使用体验。

如果发现问题,可以通过调整 canary-weight 注解将流量切回旧版本:

nginx.ingress.kubernetes.io/canary-weight: "0"  # 所有流量切回旧版本

灰度发布的进阶用法

除了基于权重的流量分割,Nginx Ingress Controller 还支持以下灰度发布策略:

1. 基于请求头的流量分割

通过 nginx.ingress.kubernetes.io/canary-by-header 注解,将特定请求头的流量路由到新版本。

示例配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
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"
spec:
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v2
port:
number: 80
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v1
port:
number: 80

说明

  • 当请求头中包含 X-Canary: true 时,流量会被路由到新版本(v2)。
  • 其他请求继续使用旧版本(v1)。

2. 基于 Cookie 的流量分割

通过 nginx.ingress.kubernetes.io/canary-by-cookie 注解,将特定 Cookie 的流量路由到新版本。

示例配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "canary"
spec:
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v2
port:
number: 80
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v1
port:
number: 80

说明

  • 当请求中包含 canary=true 的 Cookie 时,流量会被路由到新版本(v2)。
  • 其他请求继续使用旧版本(v1)。

3. 组合使用

可以同时使用权重、请求头和 Cookie 实现更复杂的灰度发布策略。

示例配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "canary"
spec:
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v2
port:
number: 80
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-v1
port:
number: 80

说明

  • 10% 的流量会被分配到新版本(v2)。
  • 如果请求头中包含 X-Canary: true 或 Cookie 中包含 canary=true,流量也会被路由到新版本。

总结

通过 Kubernetes 的 Ingress 注解,我们可以轻松实现灰度发布,逐步将新版本应用推送给用户,降低发布风险。无论是基于权重的流量分割,还是基于请求头或 Cookie 的精细化控制,Nginx Ingress Controller 都提供了强大的支持。

灰度发布不仅是技术上的优化,更是对用户体验的尊重。希望本文能帮助你掌握这一重要技能,让你的发布过程更加平稳、可靠!


立即尝试:在你的 Kubernetes 集群中部署一个灰度发布示例,感受渐进式发布的魅力吧!如果你有任何问题或想法,欢迎在评论区留言讨论!

K8s 灰度发布实战:通过 Ingress 注解轻松实现流量分割与渐进式发布的更多相关文章

  1. Spring Boot 实战 —— MyBatis(注解版)使用方法

    原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...

  2. 【Kubernetes】K8s笔记(十一):Ingress 集群进出流量总管

    目录 0. Ingress 解决了什么问题 1. Ingress Controller 2. 指定 Ingress Class 使用多个 Ingress Controller 3. 使用 YAML 描 ...

  3. Apache 整合 Tomcat (首先Apache 发布的是PHP项目,占用端口80,tomcat 发布的是Java 项目,占用端口8080)

    情况简介: Apache 整合 Tomcat (首先Apache 发布的是PHP项目,占用端口80,tomcat 发布的是Java 项目,占用端口8080),而现在是虚拟出来两个域名(希望这两个域名都 ...

  4. 基于ambassador实现K8S灰度发布

    为什么需要灰度发布 灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式.在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对 ...

  5. K8S(13)监控实战-部署prometheus

    k8s监控实战-部署prometheus 目录 k8s监控实战-部署prometheus 1 prometheus前言相关 1.1 Prometheus的特点 1.2 基本原理 1.2.1 原理说明 ...

  6. 技术基础 | 用JSON在抖音上发布动态——使用Stargate即可轻松实现

    Cassandra是世界上经受住最多实战考验的数据库,通过其快速且易于使用的数据API,让你的程序开发升级. 本文将介绍什么是Stargate以及Stargate的最新进展,如果您想快速浏览相关代码和 ...

  7. K8S(16)集成实战-使用spinnaker进行自动化部署

    K8s集成实战-使用spinnaker进行自动化部署 1 spinnaker概述和选型 1.1 概述 1.1.1 主要功能 Spinnaker是一个开源的多云持续交付平台,提供快速.可靠.稳定的软件变 ...

  8. K8S(15)监控实战-ELK收集K8S内应用日志

    K8S监控实战-ELK收集K8S内应用日志 目录 K8S监控实战-ELK收集K8S内应用日志 1 收集K8S日志方案 1.1 传统ELk模型缺点: 1.2 K8s容器日志收集模型 2 制作tomcat ...

  9. K8S(14)监控实战-grafana出图_alert告警

    k8s监控实战-grafana出图_alert告警 目录 k8s监控实战-grafana出图_alert告警 1 使用炫酷的grafana出图 1.1 部署grafana 1.1.1 准备镜像 1.1 ...

  10. K8S(09)交付实战-通过流水线构建dubbo服务

    k8s交付实战-流水线构建dubbo服务 目录 k8s交付实战-流水线构建dubbo服务 1 jenkins流水线准备工作 1.1 参数构建要点 1.2 创建流水线 1.2.1 创建流水线 1.2.2 ...

随机推荐

  1. 拯救php性能的神器webman-使用后台webman-admin

    在webman的插件市场里面发现了这个 webman-admin 安装的话很简单,就是在已经安装了 webman 的目录里面执行  composer require -W webman/admin 安 ...

  2. 用OpenResty搭建高性能服务端

    相关链接:https://github.com/openresty/lua-nginx-module OpenResty 简介 OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web ...

  3. Blazor 组件库 BootstrapBlazor 中EditorForm组件介绍

    组件介绍 EditorForm 组件是一个非常实用的组件,当进行数据编辑时,仅需要将 Model 属性赋值即可. 绑定模型默认自动生成全部属性,可以通过设置 AutoGenerateAllItem 更 ...

  4. Android开发重要知识点

    一.网络 1.https原理 2.tcp/ip协议 三次握手:https://www.cnblogs.com/cenglinjinran/p/8482412.html 四次挥手:https://www ...

  5. FineReport取消强制分页和调整宽度的设置方法

    在decision里,找到管理系统-目录管理,打开相应挂载的报表,在参数设置里,添加以下内容: _bypagesize_ 字符串 false

  6. 10C++选择结构(4)——教学

    一.switch语句 (第25课 成绩等级) 问题:风之巅小学规定,若测试成绩大于或等于90分为"A",大于或等于70分小于90分为"B",大于或等于60分小于 ...

  7. 中电金信智能视觉分析系统,以AI技术助力企业升级

    ​ 基于行业需求与业务痛点,中电金信推出了智能视觉分析系统.该系统是集视频接入.视频识别与分析.AI算法管理.异常报警等为一体,可提供视频安全监管标准的场景应用方案以及二次开发能力的通用智能视觉分析系 ...

  8. OpenCV4.1.0中的GPU版本的SURF特征点提取类的命名空间、所在头文件和类名

    OpenCV4.1.0中的GPU版本的SURF特征点提取类的命名空间.所在头文件和类名情况如下: 类名:cv::cuda::SURF_CUDA 所在的命名空间:cv::cuda 所在头文件:$\bui ...

  9. OGC——WMS服务

    一.引言 一直用arcgis javascript的二次开发,经常使用它的一些服务WMS.WMTS.WFS.MapService等,并没有深入了解这些服务内部机制,直到最近学习了geoserver,由 ...

  10. RL中on-policy和off-policy的本质区别/重要性采样

    本随笔的图片都来自UCL强化学习课程lec5 Model-free prediction的ppt (Teaching - David Silver ). 回忆值函数的表达式: \[v_\pi(s) = ...