问题描述
Ingress如何根据weight分发用户请求,从而控制某一服务的访问占比。
问题分析
Ingress提供了canary功能,可以通过nginx.ingress.kubernetes.io/canary-weight 设置对某一服务访问流量的权重。
问题解决
1.部署两个 echoserver 用于测试
$ kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
canary-5978bccbf6-x44t8 1/1 Running 0 8s
production-8ffb86cb4-gvzc8 1/1 Running 0 5m24s
$ kubectl get svc -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
canary ClusterIP 10.99.3.0 <none> 80/TCP 17s
production ClusterIP 10.99.224.239 <none> 80/TCP 5m33s
# 访问production svc
$ root@k8s-master01:/usr/local/src/canary# curl 10.99.224.239
Hostname: production-8ffb86cb4-gvzc8
Pod Information:
node name: 192.168.0.75
pod name: production-8ffb86cb4-gvzc8
pod namespace: default
pod IP: 10.233.87.35
Server values:
server_version=nginx: 1.13.3 - lua: 10008
Request Information:
client_address=10.233.15.89
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://10.99.224.239:8080/
Request Headers:
accept=*/*
host=10.99.224.239
user-agent=curl/7.68.0
Request Body:
-no body in request-
# 访问canary svc
$ curl 10.99.3.0
Hostname: canary-5978bccbf6-x44t8
Pod Information:
node name: 192.168.0.75
pod name: canary-5978bccbf6-x44t8
pod namespace: default
pod IP: 10.233.90.160
Server values:
server_version=nginx: 1.13.3 - lua: 10008
Request Information:
client_address=10.233.15.89
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://10.99.3.0:8080/
Request Headers:
accept=*/*
host=10.99.3.0
user-agent=curl/7.68.0
Request Body:
-no body in request-
2.创建ingress
$ cat production-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production
spec:
ingressClassName: nginx
rules:
- host: "prod.xxx.com"
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: production
port:
number: 80
$ cat canary-weight-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-weight
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
ingressClassName: nginx
rules:
- host: "prod.xxx.com"
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: canary
port:
number: 80
$ kubectl apply -f production-ingress.yaml
$ kubectl apply -f canary-weight-ingress.yaml
$ kubectl get ingress -n default
NAME CLASS HOSTS ADDRESS PORTS AGE
canary-weight nginx prod.xxx.com 10.99.115.162 80 91s
production nginx prod.xxx.com 10.99.115.162 80 2m5s
3.验证
$ c=0;p=0;for i in $(seq 1000); do result=$(curl -s prod.xxx.com:32080 | grep Hostname | awk -F: '{print $2}'); [[ ${result} =~ ^[[:space:]]canary ]] && let c++ || let p++; done;echo "production:${p}; canary:${c};"
production:721; canary:280;
参考链接
[1] https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary 如果您有其他问题,欢迎您联系火山引擎技术支持服务