在上一节中,我们学习了使用Istio Gateway向集群外部公开集群中的http服务。Istio网关在访问集群外的流量时类似于K8S的入口。istio-Ingres gateway组件相当于k8s中的入口控制器。Istio网关和K8S的区别在于,在Istio网关资源中只定义了暴露的端口、协议和域名,路由信息需要使用Istio的VirtualService虚拟服务的路由规则进行配置,这样Istio提供的各种功能才能应用到接入集群的流量中。
本节将首先学习如何使用Istio Gateway将集群中的tcp服务暴露到集群外部,同时体验Istio流量管理的TCP流量转移功能,以及如何使用Istio将TCP流量从一个版本的微服务逐步迁移到另一个版本。
准备测试环境,部署两个版本的tcp-echo服务,创建一个名为Istio-io-TCP-traffic-shift的命名空房间,标记为自动注入到Istio Sidecar。
kubectl创建命名空间istio-io-TCP-traffic-shiftkube CTL标签命名空间istio-io-TCP-traffic-shift istio-injection = enabled
部署tcp-echo微服务的v1和v2版本:
kubectl apply-f samples/TCP-echo/TCP-echo-services . YAML-n istio-io-TCP-traffic-shift
上述命令将以下内容部署到k8s:
kubectl get svc,deploy,pod-n istio-io-TCP-traffic-shiftNAME TYPE CLUSTER-IP EXTERNAL-IP PORT AGEservice/TCP-echo CLUSTER IP 10 . 109 . 148 . 168 9000/TCP,9001/TCP 7m40sNAME READY最新可用年龄deployment . apps/TCP-echo-v1 1 1 1 1 7m 40S[/h
tcp-echo-services.yaml的内容如下:
API version:v1kind:Servicemetadata:name:TCP-echolabels:app:TCP-echoService:TCP-echospec:-name:TCPPort:9000-name:TCP-otherPort:9001# Port 9000选择器:app: tcp-echo-API version:apps/v1种类:部署元数据:名称:TCP-echo-v1标签:app:TCP-echo版本:v1规格:副本:1选择器:matchLabels:app
使用Istio Gateway向集群外部公开tcp服务tcp-echo。检查istio-Ingres gateway组件的服务:
ku bectl get SVC istio-Ingres gateway-n istio-system-o YAML
API version:v1kind:Servicemetadata:labels:app:istio-Ingres gatewayname:istio-Ingres gatewaynamespace:istio-systemspec:Cluster IP:10 . 106 . 130 . 216Cluster IPS:-10 . 106 . 130 . 216extern
请注意istio-Ingres gateway服务的端口中的端口31400 name tcp,该端口用于将tcp流量接入集群。暴露的tcp服务不同于http服务,使用80和443结合特定主机名域名的路由可以统一多个http服务;公开每个tcp服务需要一个单独的端口。在istio-Ingres gateway服务的默认部署中已经为我们设置了一个31400,可以直接使用。但是,如果您想要向集群外部公开另一个tcp服务,则需要修改istio-Ingres gateway服务并添加一个新的tcp端口。
注意,istio-Ingres gateway服务有一个externalIP,这里是192.168.96.50。我们可以通过192.168.96.50:31400直接访问暴露的服务。如果没有externalIP,我们就得用31400对应的NodePort 32343来问。
弄清楚istio-Ingres Gateway的作用后,再来看看如何创建istio Gateway。samples/TCP-echo/TCP-echo-all-v1 . YAML的内容如下:
API version:networking . istio . io/v1 alpha 3kind:Gatewaymetadata:name:TCP-echo-Gatewayspec:selector:istio:ingressgatewayserver:-port:number:31400name:TCPprotocol:TCPhosts:--
将上述tcp-echo-all-v1.yaml应用于k8s:
kubectl apply-f samples/TCP-echo/TCP-echo-all-v1 . YAML-n istio-io-TCP-traffic-shift
执行上述命令后,创建了目标规则tcp-echo-destination。此目标规则应用于目标服务k8s serivcetcp-echo,并配置了一个服务子集。v1和v2服务子集分别对应labelversion=v1和labelversion=v2的服务实例。执行上述命令后,还会创建网关tcp-echo-gateway。这个网关匹配任何主机名的端口31400,但是单靠网关是做不到的。您还需要使用虚拟服务配置路由规则。这里的路由规则是将tcp-echo-gateway网关的端口31400的流量路由到目标k8s服务的tcp-echo服务子集的端口9000。
在集群外使用nc命令进行测试:
对于{ 1 }中的I..10};do sh -c "(日期;睡眠1)| NC 192 . 168 . 96 . 50 31400 ";完成一个太阳2021年7月25日15时00分41秒一个太阳2021年7月25日15时00分42秒一个太阳2021年7月25日15时00分43秒一个太阳2021年7月25日15时00分44秒一个太阳
10个请求的输出结果都是1,这意味着请求流量100%被路由到v1服务。
接下来,通过以下命令将20%的流量从tcp-echo:v1迁移到tcp-echo:v2:
kubectl apply-f samples/TCP-echo/TCP-echo-20-v2 . YAML-n istio-io-TCP-traffic-shift
tcp-echo-20-v2.yaml文件的内容如下:
API version:networking . istio . io/v1 alpha 3kind:virtual servicemetadata:name:TCP-echospec:-" * "gateways:-TCP-echo-gateway-match:-port:31400route:
通过虚拟服务tcp-echo路由规则中的权重分配,80%的流量保留给tcp-echo: v1,20%的流量保留给tcp-echo:v2。此时,使用nc命令在集群外再次进行测试:
对于{ 1 }中的I..10};do sh -c "(日期;睡眠1)| NC 192 . 168 . 96 . 50 31400 ";完成两个太阳2021年7月25日15时04分41秒一个太阳2021年7月25日15时04分42秒一个太阳2021年7月25日15时04分43秒一个太阳2021年7月25日15时04分44秒一个太阳
10个请求中几乎有20%被路由到版本v2的服务提供商。
利用上述istio的路由权重特性,tcp-echo服务的一部分TCP流量从旧版本迁移到新版本。