K8s 1.18.6版本基于 ingress-nginx 实现金丝雀发布(灰度发布)

环境

软件 版本
kubernetes v1.18.6
nginx-ingress-controller 0.32.0
Rancher v2.4.5

本次实验基于 Rancher-v2.4.5 部署了1.18.6版本的k8s集群,nginx-ingress 版本为0.32.0,理论上 ingress-nginx >= 0.21.0都是可以的。

介绍

金丝雀发布:又叫灰度发布,控制产品从A版本平滑的过度到B版本

ingress-nginx:k8s ingress工具,支持金丝雀发布,可以实现基于权重、请求头、请求头的值、cookie转发流量。

rancher:k8s集群管理工具,使用UI简化k8s相关操作

ingress-nginx canary官方说明:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#canary

首先创建两个nginx应用

  1. 部署两个deployment的http应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: appv1
labels:
app: v1
spec:
replicas: 1
selector:
matchLabels:
app: v1
template:
metadata:
labels:
app: v1
spec:
containers:
- name: nginx
image: zerchin/canary:v1
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appv2
labels:
app: v2
spec:
replicas: 1
selector:
matchLabels:
app: v2
template:
metadata:
labels:
app: v2
spec:
containers:
- name: nginx
image: zerchin/canary:v2
ports:
- containerPort: 80

kubectl查看pod

# kubectl get pod -o wide |grep app
appv1-77655949f8-hx6nm 1/1 Running 0 44m 10.60.0.91 xie-node001 <none> <none>
appv2-7b8659cd88-dgd5c 1/1 Running 0 44m 10.60.0.92 xie-node001 <none> <none>

这两个应用输出以下内容

# curl 10.60.0.91
v1
# curl 10.60.0.92
canary-v2
  1. 分别为应用创建对应的service
apiVersion: v1
kind: Service
metadata:
name: appv1
spec:
selector:
app: v1
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: appv2
spec:
selector:
app: v2
ports:
- protocol: TCP
port: 80
targetPort: 80

kubectl查看service

# kubectl get svc |grep app
appv1 ClusterIP 10.50.42.17 <none> 80/TCP 26m
appv2 ClusterIP 10.50.42.131 <none> 80/TCP 26m

部署一个正常的ingress

现在这个ingress能正常的将访问路由到appv1上

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app
namespace: default
spec:
rules:
- host: nginx.zerchin.xyz
http:
paths:
- backend:
serviceName: appv1
servicePort: 80
path: /

kubectl查看ingress

# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
app <none> nginx.zerchin.xyz 172.16.0.195,172.16.0.196 80 11m

访问nginx.zerchin.xyz

# curl nginx.zerchin.xyz
v1

基于权重转发流量

nginx.ingress.kubernetes.io/canary-weight:随机整数请求的整数百分比(0-100),应将其路由到canary Ingress中指定的服务。权重0表示此Canary规则不会在Canary入口中将任何请求发送到服务。权重为100表示所有请求都将发送到Ingress中指定的替代服务。

新建一个ingress,配置如下

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "30"
name: app-canary
namespace: default
spec:
rules:
- host: nginx.zerchin.xyz
http:
paths:
- backend:
serviceName: appv2
servicePort: 80
path: /

kubectl查看ingress

# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
app <none> nginx.zerchin.xyz 172.16.0.195,172.16.0.196 80 11m
app-canary <none> nginx.zerchin.xyz 172.16.0.195,172.16.0.196 80 7m13s

这时候再访问nginx.zerchin.xyz,会发现其中30%的流量会路由到v2版本上

# for i in `seq 1 10`;do curl nginx.zerchin.xyz;done
canary-v2
canary-v2
v1
v1
canary-v2
v1
v1
v1
v1
v1

基于请求头转发流量

nginx.ingress.kubernetes.io/canary-by-header:用于通知Ingress将请求路由到Canary Ingress中指定的服务的标头。当请求标头设置always为时,它将被路由到Canary。当标头设置never为时,它将永远不会路由到金丝雀。对于任何其他值,标头将被忽略,并且按优先级将请求与其他金丝雀规则进行比较。

修改app-canary的ingress配置,修改annotation,如下:

  annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "canary"

测试结果

# curl nginx.zerchin.xyz
v1
# curl -H "canary:always" nginx.zerchin.xyz
canary-v2

基于请求头和请求头的值转发流量

nginx.ingress.kubernetes.io/canary-by-header-value:匹配的报头值,用于通知Ingress将请求路由到Canary Ingress中指定的服务。当请求标头设置为此值时,它将被路由到Canary。对于任何其他标头值,标头将被忽略,并按优先级将请求与其他金丝雀规则进行比较。此注释必须与nginx.ingress.kubernetes.io/canary-by-header一起使用。

修改app-canary的ingress配置,修改annotation,如下:

  annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "haha"

测试结果

# curl nginx.zerchin.xyz
v1
# curl -H "canary:haha" nginx.zerchin.xyz
canary-v2
# curl -H "canary:always" nginx.zerchin.xyz
v1

基于cookie转发流量

nginx.ingress.kubernetes.io/canary-by-cookie:用于通知Ingress将请求路由到Canary Ingress中指定的服务的cookie。当cookie值设置always为时,它将被路由到canary。当cookie设置never为时,它将永远不会路由到Canary。对于任何其他值,将忽略cookie,并按优先级将请求与其他canary规则进行比较。

修改app-canary的ingress配置,修改annotation,如下:

  annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "test"

测试结果

# curl nginx.zerchin.xyz
v1
# curl -b "test=never" nginx.zerchin.xyz
v1
# curl -b "test=always" nginx.zerchin.xyz
canary-v2
# curl -b "test=1" nginx.zerchin.xyz
v1

总结

  1. 金丝雀发布规则优先级:canary-by-header -> canary-by-cookie -> canary-weight

  2. 目前,每个ingress规则最多可以应用一个canary ingress

K8s 1.18.6版本基于 ingress-nginx 实现金丝雀发布(灰度发布)的更多相关文章

  1. 基于k8s集群部署prometheus监控ingress nginx

    目录 基于k8s集群部署prometheus监控ingress nginx 1.背景和环境概述 2.修改prometheus配置 3.检查是否生效 4.配置grafana图形 基于k8s集群部署pro ...

  2. nginx+lua+redis实现灰度发布_test

    nginx+lua+redis实现灰度发布: 灰度发布是指在黑白之间能够平滑过渡的一种方式 AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见, ...

  3. nginx 根据IP 进行灰度发布

    灰度发布,简单来说,就是根据各种条件,让一部分用户使用旧版本,另一部分用户使用新版本. nginx 的语法本身可以看作是一门小型的编程语言,通过简单的编程,可以轻松实现基于IP的灰度发布. 需求:搭建 ...

  4. 利用nginx+lua+memcache实现灰度发布

    一.灰度发布原理说明 灰度发布在百度百科中解释: 灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什 ...

  5. 基于nginx+lua简单的灰度发布系统

    upstream.conf upstream grey_1 { keepalive 1000; server localhost:8020; } upstream grey_2 { keepalive ...

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

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

  7. ASP.NET Core on K8S学习之旅(14)Ingress灰度发布

    本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章. 之前一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和 ...

  8. 使用Nginx实现灰度发布

    灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B ...

  9. 使用Nginx实现灰度发布(转)

    灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B ...

随机推荐

  1. 图解Kubernetes——故障排查指南

    针对越来多的Kubernetes容器云,对Kubernetes集群的故障排查却成了一个棘手问题.本文虫虫给大家以直观图示方式介绍如何排查Kubernetes的故障.该篇是系列文章续——故障排查篇. 概 ...

  2. IDEA 修改快捷键和Myeclipse 快捷键一致

    介绍 我们知道IDEA这款开发工具功能很强大,为了简化开发步骤,提高开发效率,使用快捷键很显然是必不可少的,那么怎么才能使得IDEA快捷键和MyEclipse快捷键 保持相同呢? 第一种方法,一个快捷 ...

  3. c产生随机数(含时间种子)

    有时候我们需要程序产生一个随机数. 可以用rand() 但是其实这个随机数是伪随机数,它是一个周期很长的一个值而已. 所以我们可以加入一个随机数种子srand(),这个可以取以当前时间为基准的一个值. ...

  4. C++中string类型的find 函数

    (去膜拜大佬的博客园,结果被自己菜到自闭) find string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos. 对其返回的下标position ...

  5. PHP array_diff_uassoc() 函数

    实例 比较两个数组的键名和键值(使用用户自定义函数比较键名),并返回差集: <?phpfunction myfunction($a,$b){if ($a===$b){return 0;}retu ...

  6. PHP strval() 函数

    strval() 函数用于获取变量的字符串值.高佣联盟 www.cgewang.com PHP 版本要求: PHP 4, PHP 5, PHP 7 语法 string strval ( mixed $ ...

  7. 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论

    LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...

  8. 用好这几个技巧,解决Maven Jar包冲突易如反掌

    前言 大家在项目中肯定有碰到过Maven的Jar包冲突问题,经常出现的场景为: 本地运行报NoSuchMethodError,ClassNotFoundException.明明在依赖里有这个Jar包啊 ...

  9. x86架构:分页机制和原理

    分页是现在CPU核心的管理内存方式,网上介绍材料很多,这里不赘述,简单介绍一下分页的背景和原理 1.先说说为什么要分段 实模式下程序之间不隔离,互相能直接读写对方内存,或跳转到其他进程的代码运行,导致 ...

  10. MySQL-安装配置篇

    一.MySQL二进制安装包安装 1.环境初始化 1)创建目录mkdir /app/database --安装路径 mkdir /data/3306 --存放数据路径 mkdir /binlog/330 ...