Istio 1.1 中的 Sidecar 資源
預設情況下,Istio 在 Pod 建立之前將istio-init
和istio-proxy
注入到 Pod 之中,使用istio-init
對 iptables 進行初始化,將業務容器的流量攔截到istio-proxy
,從而完成通訊控制權的移交工作——應用容器的自發 Ingress 和 Egress 通訊,都從 Envoy 中留過,Envoy 作為資料平面,需要接受來自控制面的 xDS 指令,據此作出通訊決策。
在 Istio 1.1 中引入了 Sidecar 資源物件,為這一攔截轉發過程加入了一定的控制能力,可能給 Istio 的生產應用帶來很好的效率提升。
基本結構
Sidecar 資源的一級結構很簡單,由三個成員構成:
-
workloadSelector
:標籤選擇器,用來對 Pod 進行選擇。這一欄位是可選欄位,如果忽略這一欄位,則會對名稱空間內的所有 Pod 生效。需要注意的是,一個名稱空間之內,只允許存在一個不設定此欄位的 Sidecar 物件。 -
ingress
:一個數組,用於處理進入 Pod 的流量,如果省略這一欄位,Istio 會根據業務應用的工作負載定義來設定監聽過程。-
port
:必要欄位,監聽的埠,如果使用 Unix domain socket,則設定為 0。- number
- protocal
- name
-
bind
:監聽器的繫結設定,可以是ip
,也可以是unix:///path/to/uds
,如果省略這一欄位,Istio 會根據工作負載服務來自動填充。 -
captureMode
:如果bind
指定的是 IP 地址,這個欄位可以指定是否攔截通訊,如果繫結到 Unix domain socket,這一欄位必須是DEFAULT
或者NONE
。 -
defaultEndpoint
:必要欄位,Envoy 接收進入 Pod 的流量之後的轉發目標。目標可以是127.0.0.1:PORT
或者unix:///path/to/socket
-
-
egress
:一個處理 Egress 流量的定義陣列。-
port
:監聽器的埠,如果使用 Unix domain socket,則設為 0。 -
bind
:繫結到地址或 socket。 -
captureMode
:同ingress
。 -
hosts
:必要欄位,用名稱空間/服務 FQDN
組合而成,可以是 VirtualService 或者 ServiceEntry 或者原始 Kubernetes 服務的名稱,支援萬用字元。
-
開始之前
安裝 Kubernetes 叢集和 Istio,這裡採用 1.1.2 的 demo-auth 配置。建立新名稱空間other
,並打標籤開啟自動注入:
$ helm template install/kubernetes/helm/istio-init \ --name istio-init --namespace istio-system | kubectl apply -f - ... $ helm template install/kubernetes/helm/istio \ --name istio --namespace istio-system \ --values install/kubernetes/helm/istio/values-istio-demo-auth.yaml | kubectl apply -f - ... $ kubectl create ns other namespace/other created $ kubectl label namespaces other istio-injection=enabled --overwrite namespace/other labeled $ kubectl label namespaces default istio-injection=enabled --overwrite namespace/default labeled
分別在default
和other
中啟動flaskapp
和sleep
應用。
$ kubectl apply -f sleep/sleep.yaml -n default service/sleep created deployment.extensions/sleep created $ kubectl apply -f sleep/sleep.yaml -n other service/sleep created deployment.extensions/sleep created $ kubectl apply -f httpbin/httpbin.yaml -n default service/httpbin created deployment.extensions/httpbin created $ kubectl apply -f httpbin/httpbin.yaml -n other service/httpbin created deployment.extensions/httpbin created
檢查一下呼叫關係:
$ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl http://httpbin:8000/ip { "origin": "127.0.0.1" } $ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl http://httpbin.other:8000/ip { "origin": "127.0.0.1" }
服務的可見性
預設情況下,注入了 Istio 的工作負載會進行全網格的傳播,假設default
和other
兩個不相干的名稱空間,other
中有大量的服務,而default
中只有幾個,因為路由傳播的關係,default
名稱空間中的工作負載,其 Sidecar 也會帶上other
名稱空間中的路由資訊。例如:
$ istioctl proxy-config clusters sleep-69bd44b5bb-vwpzf | grep other httpbin.other.svc.cluster.local 8000-outbound&{EDS} sleep.other.svc.cluster.local80-outbound&{EDS}
可以看到,在default
名稱空間中的 Pod,儲存了其它名稱空間中的路由資訊。這不管是對記憶體消耗還是路由控制來說,都會造成一定浪費,我們可以定義一個 Sidecar 資源,限制 sleep 服務只訪問同一名稱空間的其他服務:
apiVersion: networking.istio.io/v1alpha3 kind: Sidecar metadata: name: sleep spec: workloadSelector: labels: app: sleep egress: - hosts: - "default/*"
提交到叢集,看看效果:
$ kubectl apply -f sleep-egress.yaml sidecar.networking.istio.io/sleep created $ istioctl proxy-config clusters sleep-69bd44b5bb-vwpzf | grep httpbin httpbin.default.svc.cluster.local8000-outbound&{EDS}
可以看到,httpbin 的路由只剩下了本名稱空間之內的服務。再次嘗試訪問:
$ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl http://httpbin:8000/ip { "origin": "127.0.0.1" } $ kubectl exec -c sleep -it sleep-69bd44b5bb-vwpzf -- curl -v http://httpbin.other:8000/ip *Trying 10.245.156.252... * TCP_NODELAY set * Connected to httpbin.other (10.245.156.252) port 8000 (#0) > GET /ip HTTP/1.1 > Host: httpbin.other:8000 > User-Agent: curl/7.61.1 > Accept: */* > < HTTP/1.1 404 Not Found < date: Wed, 10 Apr 2019 04:50:15 GMT < server: envoy < content-length: 0 < * Connection #0 to host httpbin.other left intact
這樣一來,已經無法訪問httpbin.other
的服務了,但是如果嘗試從other
到default
訪問的話,還是可以繼續的。
Sidecar 的 Ingress 和 Egress
除了上面的小功能之外,Sidecar 的IstioEgressListener
和IstioIngressListener
都提供了很強大的功能,例如:
- Envoy 可以為應用容器所監聽的 Unix socket 提供反向代理服務。
-
在沒有 iptables 支援的情況下,可以使用
bind
結合port
的方式,直接指定代理方案。 - 可以在容器內部為 egress 服務提供基於 Unix socket 的反向代理。
詳情可以參考官方參考文件:https://istio.io/docs/reference/config/networking/v1alpha3/sidecar/#IstioIngressListener
中文版:https://skyao.io/learning-istio/crd/network/sidecar.html
這些功能都非常有用,上面的文件中都提供了很好的應用場景,但是這些特性我只有可見性部分測試成功了(╬ ̄皿 ̄)=○ ,目前正在討說法,非常希望是我錯了。。