全部產品
Search
文件中心

Alibaba Cloud Service Mesh:為網格內流量配置統一的出口網關

更新時間:Oct 17, 2024

當網格內的應用需要與外部服務進行通訊時,您可以使用出口網關作為統一的出口,集中管理所有的出站流量。通過配置出口網關,您可以實現對流量的安全控制和路由,提升網格內應用程式的安全性和可觀測性。

重要

閱讀本文前,請確保您已經瞭解使用ASMEgressTrafficPolicy管理出口流量中的內容。本文使用服務網格資源實現了將訪問叢集外服務的請求透明劫持到出口網關,由出口網關執行安全性原則,然後發送給叢集外服務,配置相對複雜。如果使用ASMEgressTrafficPolicy管理出口流量中的內容無法滿足您的需求,再參考本文。

前提條件

配置流程

配置流程

步驟一:部署樣本應用

  1. 部署sleep應用。

    1. 使用以下內容,建立sleep.yaml

      展開查看sleep.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "infinity"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. 在ACK叢集對應的KubeConfig環境下,執行以下命令,部署sleep應用。

      關於如何使用kubectl管理叢集,請參見擷取叢集KubeConfig並通過kubectl工具串連叢集

      kubectl apply -f sleep.yaml
  2. 執行以下命令,進入sleep Pod,訪問外部服務。

    您可以通過kubectl get pod -n default命令,查看sleep Pod的名稱。

    kubectl exec -it ${sleep Pod的名稱} -- /bin/sh
    curl aliyun.com -I

    樣本輸出:

    HTTP/1.1 301 Moved Permanently
    server: envoy
    date: Thu, 14 Dec 2023 03:05:41 GMT
    content-type: text/html
    content-length: 239
    location: https://aliyun.com/
    eagleeye-traceid: 0b57ff8717025231418255220e****
    timing-allow-origin: *
    x-envoy-upstream-service-time: 69

    返回301,表示網格內應用可以正常訪問外部服務。此處預設使用HTTP協議訪問,網站會返回重新導向響應。

    說明

    ASM預設允許訪問所有外部服務,採用此方式無法進行安全許可權控制,也無法使用網格提供的各種可觀測能力。建議您參照下文,開啟REGISTRY_ONLY,限制可訪問的服務,並使用出口網關作為流量統一出口。

(可選)步驟二:開啟REGISTRY_ONLY

ASM的外部服務存取原則預設為ALLOW_ANY,建議您將其修改為REGISTRY_ONLY。Sidecar代理將阻止應用訪問未在網格中定義服務條目的外部主機,保障網格內應用的安全。

說明
  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇資料面組件管理 > Sidecar代理配置

  3. Sidecar代理配置頁面,單擊全域頁簽,單擊外部服務存取原則,配置對外部服務的存取原則OutboundTrafficPolicyREGISTRY_ONLY,然後單擊更新設定

  4. 執行以下命令,進入sleep Pod,訪問外部服務。

    kubectl exec -it ${sleep Pod的名稱} -- /bin/sh
    curl aliyun.com -I

    樣本輸出:

    HTTP/1.1 502 Bad Gateway
    date: Thu, 14 Dec 2023 03:08:46 GMT
    server: envoy
    transfer-encoding: chunked

    返回502,表示網格內應用無法訪問未經註冊的外部服務。

步驟三:為外部服務建立服務條目(ServiceEntry)

對叢集外的服務建立ServiceEntry,叢集內應用才能使用出口網關訪問對應的外部服務。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇叢集與工作負載管理 > 叢集外服務(ServiceEntry),然後單擊使用YAML建立

  3. 建立頁面,選擇sleep應用所在的命名空間情境模板選擇訪問網格外部服務,配置如下YAML樣本,然後單擊建立

    apiVersion: networking.istio.io/v1beta1
    kind: ServiceEntry
    metadata:
      name: external-svc-http
    spec:
      hosts:
      - aliyun.com
      location: MESH_EXTERNAL
      ports:
      - number: 80
        name: http
        protocol: HTTP
      resolution: DNS
  4. 執行以下命令,進入sleep Pod,訪問外部服務。

    kubectl exec -it ${sleep Pod的名稱} -- /bin/sh
    curl aliyun.com -I

    返回301,表示網格內應用可以正常訪問外部服務。在網格內使用ServiceEntry註冊了aliyun.com,所以允許應用訪問該外部服務。此時外部流量直接從各個Pod發出,並沒有從統一的出口網關發出。

步驟四:使用出口網關作為外部服務的統一出口

上文已為aliyun.com建立了ServiceEntry,因此可以使用虛擬服務、網關規則等功能來管理訪問aliyun.com的流量。

  1. 建立出口網關,配置HTTP協議和80連接埠。具體操作,請參見建立出口網關

  2. 按照以下內容,建立網關規則。具體操作,請參見管理網關規則

    建立網關規則

  3. 使用以下YAML,建立虛擬服務。具體操作,請參見管理虛擬服務

    展開查看虛擬服務YAML

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: egressgateway-vs
    spec:
      hosts:
      - aliyun.com
      gateways:
      - egress-gw  # 上一步建立的網關規則名稱。
      - mesh
      http:
      - match:
        - gateways:
          - mesh
          port: 80
        route:
        - destination:
            host: istio-egressgateway.istio-system.svc.cluster.local
            port:
              number: 80
          weight: 100
      - match:
        - gateways:
          - egress-gw
          port: 80
        route:
        - destination:
            host: aliyun.com
            port:
              number: 80
          weight: 100
  4. 測試訪問外部服務。

    1. 執行以下命令,進入sleep Pod,訪問外部服務。

      kubectl exec -it ${sleep Pod的名稱} -- /bin/sh
      curl aliyun.com -I

      返回301,表示網格內應用可以正常訪問外部服務。此時網格內應用不是直接從Pod訪問服務,而是通過上文建立的出口網關訪問服務。

    2. 執行以下命令,在網關Pod中查看訪問日誌。

      說明
      • 若您的出口網關Pod有多個副本,產生的訪問日誌會在某個Pod上。您需要依次在所有網關Pod上執行此命令,才能找到對應的訪問日誌。

      • 如果您開啟了出口網關的訪問日誌,也可以登入Log Service控制台查看訪問記錄。

      kubectl -n istio-system logs ${出口網關Pod名稱}  -c istio-proxy | grep aliyun.com | tail -n 1

      樣本輸出:

      {"trace_id":null,"upstream_host":"106.11.XXX.XX:80","downstream_remote_address":"10.34.0.140:47942","requested_server_name":null,"response_code":301,"upstream_service_time":"24","user_agent":"curl/7.86.0-DEV","path":"/","route_name":null,"bytes_sent":0,"response_flags":"-","upstream_local_address":"10.34.0.141:60388","duration":24,"upstream_cluster":"outbound|80||aliyun.com","upstream_transport_failure_reason":null,"authority":"aliyun.com","request_id":"55789d59-9b81-4e39-b64a-66baf44e****","protocol":"HTTP/1.1","bytes_received":0,"method":"HEAD","downstream_local_address":"10.34.0.141:80","start_time":"2022-11-30T08:03:01.315Z","istio_policy_status":null,"x_forwarded_for":"10.34.0.140"}

      downstream_remote_address表示sleep Pod的IP地址。

      完成上述配置之後,相應的外部服務流量會通過出口網關向叢集外發出,您可以在網關上使用ASM提供的可觀測以及安全相關的能力,更加高效地管理出口流量。

相關文檔