目錄
Gateway(gw)
istio中gateway資源可以將網格內部的服務暴露給網格外部的服務,供網格外部的服務調用,該資源描述了需要公開的端口、端口的協議類型、以及域名等。
下面是服務的gw資源配置文件示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
selector標明瞭該gateway選擇用的pod,ingressgateway實際上是一個istio-proxy,這裏gateway用label關聯了istio的ingressgateway。
我們可以用命令查找出該pod:
|
我們查看該pod的配置,發現該pod有一個container,名稱爲istio-proxy,該服務負責從網格外轉發請求到網格內。
istio-proxy實際上是envoy + 管理envoy的父進程pilot-agent。
|
VirtualService(vs)
virtualService用來與Gateway綁定,實現服務訪問路由控制、服務版本與流量的控制。
下面是服務的vs配置示例:
|
- gateways表示與哪些gateway綁定,可以綁定多個gateway資源,這裏我們綁定了上面創建的gateway資源。
- match與route搭配可實現路由控制,上面是將path / 下的請求全部路由到兩個destination上。
- destination中描述了目標服務的具體信息,包含host服務域名、服務版本、版本權重等。
- virtual service與destination rule結合,可以實現服務版本的流量控制,新版本的灰度發佈可以根據這個來實現。
協議支持:
http協議流量規則:
DestinationRule(dr)
外部請求經過VirtualService的路由規則後,如果目標服務設置了dr,那麼dr配置的目標服務策略會生效。
下面是服務的dr配置示例:
|
- host是服務的域名
-
trafficPolicy是對於服務pod的流量規則,比較重要的如loadBalancer、connectionPool、outlierDetection
loadBalancer simple規則:
http connectionPool規則:
outlierDetection可實現異常點檢測與熔斷:
-
subset描述了服務的子集,該子集由帶有標籤(version: v2)的pod組成,不同的子集也可以設置不同的trafficPolicy,如下面的例子,默認lb策略是least_conn,而v3版本則是輪詢策略。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: bookinfo-ratings
spec:
host: ratings.prod.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_CONN
subsets:
- name: testversion
labels:
version: v3
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
ServiceEntry(se)
功能:
- 將網格外的服務加到服務發現中,就像是網格內的服務一樣被治理(成爲k8s中的一個service),如網格外的mysql、redis等服務,或是部署在物理機上未加入網格內部的服務。
機制:
- 將ServiceEntry描述的service加到服務發現中,對這些服務的outbound流量進行攔截,從而進行治理。
- 當ServiceEntry描述的service有endpoint變化時,我們可以監聽其變化,利用k8s基建,創建或者刪除k8s該service的endpoint,由於istio的服務發現依賴於k8s,該變化會被istio pilot-discovery感知到,並通過xDs通知envoy。
- istio服務發現概覽:
- TODO:serviceEntry其他配置文件等待補充……
sidecar注入以及流量劫持
sidecar模式:
Sidecar 連接到父應用並且爲其添加擴展或者增強功能。
使用sidecar的優勢:
- 將與應用業務邏輯無關的功能抽象到共同基礎設施,降低了微服務代碼的複雜度。
- 因爲不再需要編寫相同的第三方組件配置文件和代碼,所以能夠降低微服務架構中的代碼重複度。
- Sidecar 可獨立升級,降低應用程序代碼和底層平臺的耦合度。
sidecar注入過程
在創建namespace lyl時,我們使用了istio的自動注入:
|
注入以後,我們看下namespace的配置,多了一個label,istio-injection=enable
sidecar注入原理
sidecar注入依賴於Kubernetes 的准入控制器。
來自 Kubernetes 文檔:
准入控制器是一段代碼,會攔截 Kubernetes API Server 收到的請求,攔截髮生在認證和鑑權完成之後,對象進行持久化之前。可以定義兩種類型的 Admission webhook:Validating 和 Mutating。Validating 類型的 Webhook 可以根據自定義的准入策略決定是否拒絕請求;Mutating 類型的 Webhook 可以根據自定義配置來對請求進行編輯。
簡單來說,sidecar的注入是在api-server接收到deployment pod的請求之後,寫入etcd之前做的事情。
對於 sidecar 自動注入,Istio 依賴於 Mutating Admission Webhook
。讓我們來看看 istio-sidecar-injector
中的配置詳情。
kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml
|
在配置文件中,我們看到有namespaceSelector配置,matchLabels表明如果namespace滿足有label:istio-injection=enable(上面截圖可以看到我們的namespace lyl已經滿足這個條件),並且滿足下面列的rules:v1 version,且動作是pod的創建,那麼mutatingWebhook會執行istio-sidecar-injector這個service,給創建的pod注入配置。
sidecar注入結果
sidecar注入以後,查看服務啓動的pod信息
可以看到,每個pod都有兩個ready的容器,一個是我們的服務容器,另一個就是sidecar容器。
查看下第一個pod具體的配置信息:
|
發現有兩個containers,具體展開可以看到一個是我們自己服務的容器,第二個是istio-proxy容器,也就是sidecar容器,之前說到istio-proxy實際上是pilot-agent + envoy兩個父子進程,pilot負責管理envoy,所以實際上服務的sidecar就是envoy。
同時,在配置下方,我們還發現了另一個container,叫作istio-init container,這個init容器在pod初始化時創建,pod初始化完成就自動銷燬了,從配置的command中可以看出,init容器主要用來創建iptables規則。istio-iptables的代碼位於istio代碼倉庫的tools/istio-iptables目錄。
所以,Istio 給應用 Pod 注入的配置主要包括:
- Init 容器
istio-init
:用於 pod 中設置 iptables 端口轉發。 - Sidecar 容器
istio-proxy
:運行 sidecar 代理,即envoy。
iptables注入解析(以下iptables規則引用自這裏,本文不在詳述):
|
參考資料:
https://jimmysong.io/blog/sidecar-injection-iptables-and-traffic-routing/
https://istio.io/zh/docs/reference/config/networking/destination-rule/#OutlierDetection