Istio Egress Gateway出口流量管理

缺省狀態下,Istio服務網格內的Pod,由於其iptables將所有外發流量都透明的轉發給了sidecar,所以這些集羣內的服務無法訪問集羣之外的 URL,而只能處理集羣內部的目標。

控制出口流量描述瞭如何通過ServiceEntry將外部服務暴露給集羣內的客戶端

本文則通過一個官方的用例解釋如何通過Egress Gateway配置Istio的出口流量,這個例子主要適用於兩種場景:

  1. 離​​開服務網格的所有流量必須流經一組專用節點,這一組節點會有特殊的監控和審查
  2. 集羣中不是所有節點都有public IP,定義egress網關,通過它引導所有出口流量並將public IP分配給egress網關節點,允許應用節點以受控方式訪問外部服務

環境準備

創建Kubernetes集羣

阿里雲容器服務Kubernetes 1.11.2目前已經上線,可以通過容器服務管理控制檯非常方便地快速創建 Kubernetes 集羣。具體過程可以參考這裏

部署istio

阿里雲容器服務在應用目錄目前支持istio快速部署,具體過程可以參考這裏

部署用例

kubectl apply -f <(istioctl kube-inject -f https://raw.githubusercontent.com/istio/istio/release-1.0/samples/sleep/sleep.yaml)

定義需要向外發送請求的pod

export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

創建ServiceEntry

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 80
    name: http-port
    protocol: HTTP
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
EOF

驗證配置生效

kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics

如下返回表示配置生效

HTTP/1.1 301 Moved Permanently
...
location: https://edition.cnn.com/politics
...

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
...
Content-Length: 151654
...

創建Gateway

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - edition.cnn.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-cnn
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: cnn
EOF

創建VirtualService

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - istio-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: cnn
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 80
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 80
      weight: 100
EOF

再次發送請求

kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics

此時返回應該仍然是成功的,但是我們查看istio-egressgateway的日誌

kubectl logs $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') egressgateway -n istio-system | tail

應該會有一條類似這樣的記錄

[2018-06-14T11:46:23.596Z] "GET /politics HTTP/2" 301 - 0 0 3 1 "172.30.146.87" "curl/7.35.0" "ab7be694-e367-94c5-83d1-086eca996dae" "edition.cnn.com" "151.101.193.67:80"

說明出口流量已經匯入egress gateway,然後由他引導至集羣外部

配置解釋

在本例中創建了四種資源,真正定義將出口流量轉發給egress gateway的是VirtualService

  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: cnn
        port:
          number: 80
      weight: 100

這一段配置中的matchgateways表示這一條路由規則是作用在mesh上的,也就是整個網格中所有的sidecar上,port表示所有訪問80端口的流量纔會應用這條規則,因爲本例中只提供了80端口的服務,所以這一項是可以省略掉的

destination表示會把所有路由後的流量導入istio-egressgateway.istio-system.svc.cluster.local service的cnn sbuset下的80端口,這裏需要注意的是,istio-egressgateway是在Istio部署時定義的service,已經開放了80,443端口,在真實使用中如果要用到別的端口,需要在istio-egressgateway的定義中做對應的修改

同理,VirtualService中的另一部分規則作用在istio-egressgateway上,會把出口流量引導至集羣外部

總結

本文通過示例演示了Istio如何對網格內的出口流量做統一的引導。

歡迎大家使用阿里雲上的容器服務,快速搭建微服務的開放治理平臺Istio,比較簡單地集成到自己項目的微服務開發中。

歡迎大家使用阿里雲上的容器服務,快速搭建微服務的開放治理平臺Istio,比較簡單地集成到自己項目的微服務開發中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章