istio envoy中的网络层(network layer)filter实现机制

本文缘起于微信群上讨论的”L3/L4层过滤器形成Envoy核心的连接管理功能“,本人对这个说法有点疑问,除了LVS这种,一般的中间件都是四层或七层实现呀,涤大一口咬定envoy是有L3网络层过滤器这个说法,本人对envoy不大了解,只能找google问下,找答案之前也有怀疑是不是基于linux 的 netfilter实现的。
istio envoy中的网络层(network layer)filter实现机制_第1张图片
envoy流量劫持机制

经过一番查找后,终于有了答案:iptable(netfilter)。Istio 使用 sidecar 代理来捕获流量,并且在尽可能的地方自动编程网络层,以路由流量通过这些代理,而无需对已部署的应用程序代码进行任何改动。在 Kubernetes中,代理被注入到 pod 中,通过编写 iptables 规则来捕获流量。注入 sidecar 代理到 pod 中并且修改路由规则后,Istio 就能够调解所有流量。

Istio 在 Pod 中注入的 Init 容器名为 istio-init,istio-init 容器的入口是 /usr/local/bin/istio-iptables.sh 脚本,再按图索骥看看这个脚本里到底写的什么,该脚本的位置在 Istio 源码仓库的 tools/deb/istio-iptables.sh,该脚本的用法如下:

$ istio-iptables.sh -p PORT -u UID -g GID [-m mode] [-b ports] [-d ports] [-i CIDR] [-x CIDR] [-h]
  -p: 指定重定向所有 TCP 流量的 Envoy 端口(默认为 $ENVOY_PORT = 15001)
  -u: 指定未应用重定向的用户的 UID。通常,这是代理容器的 UID(默认为 $ENVOY_USER 的 uid,istio_proxy 的 uid 或 1337)
  -g: 指定未应用重定向的用户的 GID。(与 -u param 相同的默认值)
  -m: 指定入站连接重定向到 Envoy 的模式,“REDIRECT” 或 “TPROXY”(默认为 $ISTIO_INBOUND_INTERCEPTION_MODE)
  -b: 逗号分隔的入站端口列表,其流量将重定向到 Envoy(可选)。使用通配符 “*” 表示重定向所有端口。为空时表示禁用所有入站重定向(默认为 $ISTIO_INBOUND_PORTS)
  -d: 指定要从重定向到 Envoy 中排除(可选)的入站端口列表,以逗号格式分隔。使用通配符“*” 表示重定向所有入站流量(默认为 $ISTIO_LOCAL_EXCLUDE_PORTS)
  -i: 指定重定向到 Envoy(可选)的 IP 地址范围,以逗号分隔的 CIDR 格式列表。使用通配符 “*” 表示重定向所有出站流量。空列表将禁用所有出站重定向(默认为 $ISTIO_SERVICE_CIDR)
  -x: 指定将从重定向中排除的 IP 地址范围,以逗号分隔的 CIDR 格式列表。使用通配符 “*” 表示重定向所有出站流量(默认为 $ISTIO_SERVICE_EXCLUDE_CIDR)。

再参考 istio-init 容器的启动参数,完整的启动命令如下:

$ /usr/local/bin/istio-iptables.sh -p 15001 -u 1337 -m REDIRECT -i '*' -x "" -b 9080 -d ""

该容器存在的意义就是让 Envoy 代理可以拦截所有的进出 Pod 的流量,即将入站流量重定向到 Sidecar,再拦截应用容器的出站流量经过 Sidecar 处理后再出站。

iptable功能

iptables 是 Linux 内核中的防火墙软件 netfilter 的管理工具,位于用户空间,同时也是 netfilter 的一部分。Netfilter 位于内核空间,不仅有网络地址转换的功能,也具备数据包内容修改、以及数据包过滤等防火墙功能。

Init 容器中使用的的 iptables 版本是 v1.6.0,共包含 5 张表:

  1. raw 用于配置数据包,raw 中的数据包不会被系统跟踪。
  2. filter 是用于存放所有与防火墙相关操作的默认表。
  3. nat 用于 网络地址转换(例如:端口转发)。
  4. mangle 用于对特定数据包的修改(参考损坏数据包)。
  5. security 用于强制访问控制 网络规则。

iptable缺点

  1. 在规则配置较多时,由于其本身顺序执行的特性,性能会下滑严重。

  2. 每个request的处理都要经过内核态—>用户态—>内核态的过程,这其中会带来数据从内核态拷贝到用户态的,再拷贝到内核态的性能消耗

  3. 由于网络中大量数据包的到来,会产生频繁的硬件中断、上下文切换,一个数据包在多个CPU核之间切换处理,这些因素叠加起来会对性能造成更大的损耗

解决方案是Linux内核社区最近发布了bpfilter,一个使用Linux BPF提供的高性能网络过滤内核模块,计划用来替代netfilter作为iptables的内核底层实现。

有兴趣技术交流请关注我的公众号吧:)

参考:

https://www.datawire.io/envoyproxy/getting-started-envoyproxy-microservices-resilience/
https://discuss.istio.io/t/envoys-traffic-hijacking-port-forward-rule-is-stored-at-the-pod-level-or-host-level/1823
https://cloud.tencent.com/developer/article/1373882
http://www.servicemesher.com/istio-handbook/concepts-and-principle/sidecar-injection-deep-dive.html

你可能感兴趣的:(基础技术,分布式,linux)