Envoy流量分流
# HTTP Traffic Shifting Demo
### 环境说明
#### 六个Service:
- envoy:Front Proxy,地址为172.31.55.10
- 5个后端服务
- demoapp-v1.0-1、demoapp-v1.0-2和demoapp-v1.0-3:对应于Envoy中的demoappv10集群
- demoapp-v1.1-1和demoapp-v1.1-2:对应于Envoy中的demoappv11集群
#### 使用的路由配置
```
virtual_hosts:
- name: demoapp
domains: ["*"]
routes:
- match:
prefix: "/"
runtime_fraction:
default_value:
numerator: 100
denominator: HUNDRED
runtime_key: routing.traffic_shift.demoapp
route:
cluster: demoappv10
- match:
prefix: "/"
route:
cluster: demoappv11
启动
cd servicemesh_in_practise/HTTP-Connection-Manager/http-traffic-shifting
docker-compose up
[root@k8s-master http-traffic-shifting]# cat docker-compose.yaml
version: '3'
services:
front-envoy:
image: envoyproxy/envoy-alpine:v1.21-latest
environment:
- ENVOY_UID=0
- ENVOY_GID=0
volumes:
- ./front-envoy.yaml:/etc/envoy/envoy.yaml
networks:
envoymesh:
ipv4_address: 172.31.55.10
expose:
# Expose ports 80 (for general traffic) and 9901 (for the admin server)
- "80"
- "9901"
demoapp-v1.0-1:
image: ikubernetes/demoapp:v1.0
hostname: demoapp-v1.0-1
networks:
envoymesh:
aliases:
- demoappv10
expose:
- "80"
demoapp-v1.0-2:
image: ikubernetes/demoapp:v1.0
hostname: demoapp-v1.0-2
networks:
envoymesh:
aliases:
- demoappv10
expose:
- "80"
demoapp-v1.0-3:
image: ikubernetes/demoapp:v1.0
hostname: demoapp-v1.0-3
networks:
envoymesh:
aliases:
- demoappv10
expose:
- "80"
demoapp-v1.1-1:
image: ikubernetes/demoapp:v1.1
hostname: demoapp-v1.1-1
networks:
envoymesh:
aliases:
- demoappv11
expose:
- "80"
demoapp-v1.1-2:
image: ikubernetes/demoapp:v1.1
hostname: demoapp-v1.1-2
networks:
envoymesh:
aliases:
- demoappv11
expose:
- "80"
networks:
envoymesh:
driver: bridge
ipam:
config:
- subnet: 172.31.55.0/24
[root@k8s-master http-traffic-shifting]# cat front-envoy.yaml
admin:
profile_path: /tmp/envoy.prof
access_log_path: /tmp/admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 9901
layered_runtime:
layers:
- name: admin
admin_layer: {}
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: demoapp
domains: ["*"]
routes:
- match:
prefix: "/"
runtime_fraction:
default_value:
numerator: 100
denominator: HUNDRED
runtime_key: routing.traffic_shift.demoapp
route:
cluster: demoappv10
- match:
prefix: "/"
route:
cluster: demoappv11
http_filters:
- name: envoy.filters.http.router
clusters:
- name: demoappv10
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: demoappv10
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: demoappv10
port_value: 80
- name: demoappv11
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: demoappv11
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: demoappv11
port_value: 80
[root@k8s-master http-traffic-shifting]# cat send-request.sh
#!/bin/bash
declare -i ver10=0
declare -i ver11=0
interval="0.2"
while true; do
if curl -s http://$1/hostname | grep "demoapp-v1.0" &> /dev/null; then
# $1 is the host address of the front-envoy.
ver10=$[$ver10+1]
else
ver11=$[$ver11+1]
fi
echo "demoapp-v1.0:demoapp-v1.1 = $ver10:$ver11"
sleep $interval
done
运行测试脚本send-request.sh
脚本需要front-envoy的地址为参数,并每隔两秒钟向其发起一次HTTP请求
此时所有流量,都将由集群demoappv10所承载,因为默认配置中,100%的流量比例将保留给该集群
将保留给demoappv10集群的流量比例调整为90%,方法是将指定键的值定义为相应的分子数即可
curl -XPOST http://172.31.55.10:9901/runtime_modify?routing.traffic_shift.demoapp=90
重新运行测试脚本,测试的时间越长,样本数越大,越能接近于实际比例,事实上,我们完全可以阶段性地多次进行流量比例的微调。