惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
L
LangChain Blog
博客园_首页
有赞技术团队
有赞技术团队
The Register - Security
The Register - Security
GbyAI
GbyAI
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
量子位
雷峰网
雷峰网
Security Latest
Security Latest
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
IT之家
IT之家
爱范儿
爱范儿
S
Schneier on Security
N
News | PayPal Newsroom
H
Help Net Security
Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
U
Unit 42
博客园 - 司徒正美
Forbes - Security
Forbes - Security
P
Proofpoint News Feed
W
WeLiveSecurity
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
The Cloudflare Blog
AWS News Blog
AWS News Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
H
Heimdal Security Blog
V
Vulnerabilities – Threatpost
Microsoft Azure Blog
Microsoft Azure Blog
T
Tailwind CSS Blog
G
GRAHAM CLULEY

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
Kubernetes 应用最佳实践 - 金丝雀发布
2023-05-01 · via 蛮荆

2023-05-01 Cloud Native Kubernetes Kubernetes 应用最佳实践

概述

金丝雀发布是一种软件发布策略,其中应用的新版本被发布到一小部分用户客户端进行测试,这些用户就像 “金丝雀” 一样,可以提供对新版本功能和性能的真实反馈。 新版本如果没有问题,可以逐步扩大到更多的用户客户端,如果出现问题时,可以迅速回滚或修复。金丝雀发布核心目的在于减少对已有系统的潜在影响,提高发布过程的可控性

图片来源: https://www.amazon.com/Kubernetes-Patterns-Designing-Cloud-Native-Applications/dp/1492050288

和灰度发布的差异

国内很多开发者直接把金丝雀发布和灰度发布混为一谈,这里简单说下两者的区别。

灰度发布是一种将应用新版本逐步更新到客户端的方式

在灰度发布中,新版本会先提示一小部分用户进行更新,然后根据用户反馈和系统数据逐步扩大更新范围。 和金丝雀发布相同的是,灰度发布也是通过一小部分流量来获取真实数据反馈,和金丝雀发布不同的是,灰度发布的主要目的是逐渐引入新版本,而不仅仅是进行测试。

示例

我们经常看到 APP 的灰度更新提示,下面是两个国民级应用的截图。

支付宝版本升级提示

微信版本升级提示

Kubernetes 集成

我们可以利用 Kubernetes 中 Deployment + Ingress 两者的结合,简单平滑地将金丝雀发布流程集成到 Kubernetes 架构体系中。

具体的流程如下:

  1. 创建应用的金丝雀版本 (新版本) 镜像和 Deployment (资源请求和限制,副本数量,HPA 等)
  2. 配置服务发现,为金丝雀版本应用 Pod 配置专属的 Service
  3. 流量切分,将生产环境的一小部分流量切分到金丝雀版本中
  4. 持续监控 (业务稳定三板斧: 日志, 监控指标, 链路追踪)
  5. 渐进式更新 (逐步加大金丝雀版本的流量比例) 或及时回滚 (只需要将金丝雀版本流量比例重置为 0 即可)
  6. 删除旧的生产 Service 和 Deployment

Kubernetes 金丝雀请求流程

业务流程

上面谈到了 Kubernetes 中金丝雀发布的技术方案,下面简单说一下业务方面需要哪些配合工作。

  1. 后台发放金丝雀版本的客户端 (用户) 名额,可以根据用户画像发放,也可以随机发放
  2. 客户端收到金丝雀版本更新后,提示当前用户是否更新到金丝雀版本
  3. 用户下载更新金丝雀版本应用 (例如 Android 绕过应用商城直接下载安装,IOS 通过官方 TestFlight 方案)
  4. 金丝雀版本应用访问时,流量被切分到金丝雀版本的 Pod, 产生对应的日志, 监控指标, 链路追踪数据

Kubernetes 金丝雀日志示例


Kubernetes 金丝雀日志示例2

流量切分

上文中谈到的将生产环境的一小部分流量切分到金丝雀版本中,下面来介绍两种常见的业务金丝雀部署场景。 限于篇幅,本文仅讨论使用 Kubernetes 原生功能作为流量切分方案,不考虑 Istio, Linkerd 等 Service Mesh 方案。

REST 接口不同

这种实现方案是最简单的,我们可以直接使用 Ingress + Service 来实现,通过将不同版本的接口路由到不同的服务即可,例如:

  • 当前运行版本的路由 /api/v1/users/:id/profile 流量切分到生产应用版本的 Service
  • 金丝雀版本的路由 /api/v2/users/:id/profile 流量切分到金丝雀版本的 Service

其中,Deployment 对应的 yaml 声明式代码大致如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-app
  labels:
    version: prod # 标签 = prod
spec:
  # 定义生产版本的 Deployment

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-app
  labels:
    version: canary # 标签 = canary
spec:
  # 定义金丝雀版本的 Deployment

Service 对应的 yaml 声明式代码大致如下:

apiVersion: v1
kind: Service
metadata:
  name: user-app-prod-service
spec:
  selector:
    version: prod  # 将流量路由到标签为 prod 的 Pod
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

---

apiVersion: v1
kind: Service
metadata:
  name: user-app-canary-service
spec:
  selector:
    version: canary  # 将一部分流量路由到标签为 canary 的 Pod
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080 

Ingress 对应的 yaml 声明式代码大致如下 (这里以 Nginx Ingress Controller 为例):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-app-ingress
spec:
  rules:
    - host: dbwu.tech
    - http:
        paths:
          - path: /api/v1/users
            backend:
              service:
                name: user-app-prod-service
                port:
                  number: 80
              weight: 90 # 生产环境版本切分 90% 的流量
          - path: /api/v2/users
            backend:
              service:
                name: user-app-canary-service
                port:
                  number: 80
              weight: 10 # 金丝雀版本切分 10% 的流量

REST 接口版本相同

现实中更常见的场景是: 应用的生产版本和金丝雀版本使用相同的 REST 接口,但是需要将流量切分到不同版本中,同样可以使用 Ingress 来实现。

Nginx Ingress Controller 下列 canary-* Annotation 来支持金丝雀发布机制,下面是几个常用字段的描述。

字段 说明
nginx.ingress.kubernetes.io/canary true:启用 canary false:不启用 canary
nginx.ingress.kubernetes.io/canary-by-header 基于请求头的名称进行金丝雀发布
nginx.ingress.kubernetes.io/canary-by-header-value 基于请求头的值进行金丝雀发布
nginx.ingress.kubernetes.io/canary-by-header-value 基于请求头的值进行金丝雀发布
nginx.ingress.kubernetes.io/canary-weight 基于权重进行金丝雀发布 (0 - 100)

Service 对应的 yaml 声明式代码直接复用上文中的即可,这里不再赘述,Ingress 对应的 yaml 声明式代码大致如下:

# 生产版本 Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prod
  annotations:
spec:
  ingressClassName: nginx
  rules:
    - host: dbwu.tech
      http:
        paths:
          - path: /api/v1/users
            backend:
              service:
                name: user-app-prod-service # 生产环境版本
                port:
                  number: 80


---

# 金丝雀版本 Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary
  annotations:
    # 启用金丝雀发布
    nginx.ingress.kubernetes.io/canary: "true"
    # 这里以 Request.Header 中的 app_release_version 作为金丝雀流量标识名称 
    nginx.ingress.kubernetes.io/canary-by-header: "app_release_version"
    #  这里以 v1.2.3 版本号作为金丝雀流量标识值
    nginx.ingress.kubernetes.io/canary-by-header-value: "v1.2.3"
    # 给金丝雀版本切分 10% 的流量
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  ingressClassName: nginx
  rules:
    - host: dbwu.tech
      http:
        paths:
          - path: /api/v1/users
            backend:
              service:
                name: user-app-canary-service # 金丝雀版本
                port:
                  number: 80

开箱即用的方案

如果使用云计算服务商,那么只需要点几下鼠标,改几个配置参数就可以了 :-)

下面以笔者在工作中使用的阿里云为例演示。

阿里云金丝雀发布演示 - 1

阿里云金丝雀发布演示 - 2

阿里云金丝雀发布演示 - 3

扩展阅读