日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

在ASM網關上基于Client IP進行路由

基于客戶端IP進行路由是較為常見的需求,例如內網和公網的用戶需要訪問不同版本的應用、不同地區的用戶需要訪問不同類別的內容等。因此ASM提供了自定義插件能力,可以將請求的客戶端IP轉換為請求Header進行路由。本文將介紹如何在ASM中利用自定義插件實現基于客戶端IP的路由。

背景信息

ASM使用Envoy作為網格代理來進行實際的流量轉發,利用Envoy豐富的插件生態來對網格能力進行擴展。以HTTP協議為例,Envoy提供了高度靈活的擴展接口,您可以直接利用這些接口讀取到詳細的請求元數據,甚至可以修改請求Header、Body等屬性。Envoy的插件可以分為以下三類:

  • 原生Envoy Filter:基于C++開發,難度大,但性能更好。

  • WASM插件:可以使用多種語言開發,更加安全、靈活,開發難度較低。

  • Lua插件:使用Lua進行開發,靈活度受限,但開發難度最低。

本文將使用一個簡單的Lua插件,將請求的Client IP轉換為請求的Header,通過虛擬服務匹配該Header,實現不同來源的請求返回不同的響應。

前提條件

步驟一:確認客戶端源IP

首先,部署sleep應用到集群作為客戶端。后面我們將分別從sleep和本地客戶端來訪問httpbin服務,從而測試不同源IP的請求。

說明

本地客戶端特指當前場景下執行文檔操作的用戶終端,包括個人電腦,ECS等。例如使用個人電腦登錄ECS,再通過kubectl訪問ACK集群時,ECS就是本地客戶端。

  1. 使用ACK集群kubecofig創建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: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
            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. 執行以下命令,部署sleep應用。

    kubectl apply -f sleep.yaml
  3. 執行以下命令,配置入口網關IP地址的環境變量。關于網關IP的獲取方式,請參見獲取入口網關地址

    export ASM_GATEWAY_IP=112.35.xx.xx
  4. 執行以下命令,獲取本地客戶端IP。

    curl ${ASM_GATEWAY_IP}/ip
  5. 執行以下命令,獲取sleep Pod的IP。

    kubectl exec deploy/sleep -it -- curl ${ASM_GATEWAY_IP}/ip
    說明

    訪問httpbin應用/ip路徑的請求將會返回客戶端IP。這種獲取客戶端IP的方式需要網關中Service的ExternalTrafficPolicy設為local

步驟二:創建Lua插件并應用到ASM網關上

Lua插件是通過Envoy的Lua Filter實現的。您可以自行編寫Lua代碼,并將Lua代碼直接作為Lua Filter配置的一部分發送給Envoy。Envoy會在請求處理時調用配置的Lua代碼來執行相應操作。

本文中需要的Lua代碼片段如下。

function envoy_on_request(request_handle)
    -- 定義envoy_on_request函數,處理接收到的請求
    -- 參數request_handle用來獲取并修改請求信息
  local client_address = request_handle:streamInfo():downstreamRemoteAddress()
    --   獲取請求源IP
  request_handle:headers():add("x-client-address", client_address)
    --   設置請求header,header的key為x-client-address
end
  1. 創建Envoy過濾器資源,具體操作,請參見使用Envoy過濾器模板創建Envoy過濾器

    創建Envoy過濾器模板過程中,將下方YAML粘貼至多版本適配Envoy過濾器模板的輸入框中。

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: add-header-by-ip
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: GATEWAY
            listener:
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.lua
              typed_config:
                "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
                inlineCode: |
                  function envoy_on_request(request_handle)
                    local client_address = request_handle:streamInfo():downstreamRemoteAddress()
                    request_handle:headers():add("x-client-address", client_address)
                  end
  2. 綁定至工作負載時,請選擇選定工作負載綁定,選擇istio-system命名空間,工作負載類型選擇Service,選中ASM網關對應的Service(名稱為istio-${ASM網關名稱})。

  3. 綁定完成之后,單擊Envoy過濾器。可以看到對應的Envoy過濾器已經創建成功。

步驟三:創建基于Client IP的路由規則

使用ASM的kubeconfig,修改httpbin應用中部署的虛擬服務,最終YAML如下所示:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin-vs
  namespace: default
spec:
  gateways:
    - httpbin
  hosts:
    - '*'
  http:
    - match:
      - headers:
          x-client-address:
            prefix: ${獲取到的Sleep客戶端IP}
      directResponse:
        status: 200
        body:
          string: "from sleep"
    - match:
      - headers:
          x-client-address:
            prefix: ${獲取到的本機IP}
      directResponse:
        status: 200
        body:
          string: "from my host"    
    - name: test
      route:
        - destination:
            host: httpbin.default.svc.cluster.local
            port:
              number: 8000

上述配置的含義是:

  • 所有來自sleep的請求,將直接返回一個from sleep字符串。

  • 所有來自本地客戶端的請求,將直接返回一個from my host字符串。

步驟四:測試

  1. 在本地客戶端執行以下命令。

    curl ${ASM_GATEWAY_IP}/ip

    預期輸出:

    from my host
  2. 使用ACK集群的kubeconfig執行以下命令。

    kubectl exec deploy/sleep -it -- curl ${ASM_GATEWAY_IP}/ip

    預期輸出:

    from sleep

相關文檔

  • 在熟悉Envoy架構的前提下,Lua插件相較于其他Envoy插件開發難度最低。關于如何開發Envoy的Lua插件,請參見Lua script for HTTP filters

  • WASM插件是基于WebAssembly For Proxies規范編寫的Envoy插件,支持多種語言。您可以嘗試使用較低入門難度的Golang來開發WASM插件。具體操作,請參見使用Go為網格代理編寫WASM插件