本篇是自己的一篇学习笔记,主要是为了学明白,iptable是如何在envoy里面进行流量劫持的,会从下面几个方面来介绍:
问题 1: iptable是怎么与envoy关联起来的
Istio部署业务的时候,envoy都会同时部署在sidecar里面,而在部署sidecar的时候,会将envoy和iptable进行一个关联。
Istio在pod中注入了一个名字叫做istio-init的init容器,这个init容器会在Pod启动之前被优先执行,而iptable与envoy的关联关系就是在这个init容器启动的时候进行操作的。在这一个阶段会主动执行下面的iptable相关的命令,如下所示:
istio-iptables -p 15001 -z 15006 -u 1337 -m REDIRECT -i '*' -x "" -b '*' -d 15090,15020
备注:在 Istio 1.1 版本时还是使用 isito-iptables.sh
命令行来操作 IPtables。
这个命令的含义是: 将进入VM/Pod的tcp的入口流量重定向到15006端口,这个端口对应的是envoy里面的inbound端口,出口的流量定位到15001端口,这里对应的是envoy的outbound端口。
istio-iptables命令行的介绍:
$ 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)。
问题 2: 业务app中的流量请求是如何被iptable劫持发送给envoy的,并且envoy是如何把这个流量请求传递出去的
下图展示的是 productpage
服务请求访问 http://reviews.default.svc.cluster.local:9080/
,当流量进入 reviews
服务内部时,reviews
服务内部的 sidecar proxy 是如何做流量拦截和路由转发的。
入口流量,按照上图标识分为入口流量和出口流量:
入口流量部分:
1-->(iptable开始进行流量劫持)[2-->3-->4]--->inbound handler(envoy的15006端口)-->envoy处理完成之后-->(再次进入iptable)-->[5-->6-->7-->8]--->流量转发到到应用容器,业务进行处理
出口流量部分:
业务层面处理完成之后,iptable开始进行[9-->10-->11-->12]-->outbound handler(envoy的15001端口)-->envoy处理完成之后-->13-->14-->15-->16-->upstream
参考文档:
https://jimmysong.io/blog/sidecar-injection-iptables-and-traffic-routing/#使用-iptables-做流量劫持时存在的问题