Istio Sidecar流量拦截机制-Day02

1. Envoy Sidecar注入的一些要求

1.1 Istio环境中运行Pod的要求

(1)Service association(服务关联)
Pod必须从属于某个Service,哪怕Pod不需要暴露任何端口,因为只有svc存在,才能让istio发现、注入sidecar以及后续的配置下发,不暴露端口是说这个服务有可能是客户端角色,而流量治理的机制,都是在客户端上完成的;
同时从属于多个Service时,这些Service不能为该类Pod的同一个端口标识使用不同的协议,否则会导致流量治理策略在自动生成的时候出问题。


(2)Application UIDs
UID 1337预留给了Sidecar Proxy使用,业务应用不能以这一UID运行。


(3)NET_ADMIN and NET_RAW capabilities
强制启用了PSP(Pod Security Policy)的Kubernetes环境中,必须允许在网格内的Pod上使用NET_ADMIN和
NET_RAW这两个Capability,以确保Sidecar Envoy依赖的初始化Pod能够正常运行;
未启用PSP,或者启用了PSP但使用了专用的Istio CNI Plugin的场景,可以不用。


(4)Pods with app and version labels
显式地为Pod使用app标签和version标签。
app标签用于为分布式追踪生成context(上下文),而label则用于指示应用的版本化。
一般app用于标识服务名,label用来做子集划分。


(5)Service Port应该明确指定使用的协议。
格式:协议 或协议-后缀。18之前要基于协议来识别,使用7层代理还是4层代理。
Kubernetes v1.18及之后的版本中,可以直接使用appProtocol字段进行标识

1.2 协议的选择

(1)Istio支持代理的协议
支持代理任何类型的TCP流量,包括7层的HTTP、HTTPS、gRPC(http2)及4层的原始TCP(raw tcp)协议。
但为了提供额外的能力,比如路由和更加丰富的指标,Istio需要确定更具体的协议(应用层协议)。
Istio不会代理UDP协议。


(2)协议选择
Istio能够自动检测并识别HTTP(1.0 1.1)和HTTP/2(GRPC)的流量,未检测出的协议类型将一律视为普通的TCP流量。
也支持由用户手动指定。


(3)手动指定协议
格式:<协议>[-<后缀>]。只能指定http、https、grpc,其他的一律当成TCP。
Kubernetes v1.18及之后的版本中,可以直接使用appProtocol字段进行标识。

支持的协议
支持的协议

1.3 Sidecar代理方式简介

(1)Kubernetes平台上,Envoy Sidecar容器与application容器于同一个Pod中共存,它们共享NETWORK、UTS和IPC等名称空间,因此也共用同一个网络协议栈;
Envoy Sidecar基于init容器(需要使用NET_ADMIN和NET_RAW Capability于Pod启动时设置iptables规则以实现流量拦截。

  • 入站流量由iptables拦截后转发给Envoy;
  • Envoy根据配置完成入站流量代理;
  • 后端应用程序生成的出站流量依然由iptables拦截并转发给Envoy;
  • Envoy根据配置完成出站流量代理;

(2)流量拦截模式

  • REDIRECT:重定向模式
  • TPROXY:透明代理模式
  • 具体操作细节请参考:https://github.com/istio/istio/blob/master/tools/packaging/common/istio-start.sh

2. Sidecar Envoy 流量劫持

流量的透明劫持,用于确保让应用无需事先改造即可获得服务治理和观测能力。
开启透明劫持功能后,出入应用的业务流量将会被Sidecar Envoy自动拦截

2.1 未实施和实施了流量拦截的区别

2.1.1 未实施流量拦截时的通信

在这里插入图片描述

2.1.2 入向流量拦截

在这里插入图片描述

2.1.3 出向流量拦截

在这里插入图片描述

2.2 流量劫持过程

(1)Init流程(0):下图紫色虚线表示Init流程。

  • Pod启动时,会借助Init Container特权容器开启流量劫持,并设置流量劫持规则;
  • 劫持规则分为Inbound规则和Outbound规则;
    该阶段属于一个一次性阶段,只会在pod刚被创建启动时进行配置。

(2)Inbound流程(1、2、3):下图橙色实线代表着Inbound流程

  • 请求发给APP前被traffic intercetion劫持;
  • traffic intercetion根据Inbound规则,将请求转发到Sidecar;
  • Sidecar将请求转发给APP;
    该阶段属于永久性的配置,每次请求都会生效。

(3)Outbound流程(4、5、6):下图黑色实线表示Outbound请求。

  • App发出的Outbound请求被traffic interception劫持;
  • traffic interception根据Outbound规则将请求转发给Sidecar;
  • Sidecar处理之后将请求回复给请求者;
    该阶段属于永久性的配置,每次请求都会生效。

流量劫持过程

3. Sidecar在yaml和pod中的体现

Istio基于Kubernetes Admission Controller Webhook完成sidecar自动注入,它会为每个微服务分别添加两个相关的容器。

  • istio-init:隶属于Init Containers,即初始化容器,负责在微服务相关的Pod中生成iptables规则以进行流量拦截并向Envoy Proxy进行转发,运行完成后退出;
  • istio-proxy:隶属于Contianers,即Pod中的正常容器,程序为Envoy Proxy;

部分yaml配置展示

……
Init Containers:
  istio-init: # 初始化容器,这个就是注入sidecar时生成的。
    Container ID:  containerd://b3c76cfca6d9820e370c7c2f0f8d2ea9e088d3bb98805ee79f38c7be982a1ef6
    Image:         docker.io/istio/proxyv2:1.14.3 # 初始化容器镜像版本,和istiod版本一般都是相同的
	……
    Args: # 下面就是sidecar通过istio-iptables做的端口映射
      istio-iptables
      -p
      15001 # 出向流量端口(这样就不会和业务本身的端口冲突)
      -z
      15006 # 入向流量端口(这样就不会和业务本身的端口冲突)
……
Containers:
  sleep: # 这个就是业务容器了
    Container ID:  containerd://3c80920d3cd5f32f805bc24b0ddced5e86718dda8ab72dcafd87c485d7d5eae0
    Image:         curlimages/curl
  ……
  istio-proxy: # 另外还会生成一个istio-proxy容器,也就是sidecar容器
    Container ID:  containerd://dacc430cff8feb260ad5e2d60c0f6eef669912684012d25642c12793e9650279
    Image:         docker.io/istio/proxyv2:1.14.3 # 代理容器版本也和istiod是一致的。
	……

Istio Sidecar使用的端口和协议
为避免与 Sidecar 发生端口冲突,应用程序不应使用 Envoy 使用的任何端口

在这里插入图片描述
Istio 控制平面(istiod)使用以下端口和协议。

在这里插入图片描述

3.1 istio-init初始化容器

(1)istio-init初始化容器基于istio/proxyv2镜像启动,它运行istio-iptables程序以生成流量拦截规则。
拦截的流量将转发至两个相关的端口:

  • 15006:由-z选项定义,指定用于接收拦截所有发往当前Pod/VM的入向流量的目标端口,该配置仅用REDIRECT转发模式;
  • 15001:由-p选项定义,指定用于接收拦截的所有TCP出向流量的目标端口;
    流量拦截模式由-m选项指定,目前支持REDIRECT(默认)和TPROXY两种模式;
    流量拦截时要包含的目标端口列表使用-b选项指定,而要排除的目标端口列表则使用-d选项指定;
    流量拦截时要包含的目标CIDR地址列表可使用-i选项指定,而要排除的目标CIDR格式的地址列表则使用-x选项指定;

(2)此前版本中,该初始化容器会运行一个用于生成iptables规则的相关的脚本来生成iptables规则,脚本地址为:https://github.com/istio/cni/blob/master/tools/packaging/common/istio-iptables.sh

3.2 Istio中用于流量拦截的iptables规则

nsenter命令于宿主机上可直接于目标容器的网络名称空间中运行iptables命令。
例如,假设productpage相关的Pod被调度运行于k8s-node02节点之上,且其内部的envoy进程的pid在宿主机为5670。

3.2.1 查看pod对应的的iptables规则

3.2.1.1 去到pod对应的node节点
[root@k8s-master1 ~]# kubectl get po -owide
NAME                          READY   STATUS    RESTARTS   AGE     IP              NODE        NOMINATED NODE   READINESS GATES
backendv36-697647965b-shb62   2/2     Running   0          7d17h   10.100.113.24   k8s-node1   <none>           <none>
backendv36-697647965b-wtj4g   2/2     Running   0          7d17h   10.100.12.31    k8s-node2   <none>           <none>
demoappv10-54757f48d6-8gn5q   2/2     Running   0          4d17h   10.100.12.35    k8s-node2   <none>           <none>
demoappv10-54757f48d6-jltbh   2/2     Running   0          5d17h   10.100.113.27   k8s-node1   <none>           <none>
demoappv11-6b479f5664-sgjtx   2/2     Running   0          6d20h   10.100.113.26   k8s-node1   <none>           <none>
proxy-645cd54b84-4ctnb        2/2     Running   0          6d20h   10.100.113.25   k8s-node1   <none>           <none>
sleep-645b966fc4-qjgns        2/2     Running   0          12d     10.100.113.23   k8s-node1   <none>           <none>
[root@k8s-master1 ~]# ssh k8s-node1
root@k8s-node1's password:
Last login: Thu Nov  2 17:16:16 2023 from k8s-master1
[root@k8s-node1 ~]#
3.2.1.2 查看对应的envoy进程
[root@k8s-node1 ~]# ps -ef |grep envoy
1337        9456    9382  0 10月30 ?      00:46:44 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error
1337        9681    9664  0 10月30 ?      00:50:37 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error
1337      737728  737706  0 11月06 ?      00:30:10 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error --concurrency 2
1337     1274240 1274222  0 11月01 ?      00:55:23 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error --concurrency 2
1337     1360548 1360528  0 11月07 ?      00:26:44 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error --concurrency 2
1337     1361536 1361516  0 11月07 ?      00:29:38 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error --concurrency 2
root     2046566 2046013  0 10:49 pts/0    00:00:00 grep --color=auto envoy
1337     2159052 2158948  0 11月08 ?      00:21:58 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error --concurrency 2

3.2.1.3 通过Gid过滤iptables规则
[root@k8s-node1 ~]# nsenter -t 1360548 -n iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N ISTIO_INBOUND
-N ISTIO_IN_REDIRECT
-N ISTIO_OUTPUT
-N ISTIO_REDIRECT
-A PREROUTING -p tcp -j ISTIO_INBOUND # 入站规则: 这个规则将 TCP 流量引导到 ISTIO_INBOUND 链。
-A OUTPUT -p tcp -j ISTIO_OUTPUT # 出站规则:这个规则将 TCP 流量引导到 ISTIO_OUTPUT 链。
-A ISTIO_INBOUND -p tcp -m tcp --dport 15008 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 15090 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 15021 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 15020 -j RETURN
# 上述4个端口的规则,也属于入站规则,这些规则用于返回指定端口的流量,过这些端口的流量将直接返回而不经过后续的规则。
-A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT # 入站规则:如果流量不符合前述的端口规则,那么它将被引导到 ISTIO_IN_REDIRECT 链。
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006 # 入站规则:这个规则将 TCP 流量重定向到端口 15006,这是一个 Istio Sidecar 代理接收 Inbound 流量的端口。
-A ISTIO_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN # 出站规则:如果流量源自本地回环地址(127.0.0.6)并且目标是本地回环接口 (lo),则返回,即不经过后续规则。
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --uid-owner 1337 -j ISTIO_IN_REDIRECT
-A ISTIO_OUTPUT -o lo -m owner ! --uid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN
# 上述三行配置也是出站规则:这些规则用于处理特定用户(uid 为 1337)的流量。如果目标不是本地回环地址,且用户 ID 为 1337,则引导到 ISTIO_IN_REDIRECT 链。否则,返回,即不经过后续规则。
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --gid-owner 1337 -j ISTIO_IN_REDIRECT
-A ISTIO_OUTPUT -o lo -m owner ! --gid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
# 上述四行也是出站规则:这些规则处理特定用户组(gid 为 1337)的流量,与上述用户规则相似。
-A ISTIO_OUTPUT -j ISTIO_REDIRECT # 出站规则:如果流量不符合前述的规则,那么它将被引导到 ISTIO_REDIRECT 链。
-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001 # 出站规则:这个规则将 TCP 流量重定向到端口 15001,这是一个 Istio Sidecar 代理用于发送 Egress 流量的端口。

4. Istio流量拦截的处理机制

(1)首先在上面,通过执行nsenter命令查看的iptables规则中,可以看到自定的两个链,分别是-N ISTIO_INBOUND 和 -N ISTIO_IN_REDIRECT,然后在这两个链上,添加了入站规则和出站规则。


(2)对于入站规则INBOUND而言,如果tcp请求的目的端口是15008、15020、15021、15090这4个端口,就直接RETURN,不予拦截。
其他端口的话,如果是入向流量,就直接由ISTIO_IN_REDIRECT链处理(-A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT)。
ISTIO_IN_REDIRECT链会把过来的请求,都重定向到15006这个端口进行处理,15006其实就是Envoy的VirtualInboundListener绑定的端口。


“入站流量”总结下来就是:请求到达pod内核时,先到PREROUTING链,然后由PREROUTING链重定向给ISTIO_INBOUND链。
在ISTIO_INBOUND上,除了15008、15020、15021、15090这4个端口不予拦截,其他端口统统重定向到ISTIO_IN_REDIRECT链进行处理。
ISTIO_IN_REDIRECT链会把所有请求都重定向到15006这个入站侦听器进行处理,然后根据envoy的内部规则(就是我们通过控制平面下发的配置),进行流量代理。


(3)那么对于出站流量来说,都是通过ISTIO_OUTPUT规则处理。
所有到达OUTPUT的请求,都会被转交给ISTIO_OUTPUT这个自定义链进行处理(-A OUTPUT -p tcp -j ISTIO_OUTPUT)。
如果原地址是127.0.0.6/32,并且输出接口是lo本地回环,就直接返回,不进行流量拦截。(-A ISTIO_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN)
如果目标地址不是127.0.0.1/32,但输出接口是lo,且UID是1337,那么就交给ISTIO_IN_REDIRECT链处理。(-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --uid-owner 1337 -j ISTIO_IN_REDIRECT)
如果输出接口是lo,但UID不是1337,就直接RETURN,不予拦截。
如果出去的请求的UID是1337,直接RETURN,不予拦截。
如果目标地址不是127.0.0.1/32,但从lo接口输出,且Gid是1337,就转发到ISTIO_IN_REDIRECT链处理。
如果输出接口是lo,但gid不是1337的,就直接RETURN,不予拦截。
如果gid是1337,也是直接RETURN,不予拦截。
如果目标地址是127.0.0.1/32,直接RETURN,不予拦截。
其余的全部交由ISTIO_REDIRECT链处理。
ISTIO_REDIRECT链会把这些请求都转发到15001端口处理,然后根据envoy内部的配置处理请求。


出站流量总结:
原地址是127.0.0.6/32,流量从lo出去,这种一般都是业务程序和sidecar代理之间的通信,所以这种没有必要进行拦截,就直接RETURN了。
一般-o lo的,基本都代表是业务程序和sidecar代理之间的通信,也就是内部通信。
那么如果目标地址不是127.0.0.1/32,但是流量要从lo出去,且uid是1337,这种请求有可能是sidecar本身的出向流量,所以要交给ISTIO_IN_REDIRECT链处理(经过一系列流量规则处理后,在对外发出)。

4.1 Isito入站请求拦截机制

在这里插入图片描述

4.2 Isito出站请求拦截机制

在这里插入图片描述

5. Istio-proxy容器和相关的Listener

5.1 istio-proxy代理容器

Istio-proxy即所谓的sidecar容器,它运行两个进程
(1)pilot-agent

  • 基于k8s api server为envoy初始化出可用的boostrap配置文件并启动envoy;
  • 监控并管理envoy的运行状态,包括envoy出错时重启envoy,以及envoy配置变更后将其重载(热重启)等;

(2)envoy

  • envoy由pilot-agent进程基于生成bootstrap配置进行启动(pilot-agent是envoy的管理进程),而后根据配置中指定的pilot地址(Istiod地址),通过xDS API获取动态配置信息;
  • Sidecar形式的Envoy通过流量拦截机制为应用程序实现入站和出站代理功能;


    这也是为什么不把Sidecar直接称为Envoy的原因,就是因为Sidecar中不单单只有envoy一个进程。

5.1.1 在pod中查看pilot-agent和envoy进程

在这里插入图片描述

5.2 istio-proxy容器及其Listener

(1)Envoy的bootstrap配置文件由pilot-agent负责生成,而生效的大多配置则定义成了dynamic resources,并通过xDS静态集群指向的Pilot获取;

  • 而这些配置则来自于VirtualService、DestinationRule、Gateway和ServiceEntry资源对象等提供的配置;

(2)由Pilot基于Kubernetes发现的网格内的各Service,均会被自动转换为下发给各Sidecar实例的Listener、Route、Cluster和Endpoint的相关配置;

  • 为了能够让Sidecar Envoy代理网格内进出各Service的流量,所以需要进行流量劫持,而后由Envoy根据请求特征,将流量派发至合适的Listener,进而完成后续的流量路由、负载均衡等;

5.2.1 使用curl命令查看listener

[root@k8s-master1 ~]# kubectl exec -it demoappv10-54757f48d6-8gn5q -- sh
[root@demoappv10-54757f48d6-8gn5q /]# curl 127.0.0.1:15000/listeners # 这就是之前学的envoy的管理接口操作
bf25d299-6401-40c0-8f31-66d099be4e36::0.0.0.0:15090
4e94dc50-f588-441b-ade8-e97653155810::0.0.0.0:15021
10.200.5.97_443::10.200.5.97:443
10.200.141.24_15012::10.200.141.24:15012
10.200.0.1_443::10.200.0.1:443
10.200.145.163_15443::10.200.145.163:15443
10.200.0.10_53::10.200.0.10:53
10.200.141.24_443::10.200.141.24:443
10.200.212.98_443::10.200.212.98:443
10.200.145.163_443::10.200.145.163:443
10.200.145.163_31400::10.200.145.163:31400
0.0.0.0_8080::0.0.0.0:8080
0.0.0.0_15014::0.0.0.0:15014
0.0.0.0_9411::0.0.0.0:9411
0.0.0.0_20001::0.0.0.0:20001
10.200.0.10_9153::10.200.0.10:9153
10.200.43.119_14268::10.200.43.119:14268
0.0.0.0_8082::0.0.0.0:8082
10.200.145.163_15021::10.200.145.163:15021
10.200.36.11_3000::10.200.36.11:3000
0.0.0.0_16685::0.0.0.0:16685
0.0.0.0_80::0.0.0.0:80
0.0.0.0_15010::0.0.0.0:15010
0.0.0.0_9090::0.0.0.0:9090
10.200.43.119_14250::10.200.43.119:14250
virtualOutbound::0.0.0.0:15001  # 虚拟出向侦听器
virtualInbound::0.0.0.0:15006 # 虚拟入向侦听器

# 查看集群信息,内容太多,这里就不贴出来了
[root@demoappv10-54757f48d6-8gn5q /]# curl 127.0.0.1:15000/clusters

5.2.2 使用pilot-agent查看listener

该方式主要用在pod没有安装curl命令时使用

[root@k8s-master1 ~]# kubectl exec -it proxy-645cd54b84-4ctnb -c istio-proxy -- pilot-agent request GET /listeners
9deb871d-cb65-4184-8fb2-66863d4b90dc::0.0.0.0:15090
6cbacdb6-cfff-478f-ba72-18a440f54bf9::0.0.0.0:15021
10.200.145.163_15443::10.200.145.163:15443
10.200.145.163_443::10.200.145.163:443
10.200.141.24_15012::10.200.141.24:15012
10.200.145.163_31400::10.200.145.163:31400
10.200.0.1_443::10.200.0.1:443
10.200.141.24_443::10.200.141.24:443
10.200.212.98_443::10.200.212.98:443
10.200.0.10_53::10.200.0.10:53
10.200.5.97_443::10.200.5.97:443
0.0.0.0_9090::0.0.0.0:9090
0.0.0.0_80::0.0.0.0:80
0.0.0.0_8080::0.0.0.0:8080
10.200.0.10_9153::10.200.0.10:9153
10.200.36.11_3000::10.200.36.11:3000
0.0.0.0_9411::0.0.0.0:9411
0.0.0.0_8082::0.0.0.0:8082
0.0.0.0_15010::0.0.0.0:15010
0.0.0.0_15014::0.0.0.0:15014
10.200.145.163_15021::10.200.145.163:15021
0.0.0.0_16685::0.0.0.0:16685
10.200.43.119_14268::10.200.43.119:14268
10.200.43.119_14250::10.200.43.119:14250
0.0.0.0_20001::0.0.0.0:20001
virtualOutbound::0.0.0.0:15001 # 虚拟出向侦听器
virtualInbound::0.0.0.0:15006 # 虚拟入向侦听器

5.3 istio-proxy Listener

Envoy Listener支持绑定于IP Socket或Unix Domain Socket之上,也可以不予绑定,而是接收由其它的Listener转发来的数据。

  • VirtualOutboundListener通过一个端口(15001)接收所有的出向流量,而后再按照请求的端口分别转发给相应的Listener进行处理;
  • VirtualInboundListener(15006)的功能相似,但它主要用于处理入向流量;

5.3.1 Virtual Outbound Listener

(1)iptables将其所在的Pod中的外发流量拦截后,转发至监听于15001的Listener,而该Listener通过在配置中将use_origin_dest参数设置为true,从而实现将接收到的请求转交给同请求原目标地址关联的Listener之上;

(2)若不存在可接收转发报文的Listener,则Envoy将根据Istio的全局配置选项outboundTrafficPolicy(外发流量配置)参数的值决定如何进行处理。

  • ALLOW_ANY:允许外发至任何服务的请求(默认策略),无论目标服务是否存在于Pilot的注册表中。此时,没有匹配的目标Listener的流量将由该侦听器上tcp_proxy过滤器指向的Passthrough Cluster(透传集群)进行透传(直接转发出去);
  • REGISTRY_ONLY:仅允许外发请求至注册于Polit中的服务;此时,没有匹配的目标Listener的流量将由该侦听器上tcp_proxy过滤器指向的BlackHoleCluster(黑洞集群)将流量直接丢弃;

配置示例

spec:
  meshConfig:
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY
5.3.1.1 流量外发修改方式
[root@k8s-master1 ~]# istioctl profile dump demo|grep 'meshConfig:' -A 3
  meshConfig:
    accessLogFile: /dev/stdout
    defaultConfig:
      proxyMetadata: {}

默认的流量外发策略就是ALLOW_ANY,如果要修改,就导出该文件添加对应字段,重新istioctl apply就行,istio会重新应用新增的这部分配置。

5.3.2 Virtual Inbound Listener

(1)入向流量劫持
较早版本的Istio基于同一个VirtualListener在15001端口上同时处理入站和出站流量;
自1.4版本起,Istio引入了REDIRECT代理模式,它通过监听于15006端口的专用VirtualInboundListener处理入向流量代理以规避潜在的死循环问题;

(2)入向流量处理
对于进入到侦听器“0.0.0.0:15006”的流量,VirtualInboundListener会在filterChains中,通过一系列的filter_chain_match对流量进行匹配检测,以确定应该由哪个或哪些过滤器进行流量处理;


(3)入向流量处理机制
VirtualInboundListener会将接收到请求,经过一系列filter_chain_match,对入站流量进行匹配检测,匹配到的流量,将由相应的filters进行处理。
这有别于VirtualOutboundListener对入向流量的处理方式,并非将流量分发给独立的Egress Listener进行处理;

在这里插入图片描述
在这里插入图片描述

5.3.2.1 配置分析

导出配置

[root@k8s-master1 ~]# kubectl exec -it proxy-645cd54b84-4ctnb -c istio-proxy -- pilot-agent request GET /config_dump # 这样内容超级多,可以dump下来,通过json分析网站去分析

事实上,入向流量的相关过滤器匹配条件及流量处理机制,也可以简单地通过istioctl proxy-config命令来获取。
仍然以监听于8080/tcp端口提供服务的demoapp应用的某实例为例

在这里插入图片描述

5.4 istio-proxy Clusters

在这里插入图片描述
在这里插入图片描述

6. Sidecar CRD

如果整个网格中的服务数量非常多的话,那么每一个sidecar上都会存在大量的出向侦听器的定义和出向集群的定义。
但考虑到我们自己实际微服务的结构,对于某一些特定的服务来说,其中有很多出向侦听器的定义和出向集群的定义是没有用的。
入下图:
在这里插入图片描述
对于Product Page而言,不管是访问Reviews还是访问Details都是必须的,但是把Ratings的出向侦听器和出向集群配置在Product Page上是浪费的。
同样的,对Ratings而言,配置他前面的任何服务的出向侦听器和出向集群都是浪费的,因为它本事就已经是最底层、最上游的服务了,它不可能会去访问下游的服务。


那么如何避免这种情况呢?可以通过定义Sidecar cr资源,来调整相应配置。
Sidecar CRD提供了为Sidecar Envoy微调其用于workload(pod)间通信时支持的端口集和协议等配置的方式;

6.1 Sidecar CRD介绍

默认情况下,Istio会配置每一个Sidecar Envoy能够与同一网格内所有的workload实例通信,并且能够在与其代理的workload相关的所有端口上接收流量 ;
另外,转发来自其代理的workload实例(pod)的出向流量时,Sidecar CRD资源对象还能够限制Sidecar Envoy可以访问的外部服务集;

6.2 Sidecar CRD的生效机制

(1)Sidecar CRD通过workloadSelector字段挑选同一名称空间中的一个或多个workload实例来应用其提供的配置;


(2)对于未提供workloadSelector字段Sidecar资源,其配置将应用于同一名称空间中的所有workload实例;


(3)namespace中同时存在带有workloadSelector字段以及未附带此字段的Sidecar 资源对象时,workload实例将优先应用带有此字段的Sidecar对象。


(4)每个namespace中仅应该提供一个未附带workloadSelector字段的Sidecar资源,否则其配置结果将难以确定。


(5)另外,每个workload也应该仅应用一个带有workloadSelector字段的Sidecar资源,否则其行为同样难以明确。

6.2 Sidecar配置示例

6.2.1 示例一

6.2.1.1 配置前的出向侦听器
[root@k8s-master1 ~]# istioctl pc listeners proxy-645cd54b84-4ctnb

在这里插入图片描述

6.2.1.2 创建Sidecar资源
[root@k8s-master1 ~]# mkdir Sidecar-CRD
[root@k8s-master1 ~]# cd Sidecar-CRD
[root@k8s-master1 Sidecar-CRD]# vim sidecar.yaml
[root@k8s-master1 Sidecar-CRD]# kubectl api-resources |grep Sidecar
sidecars                                       networking.istio.io/v1beta1            true         Sidecar
[root@k8s-master1 Sidecar-CRD]# !vi
vim sidecar.yaml
[root@k8s-master1 Sidecar-CRD]# vim sidecar.yaml
[root@k8s-master1 Sidecar-CRD]# cat sidecar.yaml
apiVersion: networking.istio.io/v1beta1
kind: Sidecar # Sidecar资源定义
metadata:
  name: proxy-sidecar
  namespace: default
spec:
  workloadSelector:
    labels:
      app: proxy # 只要有该标签的pod中的sidecar,都受该配置限制
  egress:
  - hosts:
    - "./*" # 表示当前ns下(metadata.namespace)的所有svc都配置为出向侦听器

上述配置含义:在该Sidecar所在ns下,只要有app: proxy这个标签的,都会受到workloadSelector限制,从而变为出向侦听器。
默认情况下,所有ns下的所有svc,都会被配置成出向侦听器。

[root@k8s-master1 Sidecar-CRD]# kubectl apply -f sidecar.yaml
sidecar.networking.istio.io/proxy-sidecar created

[root@k8s-master1 Sidecar-CRD]# kubectl get sidecar
NAME            AGE
proxy-sidecar   32s
6.2.1.3 检查配置是否生效

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值