k8s~envoy上新增wasm外掛

張佔嶺發表於2023-12-08

先檢視這篇文章k8s~envoy的部署

當在Kubernetes中使用Envoy的WASM過濾器時,WASM過濾器會與Envoy一起部署在同一個Pod中,並與後端服務進行通訊。以下是一個簡單的關係圖示意:

  +----------------------+
  |       Kubernetes     |
  |        Cluster       |
  +----------|-----------+
             |
             |
  +----------v-----------+
  |                      |
  |        Pod           |
  |                      |
  | +------------------+ |
  | |      Envoy       | |
  | |   with WASM     | |
  | |   Filter       | |
  | +------------------+ |
  | |   Backend App   | |
  | +------------------+ |
  |                      |
  +----------------------+

在這個示意圖中,我們有一個執行在Kubernetes中的Pod,其中包含了Envoy和後端服務兩個容器。Envoy與WASM過濾器一起作為Sidecar代理與後端服務一起執行,負責處理流量轉發、負載均衡、安全策略等功能。後端服務則是實際提供業務功能的應用程式。

wasm部署過程

WASM過濾器可以在Envoy中攔截請求並對其進行修改或增強,然後將請求傳送到後端服務。這種部署模式允許WASM過濾器直接與Envoy共享相同的網路名稱空間,並透過Envoy來與後端服務通訊。

在Kubernetes中應用Envoy的Filter並實現WebAssembly(WASM)的過濾器涉及以下幾個步驟:

  1. 準備WASM模組:

    • 編寫你的WASM模組,其中包含Envoy的Filter邏輯。確保你的WASM模組包含了你期望的Filter行為,比如認證、日誌記錄等。
    • 編譯WASM模組,以確保其與Envoy相容。
  2. 配置Envoy Filter:

    • 在你的Envoy配置檔案中,新增一個Filter配置,指定使用你的WASM模組。

    • 在配置檔案中,你可能需要新增類似以下的部分:

      filters:
        - name: envoy.filters.http.wasm
          config:
            name: "my_wasm_filter"
            root_id: "my_root_id"
            vm_config:
              code:
                local: 
                  filename: "/etc/wasm/ip-rate-limit/main.wasm"
              runtime: "envoy.wasm.runtime.v8"
            configuration: 
               "@type": "type.googleapis.com/google.protobuf.StringValue"
                     value: |
                       {
                         "ttlSecond": 60,
                         "burst": 3
                       }
      
  • 請根據實際情況替換 my_wasm_filtermy_root_id/etc/wasm/ip-rate-limit/main.wasm
  • 如果你的envoy部署在k8s裡,那上面的檔案應該是envoy pod裡的路徑,你可以透過pvc進行指定pv,(pv對應儲存類或者持久類)
  1. 部署Envoy配置:

    • 將更新後的Envoy配置部署到Rancher or k8s中。
  2. 監控日誌和錯誤:

    • 監控Envoy的日誌以檢視是否有任何關於WASM Filter的錯誤或警告。確保Envoy能夠成功載入和執行你的WASM模組。
  3. 測試Filter行為:

    • 傳送請求到Envoy並確保WASM Filter按照預期進行操作。可以透過檢視Envoy的日誌、觀察返回的請求或使用其他除錯工具來驗證Filter的行為。

envoy版本的注意項

  • envoyproxy/envoy:v1.21-latest,對應10000埠
  • envoyproxy/envoy 對應80埠

完成的envoy.yaml配置

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9901 } #envoy後臺系統的埠

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 10000 } #envoy路由的埠
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          scheme_header_transformation:
            scheme_to_overwrite: https
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: httpbin
          http_filters:
          - name: wasmdemo
            typed_config:
              "@type": type.googleapis.com/udpa.type.v1.TypedStruct
              type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
              value:
                config:
                  name: wasmdemo
                  vm_config:
                    runtime: envoy.wasm.runtime.v8
                    code:
                      local:
                        filename: /etc/wasm/ip-rate-limit/main.wasm
                  configuration:
                    "@type": "type.googleapis.com/google.protobuf.StringValue"
                    value: |
                      {
                        "ttlSecond": 60,
                        "burst": 3
                      }

          - name: envoy.filters.http.router
  clusters:
  - name: httpbin
    connect_timeout: 30s
    type: LOGICAL_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: httpbin
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: httpbin_app_service.app_namespace
                port_value: 8080

最後,我們把envoy服務的10000埠公開出去,在叢集外就可以訪問它了,你的wasm就可以被啟用了;當然將10000埠公開出現的方法有很多,比較通用的方式是將它透過ingress或者阿里higress進行代理,更靈活。