实践envoy

已知envoy工作流程

  1. istio中envoy的动态配置: Envoy 的动态配置通过 xDS 协议进行传输。在 Istio 中,istiod(Istio Pilot)充当了 xDS 服务器的角色,负责向 Envoy 提供动态配置。动态配置主要包括以下几个方面:

    • Listener 动态配置(LDS):定义 Envoy 监听的地址和端口以及相应的过滤器链配置。
    • Cluster 动态配置(CDS):定义后端服务的集群配置,包括集群名称、类型、负载均衡策略和后端服务的主机和端口信息。
    • Endpoint 动态配置(EDS):定义每个集群中后端服务的实例和地址信息。

    这些动态配置信息会根据 Istio 中定义的规则和策略进行实时更新和调整。Pilot 从服务注册和发现组件(如 Kubernetes API Server)获取服务的信息,然后将其转换为 Envoy 可识别的配置格式,并通过 xDS 协议将其传递给 Envoy。

  2. 在 istio 的服务网格中,front-tomcat 访问到 bill-service 的流量流向如下:

    1. 前端应用 front-tomcat 发出请求到本地的 Envoy 代理。
    2. Envoy 代理根据规则配置(如 VirtualService 和 DestinationRule)将请求路由到目标服务 bill-service。
    3. Envoy 代理检查 Sidecar 的缓存,如果缓存中没有目标服务的地址信息,它会向 Pilot 发送请求以获取最新的 Endpoint 配置。
    4. Pilot 会根据服务注册信息和 Istio 的规则配置,生成并提供包含目标服务的 Endpoint 配置给 Envoy。
    5. Envoy 获取到最新的 Endpoint 配置后,使用负载均衡策略(如 ROUND_ROBIN)选择一个后端服务的实例。
    6. Envoy 将请求转发到选定的后端服务实例,并在转发过程中应用任何额外的策略和过滤器(如负载均衡、重试、熔断等)。
    7. 后端服务 bill-service 接收到请求并进行处理,然后将响应返回给 Envoy。
    8. Envoy 将响应返回给 front-tomcat。

通过上述流程,front-tomcat 可以通过 Envoy 代理与 bill-service 进行通信,并且流量的路由、负载均衡和策略等都由 Envoy 和 Istio 控制平面进行管理和调整。

探索envoy具体信息

[root@k8s-master ~/servicemesh]#kubectl -n istio-demo exec front-tomcat-v1-74b8ff99db-lbk79 -- curl -s bill-service:9999
this is bill-service-v1

带着疑问

  • istio中envoy的动态配置到底长什么样子?
  • 在istio的网格内,front-tomcat访问到bill-service,流量的流向是怎么样的?

istio-proxy容器启动后,监听15000端口

[root@k8s-master ~/servicemesh]#kubectl -n istio-demo exec -it front-tomcat-v1-74b8ff99db-lbk79 -c istio-proxy -- sh
$ netstat -tnlp
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:15000         0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      17/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      17/envoy            
tcp        0      0 0.0.0.0:15006           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      17/envoy            
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      -                   
tcp6       0      0 :::8009                 :::*                    LISTEN      -                   
tcp6       0      0 :::8778                 :::*                    LISTEN      -                   
tcp6       0      0 :::15020                :::*                    LISTEN      1/pilot-agent       
tcp6       0      0 :::8080                 :::*                    LISTEN      -                   

$ curl localhost:15000 -I
HTTP/1.1 200 OK
content-type: text/html; charset=UTF-8
cache-control: no-cache, max-age=0
x-content-type-options: nosniff
date: Sun, 21 May 2023 13:30:07 GMT
server: envoy
transfer-encoding: chunked

$ curl localhost:15000/help

$ curl localhost:15000/config_dump

没istio之前流量

[root@k8s-master ~/servicemesh]#kubectl -n istio-demo exec front-tomcat-v1-74b8ff99db-lbk79 -- curl -s bill-service:9999
this is bill-service-v1

image-20230521212617500

之前的认知是

  • 集群内访问svc,如bill-service:9999
  • coredns解析出cluster-ip
  • route表解析出eth0
  • 流量转发给宿主机
  • 宿主机iptables匹配cluster-ip
  • iptables转发给目标pod

加入istio服务网格后

为什么流量通过istio可以定制比例关系里,从五五开,成了九比一。

回顾iptables

iptables

istio注入pod流程

      initContainers:
      - args:
        - istio-iptables
        - -p
        - "15001"
        - -z
        - "15006"
        - -u
        - "1337"
        - -m
        - REDIRECT
        - -i
        - '*'
        - -x
        - ""
        - -b
        - '*'
        - -d
        - 15090,15021,15020
        - --log_output_level=default:info

Istio 给应用 Pod 注入的配置主要包括:

  • Init 容器 istio-init

    Istio 在 pod 中注入的 Init 容器名为 istio-init,作用是为 pod 设置 iptables 端口转发。

    我们在上面 Istio 注入完成后的 YAML 文件中看到了该容器的启动命令是:

    istio-iptables -p 15001 -z 15006 -u 1337 -m REDIRECT -i '*' -x "" -b '*' -d 15090,15021,15020
    

    Init 容器的启动入口是 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)。
    

    以上传入的参数都会重新组装成 iptables 规则,关于 Istio 中端口用途请参考 Istio 官方文档

    这条启动命令的作用是:

    • 将应用容器的所有入站流量都转发到 sidecar的 15006 端口(15090 端口(Envoy Prometheus telemetry)和 15020 端口(Ingress Gateway)除外,15021(sidecar健康检查)端口)
    • 将所有出站流量都重定向到 sidecar 代理(通过 15001 端口)
    • 上述规则对id为1337用户除外,因为1337是istio-proxy自身的流量

    istio-init容器接管流量

    该容器存在的意义就是让 sidecar 代理可以拦截pod所有的入站(inbound)流量以及出站(outbound)流量,这样就可以实现由sidecar容器来接管流量,进而实现流量管控。

    因为 Init 容器初始化完毕后就会自动终止,因为我们无法登陆到容器中查看 iptables 信息,但是 Init 容器初始化结果会保留到应用容器和 sidecar 容器中。

命令检查istio做了什么

  • pod网络规则的修改,只能查看pod的网络名称空间
  • 通过pod的namespace检查iptables
[root@k8s-slave1 ~]#crictl ps |grep front
1d995b84779e4       f5598a5c8445b       2 days ago          Running             istio-proxy         0                   a8ea62352c00a       front-tomcat-v1-74b8ff99db-lbk79
36bcf7734f625       6bdbd1699d80c       2 days ago          Running             front-tomcat        0                   a8ea62352c00a       front-tomcat-v1-74b8ff99db-lbk79
[root@k8s-slave1 ~]#

# 获取容器pid
[root@k8s-slave1 ~]#crictl inspect 36b |grep pid
    "pid": 124193,
            "pid": 1
            "type": "pid"

# 根据进程id,进入namespace,再输入exit即可退出
[root@k8s-slave1 ~]#nsenter -n --target 124193
[root@k8s-slave1 ~]#iptables -t nat -vnL

查出如下iptables规则

[root@k8s-slave1 ~]#iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 93537 packets, 5612K bytes)
 pkts bytes target     prot opt in     out     source               destination         
93536 5612K ISTIO_INBOUND  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain INPUT (policy ACCEPT 93536 packets, 5612K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 7081 packets, 665K bytes)
 pkts bytes target     prot opt in     out     source               destination         
  189 11340 ISTIO_OUTPUT  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain POSTROUTING (policy ACCEPT 7148 packets, 669K 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
93536 5612K 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
    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

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
  122  7320 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           
   67  4020 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         
   67  4020 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 15001

上述输出是 iptables 命令的结果,它显示了针对网络数据包的转发规则和网络地址转换(NAT)规则。下面是对输出进行解释:

  • Chain PREROUTING:这是数据包进入网络堆栈时进行的第一个操作链。在这里,有一条规则被应用,将来自任何源地址和任何目标地址的 TCP 数据包重定向到 ISTIO_INBOUND 链。
  • Chain INPUT:这是在数据包到达本地系统时进行的操作链。在此示例中,没有应用任何规则。
  • Chain OUTPUT:这是数据包从本地系统发出时进行的操作链。这里有一条规则,将本地系统中的 TCP 数据包重定向到 ISTIO_OUTPUT 链。
  • Chain POSTROUTING:这是数据包离开网络堆栈之前进行的最后一个操作链。在这里,没有应用任何规则。
  • Chain ISTIO_INBOUND:这是一个自定义的操作链,用于处理入站的 Istio 流量。在此操作链中,有多条规则用于处理特定的 TCP 目标端口,如 150081509015021
  • Chain ISTIO_IN_REDIRECT:这是另一个自定义的操作链,用于重定向 Istio 流量。它包含一条规则,将流量重定向到端口 15006
  • Chain ISTIO_OUTPUT:这是用于处理出站的 Istio 流量的自定义操作链。在此操作链中,有多条规则用于过滤特定的本地流量,根据所有者的 UID 和 GID 进行匹配。
  • Chain ISTIO_REDIRECT:这是另一个自定义的操作链,用于重定向 Istio 流量。它包含一条规则,将流量重定向到端口 15001

通过这些规则,iptables 可以根据定义的规则来控制网络数据包的转发和转换,以实现网络流量的控制和定制化。请注意,这只是输出的一个片段,可能还有其他规则和链在系统中定义。

Istio端口解释

在 Istio 中,存在一些特定的端口,用于处理不同类型的流量和功能。下面是对这些端口的解释:

  1. 15008:该端口用于 Istio 的入站代理(Ingress Proxy)与 Pilot Agent 之间的通信。Pilot Agent 是 Istio 的核心组件之一,负责管理服务注册、流量路由和负载均衡等功能。

  2. 15090:该端口用于 Istio 的入站代理与 Istio 遥测组件(Telemetry)之间的通信。Telemetry 组件负责收集、存储和展示关于服务的度量指标、日志和分布式追踪数据。

  3. 15021:该端口用于 Istio 的入站代理与 Mixer 组件之间的通信。Mixer 是 Istio 的策略和遥测逻辑的中心组件,负责执行访问控制、策略评估和遥测数据的收集。

  4. 15006:该端口用于 Istio 的入站和出站代理之间的通信,以及出站代理与 Mixer 组件之间的通信。它主要用于流量重定向,将流量导向到特定的 Istio 组件或代理。

  5. 15001:该端口用于 Istio 的出站代理(Egress Proxy)与 Istio 的控制平面组件之间的通信。出站代理负责将流量发送到外部服务,并将其纳入 Istio 的监控和控制之下。

这些端口是 Istio 在 Kubernetes 等环境中所使用的默认端口,可以通过配置进行修改。它们在 Istio 的架构中扮演关键角色,用于实现服务之间的流量管理、策略执行和遥测数据收集等功能。

记住15001/15006端口

Istio-Proxy在与Istio服务网格的通信过程中使用了一些特定的端口,其中包括15001和15006端口。以下是它们的作用解释:

  1. 端口15001:这是Istio-Proxy的主要监听端口,也被称为Envoy的控制平面接口。通过这个端口,Istio-Proxy与Istio控制平面的组件进行通信,例如Pilot。Istio-Proxy会接收来自控制平面的配置更新和指令,以便了解目标服务的发现信息、路由规则、负载均衡策略等。通过与控制平面的交互,Istio-Proxy能够动态地调整自身的行为,以实现流量管理和安全策略。
  2. 端口15006:这是Istio-Proxy的用于服务发现的监听端口,也称为Envoy的服务发现接口。Istio-Proxy会监听这个端口,并接收来自Pilot或其他服务发现组件的服务发现信息。这些信息包括目标服务的网络地址、健康状态、负载情况等。通过与服务发现组件的交互,Istio-Proxy可以了解到服务网格中的可用服务,并根据需要对流量进行负载均衡和路由。

总结起来,端口15001用于与Istio的控制平面通信,接收配置和指令,而端口15006用于与服务发现组件通信,接收服务发现信息。这些端口的使用使得Istio-Proxy能够与服务网格中的其他组件进行协作,并实现流量管理、安全性和服务发现等关键功能。

出站流量

注入istio的pod,容器内出口流量,会走到15001端口

[root@k8s-master ~]#
[root@k8s-master ~]#kubectl -n istio-demo exec -it front-tomcat-v1-74b8ff99db-lbk79 -c istio-proxy -- bash
istio-proxy@front-tomcat-v1-74b8ff99db-lbk79:/$ netstat -tunlp
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:15000         0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      17/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      17/envoy            
tcp        0      0 0.0.0.0:15006           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      17/envoy            
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      17/envoy            
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      -                   
tcp6       0      0 :::8009                 :::*                    LISTEN      -                   
tcp6       0      0 :::8778                 :::*                    LISTEN      -                   
tcp6       0      0 :::15020                :::*                    LISTEN      1/pilot-agent       
tcp6       0      0 :::8080                 :::*                    LISTEN      -                   
udp6       0      0 :::24884                :::*                                -                   
istio-proxy@front-tomcat-v1-74b8ff99db-lbk79:/$

根据您提供的输出,我可以看出 Istio 代理(istio-proxy)在容器中监听了一些端口。根据这些端口的监听情况,可以得出 Istio 流量的走向顺序:

  1. 流量从应用容器内部的 localhost 地址(127.0.0.1)的端口 15000 进入 Istio 代理(envoy)。
  2. Istio 代理监听在容器的所有 IP 地址的端口 15001,这意味着流量可以通过容器的 IP 地址加上该端口进入代理。
  3. 流量从容器的 localhost 地址(127.0.0.1)的端口 15004 进入 Pilot Agent(pilot-agent)。Pilot Agent 是 Istio 的核心组件之一,负责管理服务注册、流量路由和负载均衡等功能。
  4. Istio 代理监听在容器的所有 IP 地址的端口 15006,这是用于流量重定向的端口。流量可以通过容器的 IP 地址加上该端口进入代理。
  5. Istio 代理监听在容器的所有 IP 地址的端口 15021,这也是用于流量重定向的端口。流量可以通过容器的 IP 地址加上该端口进入代理。
  6. Istio 代理监听在容器的所有 IP 地址的端口 15090,用于与 Istio 的遥测组件进行通信。流量可以通过容器的 IP 地址加上该端口进入代理。

这些端口的监听情况显示了 Istio 代理如何接收来自不同源的流量,并将其引导到适当的组件进行处理,例如 Pilot Agent 和遥测组件。这有助于实现 Istio 的流量管理、策略控制和遥测数据收集等功能。

image-20230523181844408

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2024-03-31 19:44:28

results matching ""

    No results matching ""