流量切分工具
Ingress-Nginx-controller 是kubernetes 的一个工具,通过配置Ingress Annotations参数实现不同场景下的灰度发布和测试
基于header流量切分
nginx.ingress.kubernetes.io/canary-by-header : 基于Request Header 的流量切分,适用于灰度发布以及 A/B测试。
当Request Header 设置为 always时,请求将会被一直发送到Canary 版本
当 Request Header 设置为Never时,请求不会被发送到Canary 版本
基于header-value流量切分
nginx.ingress.kubernetes.io/canary-by-header-value: 要匹配的Request Header 的值, 用于通知 Ingress 将请求路由到Canary
Ingress 中指定的服务。 当Request Header 配置预期value,将会被路由到Canary入口
基于cookie流量切分
nginx.ingress.kubernetes.io/canary-by-cookie: 基于Cookier的流量切分,适用于灰度发布或者A/B测试。 Ingress基于此值,将
请求路由到 Canary Ingress 中指定的服务Cookie。
当cookie 值设置为always, 它将被路由到Canary入口
当cookie 值设置为never,请求不会被发送到Canary入口
基于header切分流量实战(模拟现网版本)
导入镜像
[root@k8snode1 ~]# ctr -n k8s.io images import openresty.tar.gz
Deploy 部署测试Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v1
labels:
app: openresty-demo
spec:
replicas; 1
selector:
matchLabels:
key: value
template:
metadata:
labels:
app: nginx
version: v1
spec:
containers:
- name: nginx
image: docker.io/openresty/openresty:centos
imagePullPolicy: IfNotPresent
ports:
- name: http
protocol: TCP
containerPort: 80
volumes:
- name: config
configMap:
name: nginx-v1
Configmap 配置Pod配置文件
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-v1
labels:
app: nginx
version: v1
data:
nginx.conf: |-
worker_processes 1;
events {
accept_mutex on;
multi_accept on;
use epoll;
worker_connections 1024;
}
http {
ignore_invalid_headers off;
server {
listen 80;
location / {
access_by_lua '
local header_str = ngx.say("nginx-v1")
';
}
}
}
创建Service,暴露服务端口
apiVersion: v1
kind: Service
metadata:
name: nginx-v1
spec:
selector:
app: nginx
version: v1
type: ClusterIP
ports:
- name: http
port: 80
protocol: TCP
基于header切分流量实战(模拟Canary版本)
[root@k8smaster1 ingress]# cat openresty-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v2
labels:
app: openresty-demo
spec:
replicas: 1
selector:
matchLabels:
app: nginx
version: v2
template:
metadata:
labels:
app: nginx
version: v2
spec:
containers:
- name: nginx
image: docker.io/openresty/openresty:centos
imagePullPolicy: IfNotPresent
ports:
- name: http
protocol: TCP
containerPort: 80
volumeMounts:
- name: config
mountPath: /usr/local/openresty/nginx/config/nginx.conf
subPath: nginx.conf
volumes:
- name: config
configMap:
name: nginx-v2
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-v2
labels:
app: nginx
version: v2
data:
nginx.conf: |-
worker_processes 1;
events {
accept_mutex on;
multi_accept on;
use epoll;
worker_connections 1024;
}
http {
ignore_invalid_headers off;
server {
listen 80;
location / {
access_by_lua '
local header_str = ngx.say("nginx-v2")
';
}
}
}
---
apiVersion: v1
kind: Service
metadata:
name: nginx-v2
spec:
selector:
app: nginx
version: v2
type: ClusterIP
ports:
- name: http
port: 80
protocol: TCP
创建Ingress, 配置访问规则
[root@k8smaster1 ingress]# cat ingress-v1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-v1
spec:
ingressClassName: nginx
rules:
- host: canary.example.com
http:
paths:
- backend:
service:
name: nginx-v1
port:
number: 80
pathType: Prefix
path: /
测试切分效果
正常访问结果
创建Canary ingress 版本,测试流量切分效果
[root@k8smaster1 ingress]# cat ingress-v2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "Region"
nginx.ingress.kubernetes.io/canary-by-header-pattern: "cd|sz"
spec:
ingressClassName: nginx
rules:
- host: canary.example.com
http:
paths:
- backend:
service:
name: nginx-v2
port:
number: 80
pathType: Prefix
path: /