Istio流量管理快速入门
Istio流量管理快速入门
王先森Istio使用场景
在业务更新迭代快速发展时代,更新版本只靠
Kubernetes
实现简单的更新发布是不行的,如果想要实现对业务流量访问限制还需要借用Istio的能力,比如升级到v2版本,将v2版本接入流量占比要到10%
,Kubernetes是无法实现。下面就是整个实现过程。
快速入门
环境准备
主机名 | IP | 角色 |
---|---|---|
k8s-master | eth0:10.1.1.100、docker:172.17.100.0/24 | K8S-master |
k8s-node1 | eth0:10.1.1.120、docker:172.17.120.0/24 | K8S-node |
k8s-node2 | eth0:10.1.1.130、docker:172.17.130.0/24 | K8S-node |
场景一
模型图
创建资源配置清单
1 | cat > front-tomcat-dpl-v1.yaml <<EOF |
1 | cat > bill-service-dpl-v1.yaml <<EOF |
1 | cat > bill-service-svc.yaml <<EOF |
应用资源配置清单
1 | $ kubectl apply -f front-tomcat-dpl-v1.yaml |
场景二
后台账单服务更新v2版本,前期规划90%的流量访问v1版本,接入10%的流量到v2版本
模型图
创建资源配置清单
新增bill-service-dpl-v2.yaml
1 | cat > bill-service-dpl-v2.yaml <<EOF |
此时,访问规则会按照v1和v2的pod各50%的流量分配。
1 | $ kubectl apply -f bill-service-dpl-v2.yaml |
K8S默认流量调度机制
集群流量调度规则详解
我们都知道默认访问规则会按照v1和v2的pod各50%的流量分配,那k8s默认的调度机制是怎么实现的呢,现在从网络层面解释下。
curl bill-service:9999
相当于请求k8s中SVCip:9999
–>查找本地路由通过route -n
没有符合进入0.0.0.0转到172.7.100.1
网桥到10.1.1.100
宿主机上面,然后宿主机看kube-proxy
组件通过iptables-save | grep svcip
找到链路–>iptables-save | grep 链路
–>就可以找到对应pod两个地址的random各自50%的规则。
流量分析详细过程
执行
curl -s bill-service:9999
操作时,因为容器内默认dns解析,实际上是在curl后端服务svc地址
。1
2
3
4
5
6
7
8
9
10
11[root@k8s-master1 bill]# kubectl exec -ti bill-service-v1-59b4f4ccc7-qvhw6 -c bill-server -- sh
/ # nslookup bill-service
Server: 192.168.0.2
Address: 192.168.0.2:53
Name: bill-service.default.svc.cluster.local
Address: 192.168.18.251
[root@k8s-master1 bill]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
bill-service ClusterIP 192.168.18.251 <none> 9999/TCP 2d23h
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 217d通过默认路由(0.0.0.0)规则转到172.17.100.1网桥
1
2
3
4
5
6
7
8[root@k8s-master1 bill]# kubectl exec -ti bill-service-v1-59b4f4ccc7-qvhw6 -c bill-server -- sh
/ # route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.7.100.1 0.0.0.0 UG 0 0 0 eth0
172.7.100.0 * 255.255.255.0 U 0 0 0 eth0
没有找到192.168.18.251 规则,就通过默认路由(0.0.0.0)转到172.17.100.1的网关上。宿主机并没有维护规则,流量而是跳转到iptables查看规则
1
2
3
4
5
6
7
8
9
10
11
12
13[root@k8s-master1 bill]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.1.1.2 0.0.0.0 UG 0 0 0 eth0
10.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
172.7.100.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
172.7.120.0 10.1.1.120 255.255.255.0 UG 0 0 0 eth0
172.7.130.0 10.1.1.130 255.255.255.0 UG 0 0 0 eth0
实际上宿主机部署kube-proxy组件,kube-proxy维护了iptables规则,流量虽然没有直接的宿主机route规则,但是流量访问时已经被iptables拦截,我们看下iptable有没有配置相关规则
[root@k8s-master1 bill]# iptables-save | grep 192.168.18.251
-A KUBE-SERVICES -d 192.168.18.251/32 -p tcp -m comment --comment "default/bill-service:http cluster IP" -m tcp --dport 9999 -j KUBE-SVC-BY6GMFMEZFXQ2BDP
-A KUBE-SVC-BY6GMFMEZFXQ2BDP ! -s 172.7.0.0/16 -d 192.168.18.251/32 -p tcp -m comment --comment "default/bill-service:http cluster IP" -m tcp --dport 9999 -j KUBE-MARK-MASQ
Istio注入资源配置清单
Istio注入方法1
1 | istioctl kube-inject -f bill-service-dpl-v1.yaml|kubectl apply -f - |
Istio注入方法2
通过向名称空间加入自动注入标签
1 | kubectl label namespace bookinfo istio-injection=enabled |
创建流量调度资源配置清单
若想实现上述需求,需要解决如下两个问题:
- 让访问账单服务的流量按照我们期望的比例,其实是一条路由规则,如何定义这个规则
- 如何区分两个版本的服务
这里需要创建两个新的资源类型:VirtualService
和DestinationRule
VirtualService
是一个虚拟的service,描述的是满足什么条件的流量被那个后端处理。类似于根据路径去匹配方法,是更开放的match条件。
DestinationRule
描述的是这个请求到达某个后端后怎么去处理,是方法内的处理逻辑。
所以负载均衡和熔断策略是定义在DestinationRule中的,还可以配置连接池大小、异常实例驱逐规则等功能。
1 | cat > bill-service-destnation-rule.yaml <<EOF |
1 | cat > bill-service-virtualservice.yaml <<EOF |
使用client验证流量分配是否生效。
1 | $ kubectl apply -f bill-service-virtualservice.yaml |
这里就会发现规划90%的流量访问v1版本、接入10%的流量到v2版本,就已经实现了。
Istio注入报错
1 | [root@k8s-master1 ~]# istioctl version |
需要安装socat:yum -y install socat