istio組件介紹和啟動流程
Deployment 名稱 | Container和Port | Container和Port |
---|---|---|
istio-pilot | pilot: 8080,15010 | proxyv2: 15003,15005,15007 |
istio-galley | galley: 443,9093 | |
istio-egressgateway | proxyv2: 80,443,15090 | |
istio-ingressgateway | proxyv2: 80,443,31400,15011,8060,853,15030,15031,15090 | |
grafana | grafana: 3000 | |
istio-policy | mixer: 9093,42422 | proxyv2: 9091,15004,15090 |
istio-telemetry | mixer: 9093,42422 | proxyv2: 9091,15004,15090 |
prometheus | prometheus: 9090 | |
istio-citadel | citadel: 8086 | |
istio-sidecar-injector | sidecar-injector | |
istio-tracing | jaegertracing/all-in-one: 9411,16686 UDP:5775,6832,6831 | |
istio-ingress | proxyv2: 80,443 |
其中,流量的走向如下圖所示:
說明:紅色線表示控制流,黑色線表示數據流,藍色部分為Envoy和pilot相關組件
Istio核心組件與功能
istio主要有兩部分組成: 控制面和數據面。
- 數據面被稱為Sidecar: 會在業務Pod中註入一個容器,劫持業務應用容器的流量,並接受控制組件的控制,同時會向控制組件輸出日誌,跟蹤及監控數據。
- 控制面是Istio的核心,管理Istio的所有功能。
Pilot: Istio的核心流量控制組件,主要負責流量管理。Pilot管理了所有Envoy的代理實例(Sidecar),主要有以下功能:
- 從K8S或者其它平臺註冊中心回去服務信息,完成服務發現
- 讀取Istio的各項控制配置,在進行裝換後將其發給數據組件進行實施。
- 數據組件Sidecar根據Pilot指令,完成 路由、服務、監聽、集群等配置。
Mixer: 主要是預檢查和匯報工作,策略控制,監控,和日誌收集等。主要工作流程如下:
- 用戶將Mixer配置發送到Kubernetes集群中
- Mixer通過對集群資源的監聽,獲取配置的變化。
- 網格中的服務每次在調用前,都會向Mixer發出預檢請求,查看是否允許執行。在服務完成調用後,會向Mixer發出報告信息,匯報在調用過程中產生的監控跟蹤數據。
- Mixer 中包含多個Adapter的組件,這些組件來處理在Mixer中接收的預檢報告數據,完成Mixer的各項功能。
Citadel: 主要用於證書管理和身份認證。
Sidecar(Envoy): Istio中的數據面,負責控制對服務網格控制的實際執行。
- Istio中默認的Sidecar是由Envoy派生出的,實際理論上只要支持Envoy的xDS協議(x descovery service 各類服務發現的總稱),其他類似的反向代理軟件就能替代Envoy來擔當此角色。
- Istio 利用istio-init初始化容器中的iptables指令,對所在Pod的流量進行劫持,從而接管Pod應用中的通信。
- Sidecar在註入到Pod之後,將原有的源容器 -> 目標容器的通信方式改變為 源容器 -> Sidecar -> Sidecar -> 目標容器。
數據面組件
Istio通過K8s的Admission webhook[9]機制實現了sidecar的自動註入,Mesh中的每個微服務pod會被加入Envoy相關的容器。
除了微服務自身的容器外,istio還在Pod中註入proxy_init
和proxyv2
兩個容器。其中proxyv2容器中運行的兩個進程是數據面的核心。
proxy_init
proxy_init是一個initContainer, 主要用於在啟動Pod前做一些初始化的工作,只有當InitContainer執行成功之後,才會啟動Pod中的其他container。
可以通過docker inspect
命令,來獲取此容器鏡像的元數據:
...
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) COPY file:1e5fc95e10f8888f4cae33f7e0ea42b5aff9d18d36280ae288a0fee948dc18e1 in / "
],
"ArgsEscaped": true,
"Image": "sha256:e261e1418e2ed94d1de1742d80997cc58f96aa3c4bfc56cd50e7f2848bf5bcf6",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/usr/local/bin/istio-iptables.sh"
],
...
從上面的命令行輸出可以看到,Proxy_init中執行的命令是istio-iptables.sh腳本,腳本具體內容可以直接從已存在的容器拷貝出來進行查看:
docker cp cbbaf5413d04:/usr/local/bin/istio-iptables.sh ./
這個腳本主要設置了Istio sidecar的iptables端口轉發規則。
proxyv2
伴隨著業務容器長久運行的註入容器是istio-proxy,這個容器負責截取POD中所有流入流出的流量。
通過如下命令,可以看到在此容器中運行的進程:
[[email protected] ~]# kubectl exec reviews-v3-748456d47b-6jvsp -c istio-proxy -- ps -ef
UID PID PPID C STIME TTY TIME CMD
istio-p+ 1 0 0 02:26 ? 00:00:00 /usr/local/bin/pilot-agent proxy sidecar --configPath /etc/istio/proxy --binaryPath /usr/local/bin/envoy --serviceCluster reviews --drainDuration 45s --parentShutdownDuration 1m0s --discoveryAddress istio-pilot.istio-system:15007 --discoveryRefreshDelay 1s --zipkinAddress zipkin.istio-system:9411 --connectTimeout 10s --proxyAdminPort 15000 --controlPlaneAuthPolicy NONE
istio-p+ 16 1 0 02:26 ? 00:03:37 /usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster reviews --service-node sidecar~10.2.53.61~reviews-v3-748456d47b-6jvsp.default~default.svc.cluster.local --max-obj-name-len 189 --allow-unknown-fields -l warn --v2-config-only
istio-p+ 39 0 0 13:07 ? 00:00:00 ps -ef
這個容器中主要運行了兩個進程:
- pilot-agent: 負責生成Envoy啟動所需的配置文件,指定了連接istio控制面的服務和端口,並負責啟動Envoy進程。
- envoy:其中指定的/etc/istio/proxy/envoy-rev0.json文件是當前pod的網絡流量的核心配置,通過此文件獲取pilot的地址,其中記錄了當前的POD信息和流量的轉發規則,pilot會與其建立長連接,並向其推送最新更新的網絡策略。
通過對envoy-rev0.json文件進行分析,我們可以發現其主要包含了如下幾個部分:
- node: 包含了當前Pod信息,包括ID,IP,servicename,namespace等。
- stats_config:定義了一些命名規則和對應的正則參數
- admin:給出了一組本地IP 127.0.0.1和15000管理端口,可以登錄此容器執行
curl http://127.0.0.1:15000/help
獲取當前POD的接口和狀態信息 - dynamic_resources:定義了xDS的服務發現配置
- static_resources:定義了連接控制面的信息,包括連接pilot組件的服務地址,以及超時時間設置和連接數限制等配置信息。
- tracing:主要定義了zipkin的接口等信息,用於追蹤業務流量的走向。
登錄istio-proxy查看監聽的端口,其中80端口為業務容器提供服務的端口:
$ netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:15001 0.0.0.0:* LISTEN 13/envoy
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:15090 0.0.0.0:* LISTEN 13/envoy
tcp 0 0 127.0.0.1:15000 0.0.0.0:* LISTEN 13/envoy
tcp6 0 0 :::15020 :::* LISTEN 1/pilot-agent
- 15001: Envoy的入口監聽器,iptable會將pod的流量導入該端口中由Envoy進行處理
- 15000: Envoy管理端口,該端口綁定在本地環回地址上,只能在Pod內訪問。
數據面組件啟動流程
流程圖示:
- initContainer執行初始化腳本,為Pod添加iptables規則
- Pilot-agent根據啟動參數和K8S API Server中的配置信息生成Envoy的初始配置文件envoy-rev0.json,該文件告訴Envoy從xDS server中獲取動態配置信息,並配置了xDS server的地址信息,即控制面的Pilot。
- Pilot-agent使用envoy-rev0.json啟動Envoy進程。
- Envoy根據初始配置獲得Pilot地址,采用xDS接口從Pilot獲取到Listener,Cluster,Route等d動態配置信息。
- Envoy根據獲取到的動態配置啟動Listener,並根據Listener的配置,結合Route和Cluster對攔截到的流量進行處理。
Envoy配置文件結構
Envoy中實際生效的配置是由初始化配置文件中的靜態配置和從Pilot獲取的動態配置一起組成的。因此只對envoy-rev0 .json進行分析並不能看到Mesh中流量管理的全貌。那麽有沒有辦法可以看到Envoy中實際生效的完整配置呢?答案是可以的,我們可以通過Envoy的管理接口來獲取Envoy的完整配置:
kubectl -n yak exec yak-files-7d48cd48f-tf75f -c istio-proxy curl http://127.0.0.1:15000/config_dump > config_dump
查看此文件的結構:
{
"configs":[
{
"@type":"type.googleapis.com/envoy.admin.v2alpha.BootstrapConfigDump",
"bootstrap":Object{...},
"last_updated":"2019-05-08T08:07:28.221Z"
},
{
"@type":"type.googleapis.com/envoy.admin.v2alpha.ClustersConfigDump",
"version_info":"2019-05-09T08:36:01Z/4",
"static_clusters":Array[3],
"dynamic_active_clusters":Array[96]
},
{
"@type":"type.googleapis.com/envoy.admin.v2alpha.ListenersConfigDump",
"version_info":"2019-05-09T08:36:01Z/4",
"static_listeners":Array[1],
"dynamic_active_listeners":Array[57]
},
{
"@type":"type.googleapis.com/envoy.admin.v2alpha.RoutesConfigDump",
"static_route_configs":Array[3],
"dynamic_route_configs":Array[17]
}
]
}
配置中主要包含了如下幾部分:
- bootstrap:文件中的內容和之前介紹的envoy-rev0.json是一致的
- clusters: 是一個服務集群,包含一個到多個endpoint,每個endpoint都可以提供服務,Envoy根據負載均衡算法將請求發送到這些endpoint中。
- static_clusters: 是來自於envoy-rev0.json的xDS server和zipkin server信息。
- dynamic_active_clusters : 是通過xDS接口從Istio控制面獲取的動態服務信息。
- listeners: Envoy采用listener來接收並處理downstream發過來的請求,listener的處理邏輯是插件式的,可以通過配置不同的filter來插入不同的處理邏輯。
- static_listeners
- dynamic_active_listeners
- routes: 配置Envoy的路由規則。Istio下發的缺省路由規則中對每個端口設置了一個路由規則,根據host來對請求進行路由分發。
- static_route_configs
- dynamic_route_configs
官方bookinfo服務調用示意圖:
參考鏈接:https://zhaohuabing.com/post/2018-09-25-istio-traffic-management-impl-intro/
istio組件介紹和啟動流程