本系列的第一篇展示了WorkloadEntry带来的VM与POD同等负载能力。第二、三篇展示了ASM VM PROXY带来的VM流量转移能力。本篇将结合这两种能力,完整地展示ASM支持非容器应用网格化的流量管理能力。由于篇幅所限,安全相关能力不做展示,但网格化后VM中的应用间、及与POD互访都具备了请求认证和来源认证的能力,再结合RBAC可以完整实现认证和授权。
1 搭建实验环境
本篇实验将完整展示端到端的全链路POD和VM混合流量转移。示例需要一个ack集群和2个ecs节点。在ack集群中,包含hello1/hello2/hello3 各1个版本为en
的POD,2个ecs节点各启动一个hello2 app,每个app对应一个版本(fr
/es
)的hello容器。
请求从hello1 POD到hello2 service(endpoints包含ack中的一个hello2 POD和ecs中的2个hello2 app),再hello2到hello3 POD。在此基础上,我们希望路由到hello2 en
/fr
/es
的流量比例为:30%:60%:10%。
示例(http_hybrid_demo)包含如下元素:
- hello1/hello2/hello3 deployment(镜像http_springboot_v1)
- hello2 docker containers(镜像http_springboot_v1/http_springboot_v2/http_springboot_v3)
- 入口网关:istio-ingressgateway
- 入口流量配置:gateway/virtualservice
- hello1流量配置:hello1 service/hello1 virtualservice/hello1 destinationrule
- hello2流量配置:hello2 service/hello2 virtualservice/hello2 destinationrule
- hello3流量配置:hello3 service/hello3 virtualservice/hello3 destinationrule
- hello2 serviceentry/hello2 workloadentry
hello2 POD和VM
本篇实验的核心是将POD和VM作为同一Service下的负载。通过配置VirtualService流量比例,让上游服务按照配比路由到POD和VM。
首先来看hello2的deployment,示意如下。
- 标签
app: hello2-deploy
这个配置需要和余文的workloadentry中的一致 - 标签
version: v1
和镜像http_springboot_v1
决定了这是hello2 service中的版本1的endpoint
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: hybrid-hello
name: hello2-deploy-v1
labels:
app: hello2-deploy
version: v1
spec:
...
spec:
containers:
- name: hello-v1-deploy
image: registry.cn-beijing.aliyuncs.com/asm_repo/http_springboot_v1:1.0.1
env:
- name: HTTP_HELLO_BACKEND
value: "hello3-svc.hybrid-hello.svc.cluster.local"
...
紧接着,我们来看相应的hello2 v2和v3的实例。在VM中按如下命令启动Docker Container:
sh vm/ssh2.sh
docker run \
--rm \
--network host \
--name http_v2 \
-e HTTP_HELLO_BACKEND=hello3-svc.hybrid-hello.svc.cluster.local \
registry.cn-beijing.aliyuncs.com/asm_repo/http_springboot_v2:1.0.1
sh vm/ssh3.sh
docker run \
--rm \
--network host \
--name http_v3 \
-e HTTP_HELLO_BACKEND=hello3-svc.hybrid-hello.svc.cluster.local \
registry.cn-beijing.aliyuncs.com/asm_repo/http_springboot_v3:1.0.1
然后,我们通过如下命令创建WorkloadEntry,将VM中的Docker Containers加入网格。
aliyun servicemesh AddVmAppToMesh \
--ServiceMeshId "$MESH_ID" \
--Namespace hybrid-hello \
--ServiceName hello2-svc \
--Ips "$VM_PRI_2","$VM_PRI_3" \
--Ports http:8001 \
--Labels app=hello2-deploy \
--Force true
这里定义的标签app=hello2-deploy
与前文中hello2 deployment中定义的一致。
2 互访验证
执行如下脚本部署上述及其他CRD,完成实验环境的基本搭建。脚本在http_hybrid_demo/asm路径下,不再冗述。
sh asm/ack.deploy.sh
sh asm/asm.deploy.sh
sh vm/dns.fake.sh
本篇的互访验证较之前两篇,须重点关注从hello1到hello2各endpoints的情况。因为这是混合流量的关键点。
首先从hello1 POD出发,直接访问hello2的3个endpoints:
echo "1 Test access vm ip directly"
echo "curl to POD $hello2_ip"
k exec "$hello2_pod" -c hello-v1-deploy -n hybrid-hello -- curl -s localhost:8001/hello/eric
echo
VMS=("$VM_PRI_2" "$VM_PRI_3")
for vm in "${VMS[@]}"; do
echo "curl to VM $vm"
k exec "$hello1_pod" -c hello-v1-deploy -n hybrid-hello -- \
curl -s "$vm":8001/hello/eric
echo
done
期待的结果如下,证明hello1 POD到hello2 endpoints之间的链路是通的。
curl to POD 172.18.0.194
Hello eric(172.18.0.194)<-Hello eric(172.18.0.254)
curl to VM 192.168.0.171
Bonjour eric(192.168.0.171)<-Hello eric(172.18.0.254)
curl to VM 192.168.0.172
Hola eric(192.168.0.172)<-Hello eric(172.18.0.254)
然后我们在hello1 POD中请求hello2 service,验证依次路由到这3个endpoints:
for i in {1..6}; do
k exec "$hello1_pod" -c hello-v1-deploy -n hybrid-hello -- \
curl -s hello2-svc.hybrid-hello.svc.cluster.local:8001/hello/eric
echo
done
期待的结果如下,证明3个hello2的各endpoints可以被hello2 service成功发现。这一步是最关键的。
因为hello1可以成功访问到hello2 service后面的3个endpoints,意味着作为同一个service的POD和VM混合流量管理基本验证通过。
Hello eric(172.18.0.194)<-Hello eric(172.18.0.254)
Hola eric(192.168.0.172)<-Hello eric(172.18.0.254)
Bonjour eric(192.168.0.171)<-Hello eric(172.18.0.254)
最后我们向hello1 service发起请求,确认3个service链路的情况:
for i in {1..6}; do
resp=$(k exec "$hello1_pod" -c hello-v1-deploy -n hybrid-hello -- curl -s hello1-svc.hybrid-hello.svc.cluster.local:8003/hello/eric)
echo $i "$resp"
done
期待的结果如下,3个service的物理链路验证完毕。
1 Hello eric(172.18.1.8)<-Bonjour eric(192.168.0.171)<-Hello eric(172.18.0.254)
2 Hello eric(172.18.1.8)<-Hello eric(172.18.0.194)<-Hello eric(172.18.0.254)
3 Hello eric(172.18.1.8)<-Hola eric(192.168.0.172)<-Hello eric(172.18.0.254)
3 流量转移
接下来,我们部署hello2的virtualservice和destinationrule,验证混合POD和VM的流量转移。
流量配置
sh asm/asm_traffic_shift.sh
执行如下脚本验证流量配比的配置已经生效:
m get virtualservice -n hybrid-hello hello2-vs -o jsonpath={.spec.http[0].route}
期待的结果如下:
[map[destination:map[host:hello2-svc subset:v1] weight:30] map[destination:map[host:hello2-svc subset:v2] weight:60] map[destination:map[host:hello2-svc subset:v3] weight:10]]
编辑workloadentry,增加version标签:
spec:
address: 192.168.0.171
labels:
app: hello-workload
version: v2
spec:
address: 192.168.0.172
labels:
app: hello-workload
version: v3
流量验证
sh asm/test_mesh.sh
hello1_pod=$(k get pod -l app=hello1-deploy -n hybrid-hello -o jsonpath={.items..metadata.name})
for i in {1..100}; do
resp=$(k exec "$hello1_pod" -c hello-v1-deploy -n hybrid-hello -- curl -s hello1-svc.hybrid-hello.svc.cluster.local:8003/hello/eric)
echo "$resp" >>test_traffic_shift_result
done
echo "expected 30%(Hello eric)-60%(Bonjour eric)-10%(Hola eric):"
sort test_traffic_shift_result | uniq -c | sort -nrk1
期待的结果如下:
expected 30%(Hello eric)-60%(Bonjour eric)-10%(Hola eric):
54 Hello eric(172.18.1.8)<-Bonjour eric(192.168.0.171)<-Hello eric(172.18.0.254)
34 Hello eric(172.18.1.8)<-Hello eric(172.18.0.194)<-Hello eric(172.18.0.254)
12 Hello eric(172.18.1.8)<-Hola eric(192.168.0.172)<-Hello eric(172.18.0.254)
4 全链路
最后我们增加gateway进行端到端验证。执行asm_z.sh脚本增加配置:
sh asm/asm_z.sh
执行test_z.sh脚本进行全链路流量转义的验证。示意如下:
alias k="kubectl --kubeconfig $USER_CONFIG"
IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
for i in {1..100}; do
resp=$(curl -s "$IP":8003/hello/asm)
echo $i "$resp"
if [[ -z $resp ]]; then
echo "error in accessing loop, stop."
rm -rf z_result
exit
fi
echo "$resp" >>z_result
done
echo "expected 30%(Hello eric)-60%(Bonjour eric)-10%(Hola eric):"
sort z_result | uniq -c | sort -nrk1
expected 30%(Hello eric)-60%(Bonjour eric)-10%(Hola eric):
61 Hello asm(172.18.0.245)<-Bonjour asm(192.168.0.170)<-Hello asm(172.18.0.247)
28 Hello asm(172.18.0.245)<-Hello asm(172.18.0.246)<-Hello asm(172.18.0.247)
11 Hello asm(172.18.0.245)<-Hola asm(192.168.0.172)<-Hello asm(172.18.0.247)
到此,POD和VM混合流量转移验证完毕。实验示例使用的是http协议,结合前一篇我们可以完成grpc协议的POD和VM混合流量转移的实践,不再冗述。
本篇示例完整演示了非容器应用网格化过程中最重要的场景。覆盖到从istio-ingressgateway到deployment、workloadentry等各种CRD的配置,完整地展示了POD和VM作为同一个service的混合流量的各技术点的配置。
接下来,我们将视角深入VM中,完成VM中应用的分组和同一分组的多个副本动态加入和删除的实现。