istio sidecar流量處理機制及配置


sidecar 介紹

在istio的流量管理等功能,都需要通過下發的配置應用到應用運行環境執行后生效,負責執行配置規則的組件在service mesh中承載應用代理的實體被稱為side-car

Istio對流量策略管理等功能無須對應用程序做變動,

這種對應用服務完全非侵入的方式完全依賴於Side-car,應用的流量有Sidecar攔截並進行認證、鑒權、策略執行等治理功能。在Kubernetes平台中,Side-car容器於應用容器在同一個Pod中並共享網絡名詞控件,因此Side-car容易可以通過iptables規則攔截進出流量進行管理。

sidecar的注入

sidecar是service mesh無侵入式架構的應用模式,在使用sidecar部署服務網格時,無需再每個應用節點運行服務代理,但是需要在每個應用程序中部署一個sidecar容器,來接管所有進出流量。

Sidecar會將額外容器注入到 Pod 模板中。Istio中的數據平面組件所需的容器有:

  • istio-init 用於設置容器的iptables規則,目的是為了接管進出流量。在應用容器前啟動並運行完成其生命周期,多個init容器按順序依次完成。
  • istio-proxy 基於envoy的sidecar的代理。

sidecar被注入的方式

  • 手動注入,使用 istioctl 修改容器模板並添加前面提到的兩個容器的配置。不論是手動注入還是自動注入,Istio 都從 istio-sidecar-injector 和的 istio 兩個 Configmap 對象中獲取配置。 refer-istio-sidecar-injector

  • 自動注入,在部署應用是,istio自動將sidecar注入到pod。這是istio推薦的方法,Istio在基於Kubernetes平台之上,需要在部署應用之前,對要標記部署應用程序的名稱空間標記 kubectl label namespace default istio-injection=enabled 這個操作是對名稱空間級別生效的。而后所部署的Pod中會注入sidecar執行上面sidecar容器的操作。

istio injector 注入原理

Sidecar Injector是Istio中實現自動注入Sidecar的組件,它是以Kubernetes准入控制器 AdmissionController 的形式運行的。Admission Controller 的基本工作原理是攔截Kube-apiserver的請求,在對象持久化之前、認證鑒權之后進行攔截。

Admission Controller有兩種:一種是內置的,另一種是用戶自定義的。

Kubernetes允許用戶以Webhook的方式自定義准入控制器,Sidecar Injector就是這樣一種特殊的MutatingAdmissionWebhook。

Sidecar Injector只在創建Pod時進行Sidecar容器注入,在Pod的創建請求到達 Kube-apiserver 后,首先進行認證鑒權,然后在准入控制階段,Kube-apiserver以REST的方式同步調用Sidecar Injector Webhook服務進行init與istio-proxy容器的注入,最后將Pod對象持久化存儲到etcd中。

sidecar容器

sidecar容器內部運行着 pilot-agentenvoy

Pilot-agent:基於kubernetesAPI資源對象為envoy初始化可用的bootstrap配置進行啟動,在運行后管理envoy運行狀態,如配置變更,出錯重啟等。

envoy:數據平面的執行層,由 pilot-agent 所啟動的,從xDS API動態獲取配置信息。Envoy並通過流量攔截機制處理入棧及出棧的流量。

envoy的listener

在運行在Kubernetes平台之上的istio,Envoy是通過Pilot將Kubernetes CRD資源 DestnationRule VirtualService Gateway等資源提供的配置,生成對應的Envoy配置。

每個sidecar中的envoy都會生成眾多的配置,這些配置在每一個網格中會對對應的流量進行攔截管理。

通過envoy admin interface查看對應生產的envoy資源配置信息

[root@master01 ~]# kubectl exec reviews-v1-6549ddccc5-k995p -c istio-proxy -- curl -s 127.0.0.1:15000/listeners
97591f7a-0cbf-469a-a5f2-c9a76a3d0ced::0.0.0.0:15090
e523c9a4-da71-439f-885f-020f70349f21::0.0.0.0:15021
10.96.56.243_10251::10.96.56.243:10251
10.0.0.6_10250::10.0.0.6:10250
10.244.0.51_8443::10.244.0.51:8443
10.0.0.5_10250::10.0.0.5:10250
10.97.190.96_10252::10.97.190.96:10252
10.96.0.1_443::10.96.0.1:443
10.96.0.10_53::10.96.0.10:53
10.105.226.65_80::10.105.226.65:80
10.105.226.65_82::10.105.226.65:82
0.0.0.0_80::0.0.0.0:80
10.0.0.6_4194::10.0.0.6:4194
10.105.226.65_443::10.105.226.65:443
10.105.226.65_81::10.105.226.65:81
10.0.0.5_4194::10.0.0.5:4194
10.102.134.81_14250::10.102.134.81:14250
10.107.39.113_9090::10.107.39.113:9090
0.0.0.0_10255::0.0.0.0:10255
0.0.0.0_20001::0.0.0.0:20001
0.0.0.0_9090::0.0.0.0:9090
10.96.0.10_9153::10.96.0.10:9153
10.102.134.81_14268::10.102.134.81:14268
0.0.0.0_9411::0.0.0.0:9411
10.101.93.145_8000::10.101.93.145:8000
10.99.79.173_443::10.99.79.173:443
10.105.226.65_8080::10.105.226.65:8080
0.0.0.0_9080::0.0.0.0:9080
10.108.161.174_3000::10.108.161.174:3000
virtualOutbound::0.0.0.0:15001
virtualInbound::0.0.0.0:15006
..

istio使用的端口

Port Protocol Description Pod-internal only
15000 TCP envoy管理端口 Yes
15001 TCP envoy出站端口 No
15006 TCP envoy入站端口 No
15008 TCP envoy隧道端口 No
15020 HTTP 從istio-agent envoy 應用 合並prometheus遙測 No
15021 HTTP 健康檢查端口 No
15090 HTTP Envoy Prometheus telemetry No

envoy的listener通過綁定與IP Socket或者Unix Domain Socket,接收轉發來的數據。

VirtualOutboundListener | VirtualIntboundListener 通過一個端口接收所有出/入站流量,並根據目標端口來區分使用哪個Listener進行處理。

iptables通過對應規則攔截發往所在Pod的流量並轉發到對應的Envoy接收端口(如入站流量為15006),該Listener通過配置將請求轉發到請求原目標地址關聯的Listener之上。envoy原始目標地址

若不存在對應的listener則根據全局配置選項進行處理

  • ALLOW_ANY:允許外發至任何服務的請求,沒有匹配到目標Listener的流量則由tcp_proxy過濾器指向的PassthroughCluster。
  • REGISTRY_ONLY:僅允許外發請求至注冊過的服務,沒有匹配到目標Listener的流量,則由tcp_proxy通過BlackHoleCluster丟棄。

監聽端口配置參數bind_to_port的值為false,意味着該Listener並未真正綁定套接字上,而是通過對應的入站/出站Linstener接收兵轉發流量。

sidecar 流量的攔截

sidecar通過注入到Pod中的init,執行在 pod 命名空間中設置 iptable 規則來完成流量捕獲並管理。

通過查看nsenter 命令可以查看對應實現的內容。

iptables在NAT表中新建了4條鏈,ISTIO_INBOUND、ISTIO_IN_REDIRECT、ISTIO_OUTPUT
和 ISTIO_REDIRECT

  • 當進入Pod的流量會被PREROUTING 攔截處理。根據規則將數據包轉發到ISOTIO_INBOUND-A PREROUTING -p tcp -j ISTIO_INBOUND
  • ISTIO_INBOUND處理對應的規則,當遇到15008 , 22 15090 15021 15020 不做處理,return給上一個鏈。 關於iptables return
  • 剩余流量從ISTIO_INBOUND 轉交給 ISTIO_IN_REDIRECT -A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT
  • ISTIO_IN_REDIRECT 將流量交給15006端口應用處理。
  • Envoy根據數據包的目的地址查看 Inbound方向的監聽器配置,根據監聽器及路由、Cluster、
    Endpoint等配置,決定是否將數據包轉發到應用。
  • OUTPUT的流量由規則 -A OUTPUT -p tcp -j ISTIO_OUTPUTISTIO_OUTPUT ` 鏈處理。
[root@master01 ~]# nsenter -t `ps -ef|grep details|grep envoy|awk '{print $2}'` -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
-A OUTPUT -p tcp -j ISTIO_OUTPUT
-A ISTIO_INBOUND -p tcp -m tcp --dport 15008 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 22 -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
-A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT 
# 到此入棧流量處理完成
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006

# 這里開始執行出站流量
# 原地址為127.0.0.6/32 不做處理
-A ISTIO_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN
# 默認目標127.0.0.1/32--uid-owner 1337的由ISTIO_IN_REDIRECT處理
-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
-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
# 默認所有ISTIO_OUTPUT鏈的流量都由ISTIO_REDIRECT
-A ISTIO_OUTPUT -j ISTIO_REDIRECT
# ISTIO_REDIRECT 的流量 默認有envoy進行處理轉發到對應的應用
-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001

Istio中目前有兩種流量攔截模式:REDIRECT模式和TPROXY模式。

TPROXY transparent proxy 透明代理,操作的是mangle表,同時需要原始客戶端socket設置
IP_TRANSPARENT選項,此模式同時保留源IP地址和目標IP地址和端口。

REDIRECT :端口重定向,將流量NAT至envoy,此模式會丟失源IP。

sidecar資源配置

Sidecar這個資源清單描述了Sidecar代理的配置,從而管理他所連接的workload實例的流量。

  • workloadSelector:選擇sidecar應用此配置的Pod,如省略則為該名稱空間的所有workload
    • lables: 配置pod的標簽
  • ingress:用於指定連接workload的入站流量的sidecar配置,如省略,則從默認獲取。
    • port:Listener關聯的端口
    • bind:Listener綁定的IP,ingress不允許unix套接字
    • captureMode: 流量捕獲模式,僅Listener綁定到IP時適用。
      • DEFAULT 環境定義默認配置
      • IPTABLES :使用IPtables重定向流量
      • NONE 不捕獲。
  • egress: 用於指定workload的出站流量的sidecar配置,如省略,則繼承默認值
    • port:Listener關聯的端口
    • bind:Listener綁定的IP或套接字
    • captureMode: 流量捕獲模式,僅Listener綁定到IP時適用。
      • DEFAULT 環境定義默認配置
      • IPTABLES :使用IPtables重定向流量
      • NONE 不捕獲。
    • hosts:目標地址,namespace/dnsName格式顯示的一台或多台服務主機
  • outboundTrafficPolicy:出站流量策略的配置,不指定則繼承默認值。
    • mode
      • REGISTRY_ONLY:僅允許注冊到pilot的服務通過。
      • ALLOW_ANY:沒有配置的,允許流量的出站。

聲明一個出站流量

下面的示例在Sidecar名為的根命名空間中聲明了全局默認配置istio-config,該配置在所有命名空間中配置了sidecars,以僅允許將流量發送到同一命名空間中的其他workload以及istio-system命名空間中的服務 。

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: istio-config
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"

以下示例配置一個應用的出站與入站規則;在名稱空間prod-us1中聲明所有app: ratings 屬於該prod-us1/ratings 帶有標簽的Pod 。workload在端口9080上接受入站HTTP通信。然后,將通信轉發到偵聽Unix套接字的附加workload實例。在出口流量,除了允許發給istio-system 名稱空間任何端口任何Pod的流量,如果是9080端口,允許發送給prod-us1名稱空間下的所有的服務。

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: ratings
  namespace: prod-us1
spec:
  workloadSelector:
    labels:
      app: ratings
  ingress:
  - port:
      number: 9080
      protocol: HTTP
      name: somename
    defaultEndpoint: unix:///var/run/someuds.sock
  egress:
  - port:
      number: 9080
      protocol: HTTP
      name: egresshttp
    hosts:
    - "prod-us1/*"
  - hosts:
    - "istio-system/*"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM