Envoy简介 什么是Envoy envoy 是作为微服务服务架构中以独立进程方式实现高级网络功能的,轻量级的7层服务代理程序,通常以sidecar
的方式运行在应用程序的周边,也可以作为网络的边缘代理来运行。envoy 的特性 进程外体系结构 ,L3/L4过滤器体系结构,HTTP L7过滤器体系结构, 一流的HTTP/2支持, HTTP/3支持(目前为alpha),HTTP L7路由,gRPC支持,服务发现和动态配置,健康检查,高级负载平衡,前端/边缘代理支持, 一流的可观察性服务网格细节剖析 宏观分析 执行的操作:
使用istioctl为pod注入了sidecar 创建了virtualservice和destinationrule 如何最终影响到了pod的访问行为?
宏观角度 nginx的配置中,可以提供类似如下的配置片段实现按照权重的转发:
因为nginx是代理层,可以转发请求,istio也实现了流量转发的效果,肯定也有代理层,并且识别了前面创建的虚拟服务中定义的规则。
1 $ istioctl kube-inject -f front-tomcat-dpl-v1.yaml
可以看到注入后yaml中增加了很多内容:
pod被istio注入后,被纳入到服务网格中,每个pod都会添加一个名为istio-proxy的容器(常说的sidecar容器),istio-proxy容器中有两个进程,一个是piolot-agent
,一个是envoy
1 2 $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c istio-proxy bash
目前已知:
在istio网格内,每个Pod都会被注入一个envoy代理 envoy充当nginx的角色,做为proxy代理,负责接管pod的入口和出口流量 目前,还需要搞清楚几个问题:
istio-init初始化容器作用是什么? istio-proxy如何接管业务服务的出入口流量? 认识envoy Envoy
是为云原生应用设计的代理。
可以和nginx做类比: https://fuckcloudnative.io/posts/migrating-from-nginx-to-envoy/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 $ docker run -d --name envoy -v `pwd `/envoy.yaml:/etc/envoy/envoy.yaml -p 10000:10000 envoyproxy/envoy-alpine:v1.15.2 $ curl localhost:10000 envoy.yaml admin: access_log_path: /tmp/admin_access.log address: socket_address: { address: 127.0.0.1, port_value: 9901 } static_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 10000 } filter_chains: - filters: - name: envoy.http_connection_manager config: stat_prefix: ingress_http codec_type: AUTO route_config: name: local_route virtual_hosts: - name: local_service domains: ["*" ] routes: - match: { prefix: "/" } route: { cluster: some_service } http_filters: - name: envoy.router clusters: - name: some_service connect_timeout: 2s type : STATIC lb_policy: ROUND_ROBIN hosts: [{ socket_address: { address: 10.103.211.217, port_value: 9999 }}]
脑补一下网络代理程序的流程,比如作为一个代理,首先要能获取请求流量,通常是采用监听端口的方式实现;其次拿到请求数据后需要对其做微处理,例如附加 Header
或校验某个 Header
字段的内容等,这里针对来源数据的层次不同,可以分为 L3/L4/L7
,然后将请求转发出去;转发这里又可以衍生出如果后端是一个集群,需要从中挑选一台机器,如何挑选又涉及到负载均衡等。
listener
: Envoy 的监听地址。Envoy 会暴露一个或多个 Listener 来监听客户端的请求。filter
: 过滤器。在 Envoy 中指的是一些“可插拔”和可组合的逻辑处理层,是 Envoy 核心逻辑处理单元。route_config
: 路由规则配置。即将请求路由到后端的哪个集群。cluster
: 服务提供方集群。Envoy 通过服务发现定位集群成员并获取服务,具体路由到哪个集群成员由负载均衡策略决定。envoy动态配置(xDS) Envoy的启动配置文件分为两种方式:静态配置和动态配置。
静态配置是将所有信息都放在配置文件中,启动的时候直接加载。 动态配置需要提供一个Envoy的服务端,用于动态生成Envoy需要的服务发现接口,这里叫XDS,通过发现服务来动态的调整配置信息,Istio就是实现了v2的API。 Envoy 接收到请求后,会先走 FilterChain
,通过各种 L3/L4/L7 Filter 对请求进行微处理,然后再路由到指定的集群,并通过负载均衡获取一个目标地址,最后再转发出去。
其中每一个环节可以静态配置,也可以动态服务发现,也就是所谓的 xDS
。这里的 x
是一个代词,类似云计算里的 XaaS
可以指代 IaaS、PaaS、SaaS 等。
所以,envoy的架构大致的样子如下:
Downstream
下游(downstream)主机连接到 Envoy,发送请求并或获得响应。
Upstream
上游(upstream)主机获取来自 Envoy 的链接请求和响应。
监听器
除了过滤器链之外,还有一种过滤器叫监听器过滤器 (Listener filters),它会在过滤器链之前执行,用于操纵连接的元数据 。这样做的目的是,无需更改 Envoy 的核心代码就可以方便地集成更多功能。 每个监听器都可以配置多个过滤器链(Filter Chains) ,监听器会根据 filter_chain_match
中的匹配条件 将流量转交到对应的过滤器链,其中每一个过滤器链都由一个或多个网络过滤器 (Network filters
)组成。这些过滤器用于执行不同的代理任务,如速率限制,TLS
客户端认证,HTTP
连接管理,MongoDB
嗅探,原始 TCP 代理等。 envoy在微服务治理中的工作环境 可以在服务旁运行,以平台无关的方式提供必要的特性,所有到服务的流量都通过 Envoy
代理,这里 Envoy
扮演的就是 Sidecar
的角色。
针对于k8s的pod来讲:
在istio中,envoy的位置:
很明显,istio中,envoy进行流量治理,更多的使用的是XDS进行配置更新,而我们知道,XDS需要有服务端来提供接口,istiod中的pilot组件则提供了xDS服务端接口的实现 。
工作原理 目前为止,我们可以知道大致的工作流程:
用户端,通过创建服务治理的规则(VirtualService、DestinationRule等资源类型),存储到ETCD中 istio控制平面中的Pilot服务监听上述规则,转换成envoy可读的规则配置,通过xDS接口同步给各envoy envoy通过xDS获取最新的配置后,动态reload,进而改变流量转发的策略 思考两个问题:
istio中envoy的动态配置到底长什么样子? 在istio的网格内,front-tomcat访问到bill-service,流量的流向是怎么样的? 针对问题1:
每个envoy进程启动的时候,会在127.0.0.1
启动监听15000端口
1 2 3 4 $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c istio-proxy -- bash
针对问题2:
1 2 $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c front-tomcat -- bash
按照之前的认知,
现在为什么流量分配由5:5 变成了9:1?流量经过envoy了的处理
envoy如何接管由front-tomcat容器发出的请求流量?(istio-init
回顾iptables:
istio-init容器作用 Istio 给应用 Pod 注入的配置主要包括:
Init 容器 istio-init
Istio 在 pod 中注入的 Init 容器名为 istio-init
,作用是为 pod 设置 iptables 端口转发。
我们在上面 Istio 注入完成后的 YAML 文件中看到了该容器的启动命令是:
1 istio-iptables -p 15001 -z 15006 -u 1337 -m REDIRECT -i '*' -x "" -b '*' -d 15090,15021,15020
Init 容器的启动入口是 istio-iptables
命令行,该命令行工具的用法如下:
1 2 3 4 5 6 7 8 9 10 11 12 $ istio-iptables [flags] -p: 指定重定向所有 TCP 出站流量的 sidecar 端口(默认为 $ENVOY_PORT = 15001) -m: 指定入站连接重定向到 sidecar 的模式,“REDIRECT” 或 “TPROXY”(默认为 $ISTIO_INBOUND_INTERCEPTION_MODE ) -b: 逗号分隔的入站端口列表,其流量将重定向到 Envoy(可选)。使用通配符 “*” 表示重定向所有端口。为空时表示禁用所有入站重定向(默认为 $ISTIO_INBOUND_PORTS ) -d: 指定要从重定向到 sidecar 中排除的入站端口列表(可选),以逗号格式分隔。使用通配符“*” 表示重定向所有入站流量(默认为 $ISTIO_LOCAL_EXCLUDE_PORTS ) -o:逗号分隔的出站端口列表,不包括重定向到 Envoy 的端口。 -i: 指定重定向到 sidecar 的 IP 地址范围(可选),以逗号分隔的 CIDR 格式列表。使用通配符 “*” 表示重定向所有出站流量。空列表将禁用所有出站重定向(默认为 $ISTIO_SERVICE_CIDR ) -x: 指定将从重定向中排除的 IP 地址范围,以逗号分隔的 CIDR 格式列表。使用通配符 “*” 表示重定向所有出站流量(默认为 $ISTIO_SERVICE_EXCLUDE_CIDR )。 -k:逗号分隔的虚拟接口列表,其入站流量(来自虚拟机的)将被视为出站流量。 -g:指定不应用重定向的用户的 GID。(默认值与 -u param 相同) -u:指定不应用重定向的用户的 UID。通常情况下,这是代理容器的 UID(默认值是 1337,即 istio-proxy 的 UID)。 -z: 所有进入 pod/VM 的 TCP 流量应被重定向到的端口(默认 $INBOUND_CAPTURE_PORT = 15006)。
以上传入的参数都会重新组装成 iptables
规则,关于 Istio 中端口用途请参考 Istio 官方文档 。
这条启动命令的作用是:
将应用容器的所有入站流量都转发到 sidecar的 15006 端口(15090 端口(Envoy Prometheus telemetry)和 15020 端口(Ingress Gateway)除外,15021(sidecar健康检查)端口) 将所有出站流量都重定向到 sidecar 代理(通过 15001 端口) 上述规则对id为1337用户除外,因为1337是istio-proxy自身的流量 该容器存在的意义就是让 sidecar 代理可以拦截pod所有的入站(inbound)流量以及出站(outbound)流量,这样就可以实现由sidecar容器来接管流量,进而实现流量管控。
init容器进行入站出站流量监控 因为 Init 容器初始化完毕后就会自动终止 ,因为我们无法登陆到容器中查看 iptables 信息,但是 Init 容器初始化结果会保留到应用容器和 sidecar 容器中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 $ docker ps |grep front-tomcat 6c0c6478ce2a 43e421a14aec "/bin/sh -c 'mkdir /…" 2 hours ago Up 2 hours k8s_front-tomcat_front-tomcat-v1-8687f9f845-rmlxt_default_0204ab7e-a083-4e71-9af6-dcc675ec7000_0 $ docker inspect 6c0c6478ce2a|grep -i pid "Pid" : 97369, "PidMode" : "" , "PidsLimit" : null, $ nsenter -n --target 97369 $ iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 3879 packets, 233K bytes) pkts bytes target prot opt in out source destination 3884 233K ISTIO_INBOUND tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain INPUT (policy ACCEPT 3884 packets, 233K bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 46 packets, 3926 bytes) pkts bytes target prot opt in out source destination 8 480 ISTIO_OUTPUT tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain POSTROUTING (policy ACCEPT 46 packets, 3926 bytes) pkts bytes target prot opt in out source destination Chain ISTIO_INBOUND (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15008 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15090 3879 233K RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15021 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15020 5 300 ISTIO_IN_REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain ISTIO_IN_REDIRECT (3 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15006 Chain ISTIO_OUTPUT (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN all -- * lo 127.0.0.6 0.0.0.0/0 0 0 ISTIO_IN_REDIRECT all -- * lo 0.0.0.0/0 !127.0.0.1 owner UID match 1337 0 0 RETURN all -- * lo 0.0.0.0/0 0.0.0.0/0 ! owner UID match 1337 8 480 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 1337 0 0 ISTIO_IN_REDIRECT all -- * lo 0.0.0.0/0 !127.0.0.1 owner GID match 1337 0 0 RETURN all -- * lo 0.0.0.0/0 0.0.0.0/0 ! owner GID match 1337 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner GID match 1337 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.1 0 0 ISTIO_REDIRECT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain ISTIO_REDIRECT (1 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15001
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c istio-proxy -- bash istio-proxy@front-tomcat-v1-8687f9f845-rmlxt:/$ netstat -nltp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:8005 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:15021 0.0.0.0:* LISTEN 16/envoy tcp 0 0 0.0.0.0:15021 0.0.0.0:* LISTEN 16/envoy tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:15090 0.0.0.0:* LISTEN 16/envoy tcp 0 0 0.0.0.0:15090 0.0.0.0:* LISTEN 16/envoy tcp 0 0 127.0.0.1:15000 0.0.0.0:* LISTEN 16/envoy tcp 0 0 0.0.0.0:15001 0.0.0.0:* LISTEN 16/envoy tcp 0 0 0.0.0.0:15001 0.0.0.0:* LISTEN 16/envoy tcp 0 0 127.0.0.1:15004 0.0.0.0:* LISTEN 1/pilot-agent tcp 0 0 0.0.0.0:15006 0.0.0.0:* LISTEN 16/envoy tcp 0 0 0.0.0.0:15006 0.0.0.0:* LISTEN 16/envoy tcp6 0 0 :::15020 :::* LISTEN 1/pilot-agent
说明pod内的出站流量请求被监听在15001端口的envoy的进程接收到,进而就走到了envoy的Listener -> route -> cluster -> endpoint 转发流程。
问题就转变为:如何查看envoy的配置,跟踪转发的过程?
envoy流量转发跟踪分析 我们知道,envoy的配置非常复杂,直接在config_dump里去跟踪xDS的过程非常繁琐。因此istio提供了调试命令,方便查看envoy的流量处理流程。
1 $ istioctl proxy-config -h
比如,通过如下命令可以查看envoy的监听器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 $ istioctl proxy-config listener front-tomcat-v1-8687f9f845-rmlxt --port 15001 -ojson $ istioctl proxy-config listener front-tomcat-v1-8687f9f845-rmlxt --port 9999 -ojson ... { "name" : "0.0.0.0_9999" , "address" : { "socketAddress" : { "address" : "0.0.0.0" , "portValue" : 9999 } }, "filterChains" : [ { "filterChainMatch" : { "applicationProtocols" : [ "http/1.0" , "http/1.1" , "h2c" ] }, "filters" : [ { "name" : "envoy.filters.network.http_connection_manager" , "typedConfig" : { "@type" : "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" , "statPrefix" : "outbound_0.0.0.0_9999" , "rds" : { "configSource" : { "ads" : {}, "resourceApiVersion" : "V3" }, "routeConfigName" : "9999" }, ...
envoy收到请求后,会转给监听器进行处理请求,监听器先匹配address和port和socket都一致的Listener,如果没找到再找port一致,address==0.0.0.0的Listener
发现istio会为网格内的Service Port创建名为0.0.0.0_<Port>
的虚拟监听器,本例中为0.0.0.0_9999
。
envoy的15001端口收到请求后,直接转到了0.0.0.0_9999
,进而转到了"routeConfigName": "9999"
,即9999这个route中。
下面,看下route的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 $ istioctl pc route front-tomcat-v1-8687f9f845-rmlxt --name 9999 NOTE: This output only contains routes loaded via RDS. NAME DOMAINS MATCH VIRTUAL SERVICE 9999 bill-service /* vs-bill-service.default $ istioctl pc route front-tomcat-v1-8687f9f845-rmlxt --name 9999 -ojson [ { "name" : "9999" , "virtualHosts" : [ { "name" : "allow_any" , "domains" : [ "*" ], "routes" : [ { "name" : "allow_any" , "match" : { "prefix" : "/" }, "route" : { "cluster" : "PassthroughCluster" , "timeout" : "0s" , "maxGrpcTimeout" : "0s" } } ], "includeRequestAttemptCount" : true }, { "name" : "bill-service.default.svc.cluster.local:9999" , "domains" : [ "bill-service.default.svc.cluster.local" , "bill-service.default.svc.cluster.local:9999" , "bill-service" , "bill-service:9999" , "bill-service.default.svc.cluster" , "bill-service.default.svc.cluster:9999" , "bill-service.default.svc" , "bill-service.default.svc:9999" , "bill-service.default" , "bill-service.default:9999" , "192.168.18.251" , "192.168.18.251:9999" ], "routes" : [ { "name" : "bill-service-route" , "match" : { "prefix" : "/" }, "route" : { "weightedClusters" : { "clusters" : [ { "name" : "outbound|9999|v1|bill-service.default.svc.cluster.local" , "weight" : 90 }, { "name" : "outbound|9999|v2|bill-service.default.svc.cluster.local" , "weight" : 10 } ] }, ...
满足访问domains列表的会优先匹配到,我们访问的是192.168.18.251:9999
,因此匹配bill-service.default.svc.cluster.local:9999
这组虚拟hosts,进而使用到基于weight的集群配置。
我们看到,流量按照预期的配置进行了转发:
1 2 90% -> outbound|9999|v1|bill-service.default.svc.cluster.local 10% -> outbound|9999|v2|bill-service.default.svc.cluster.local
下面,看一下cluster的具体内容:
1 2 3 4 5 6 7 8 9 10 11 12 $ istioctl pc cluster front-tomcat-v1-8687f9f845-rmlxt --fqdn bill-service.default.svc.cluster.local -ojson ... "name" : "outbound|9999|v1|bill-service.default.svc.cluster.local" , "type" : "EDS" , "edsClusterConfig" : { "edsConfig" : { "ads" : {}, "resourceApiVersion" : "V3" }, "serviceName" : "outbound|9999|v1|bill-service.default.svc.cluster.local" }, ...
我们发现,endpoint列表是通过eds获取的,因此,查看endpoint信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ istioctl pc endpoint front-tomcat-v1-8687f9f845-rmlxt --cluster 'outbound|9999|v1|bill-service.default.svc.cluster.local' -ojson [ { "name" : "outbound|9999|v1|bill-service.default.svc.cluster.local" , "addedViaApi" : true , "hostStatuses" : [ { "address" : { "socketAddress" : { "address" : "172.7.100.3" , "portValue" : 80 } }, ...
目前为止,经过envoy的规则,流量从front-tomcat的pod中知道要发往10.244.0.7:80
这个pod地址。前面提到过,envoy不止接管出站流量,入站流量同样会接管。
下面看下流量到达bill-service-v1的pod后的处理:
先回顾前面的iptables规则,除特殊情况以外,所有的出站流量被监听在15001端口的envoy进程拦截处理,同样的,分析bill-service-v1的iptables规则可以发现,监听在15006端口的envoy进程通过在PREROUTING链上添加规则,同样将进入pod的入站流量做了拦截。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Chain PREROUTING (policy ACCEPT 148 packets, 8880 bytes) pkts bytes target prot opt in out source destination 148 8880 ISTIO_INBOUND tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain INPUT (policy ACCEPT 148 packets, 8880 bytes) pkts bytes target prot opt in out source destination Chain ISTIO_INBOUND (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15008 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15090 143 8580 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15021 5 300 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15020 0 0 ISTIO_IN_REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain ISTIO_IN_REDIRECT (3 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15006
15006端口是一个名为 virtualInbound
虚拟入站监听器,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 $ istioctl pc l bill-service-v1-59b4f4ccc7-qvhw6.default --port 15006 -ojson "name" : "envoy.filters.network.http_connection_manager" ,"typedConfig" : { "@type" : "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" , "statPrefix" : "inbound_0.0.0.0_80" , "routeConfig" : { "name" : "inbound|80||" , "virtualHosts" : [ { "name" : "inbound|http|9999" , "domains" : [ "*" ], "routes" : [ { "name" : "default" , "match" : { "prefix" : "/" }, "route" : { "cluster" : "inbound|80||" , "timeout" : "0s" , "maxStreamDuration" : { "maxStreamDuration" : "0s" , "grpcTimeoutHeaderMax" : "0s" } }, "decorator" : { "operation" : "bill-service.default.svc.cluster.local:9999/*" } } ] } ], "validateClusters" : false
相比于VirtualOutbound
, virtualInbound
不会再次转给别的虚拟监听器,而是直接由本监听器的filterChains
处理,本例中我们可以发现本机目标地址为80的http请求,转发到了inbound|9999|http|bill-service.default.svc.cluster.local
这个集群中。
查看该集群的信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 $ istioctl pc cluster bill-service-v1-59b4f4ccc7-qvhw6.default -h $ istioctl pc cluster bill-service-v1-59b4f4ccc7-qvhw6.default --fqdn "inbound|80||" -ojson [ { "name" : "inbound|80||" , "type" : "ORIGINAL_DST" , "connectTimeout" : "10s" , "lbPolicy" : "CLUSTER_PROVIDED" , "circuitBreakers" : { "thresholds" : [ { "maxConnections" : 4294967295, "maxPendingRequests" : 4294967295, "maxRequests" : 4294967295, "maxRetries" : 4294967295, "trackRemaining" : true } ] }, "cleanupInterval" : "60s" , "upstreamBindConfig" : { "sourceAddress" : { "address" : "127.0.0.6" , "portValue" : 0 } }, "metadata" : { "filterMetadata" : { "istio" : { "services" : [ { "host" : "bill-service.default.svc.cluster.local" , "name" : "bill-service" , "namespace" : "default" } ] } } } } ]
istio小知识 同一个Pod,不同的表现
1 2 3 4 5 $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c front-tomcat bash $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c istio-proxy bash
可以发现,在front-tomcat
容器中的访问请求,是受到我们设置的 9:1的流量分配规则限制的,但是istio-proxy
容器中的访问是不受限制的。
istio-proxy自身,发起的往192.168.18.251的请求,使用的用户是 uid=1337(istio-proxy)
,因此不会被istio-init
初始化的防火墙规则拦截,可以直接走pod的网络进行通信。
集群内的Service都相应的创建了虚拟出站监听器
1 2 3 4 5 6 7 8 9 10 11 $ kubectl exec -ti front-tomcat-v1-8687f9f845-rmlxt -c front-tomcat bash $ istioctl pc l front-tomcat-v1-8687f9f845-rmlxt --port 9000 ADDRESS PORT MATCH DESTINATION 192.168.18.33 9000 App: HTTP Route: sonarqube.jenkins.svc.cluster.local:9000 192.168.18.33 9000 ALL Cluster: outbound|9000||sonarqube.jenkins.svc.cluster.local $ istioctl pc r front-tomcat-v1-8687f9f845-rmlxt --name 'sonarqube.jenkins.svc.cluster.local:9000' $ istioctl pc ep front-tomcat-v1-8687f9f845-rmlxt --cluster 'outbound|9000||sonarqube.jenkins.svc.cluster.local'
virtualOutBound 15001 –> virtial listener 192.168.18.33_9000 –> route sonarqube.jenkins.svc.cluster.local:9000 –> cluster outbound|9000||sonarqube.jenkins.svc.cluster.local –> 192.168.18.33:9000
istio服务网格内,流量请求完全绕过了kube-proxy组件
通过上述流程调试,我们可以得知,front-tomcat中访问bill-service:9999,流量是没有用到kube-proxy维护的宿主机中的iptables规则的。