MoE 系列(三)|使用 Istio 動態更新 Go 擴充套件配置

SOFAStack發表於2023-05-04

上一篇我們用 Go 擴充套件實現了 Basic Auth,體驗了 Go 擴充套件從 Envoy 接受配置。

之所以這麼設計,是想複用 Envoy 原有的 xDS 配置推送通道,今天我們就來體驗一番,雲原生的配置變更

前提準備

這次我們需要一套 K8s 環境,如果你手頭沒有,推薦使用 Kind 安裝一套。具體安裝方式,這裡就不展開了。

安裝 Istio

我們直接安裝最新版的 Istio:

# 下載最新版的 istioctl$ export ISTIO_VERSION=1.18.0-alpha.0$ curl -L https://istio.io/downloadIstio | sh -
# 將 istioctl 加入 PATH$ cd istio-$ISTIO_VERSION/$ export PATH=$PATH:$(pwd)/bin
# 安裝,包括 istiod 和 ingressgateway$ istioctl install

是的,由於 Go 擴充套件已經貢獻給了上游官方,Istiod(Pilot)和 Ingress Gateway 都已經預設開啟了 Go 擴充套件,並不需要重新編譯。

Istio 配置 Ingress

我們先用 Istio 完成標準的 Ingress 場景配置,具體可以看 Istio 的官方檔案[1]。

配置好了之後,簡單測試一下:

$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"HTTP/1.1 200 OKserver: istio-envoydate: Fri, 10 Mar 2023 15:49:37 GMT

基本的 Ingress 已經跑起來了。

掛載 Golang so

之前我們介紹過,Go 擴充套件是單獨編譯為 so 檔案的,所以,我們需要把 so 檔案,掛載到 Ingress Gateway 中。

這裡我們把上次 Basic Auth 編譯出來的 libgolang.so,透過本地檔案掛載進來。簡單點搞,直接 edit deployment 加了這些配置:

# 申明一個 hostPath 的 volumevolumes:- name: golang-so-basic-auth  hostPath:    path: /data/golang-so/example-basic-auth/libgolang.so    type: File
# 掛載進來volumeMounts:- mountPath: /etc/golang/basic-auth.so  name: golang-so-basic-auth  readOnly: true

開啟 Basic Auth 認證

Istio 提供了 EnvoyFilter CRD,所以,用 Istio 來配置 Go 擴充套件也比較方便,apply 這段配置,Basic Auth 就開啟了。

apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:  name: golang-filter  namespace: istio-systemspec:  configPatches:    # The first patch adds the lua filter to the listener/http connection manager  - applyTo: HTTP_FILTER    match:      context: GATEWAY      listener:        filterChain:          filter:            name: "envoy.filters.network.http_connection_manager"            subFilter:              name: "envoy.filters.http.router"    patch:      operation: INSERT_BEFORE      value: # golang filter specification       name: envoy.filters.http.golang       typed_config:          "@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config"          library_id: example          library_path: /etc/golang/basic-auth.so          plugin_name: basic-auth          plugin_config:            "@type": "type.googleapis.com/xds.type.v3.TypedStruct"            type_url: typexx            value:              username: foo              password: bar

雖然有點長,但是,也很明顯,配置的使用者名稱密碼還是:foo:bar

測試

我們測試一下:

$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"HTTP/1.1 401 Unauthorized
# valid foo:bar$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200" -H 'Authorization: basic Zm9vOmJhcg=='HTTP/1.1 200 OK

符合預期。

接下來,我們改一下 EnvoyFilter 中的密碼,重新 apply,再測試一下:

# foo:bar not match the new password$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200" -H 'Authorization: basic Zm9vOmJhcg=='HTTP/1.1 401 Unauthorized

此時的 Envoy 並不需要重啟,新的配置就立即生效了,雲原生的體驗就是這麼溜~

總結

因為 Go 擴充套件可以利用 Envoy 原有的 xDS 來接受配置,所以,從 Istio 推送配置也變得很順利。

不過,Istio 提供的 EnvoyFilter CRD 在使用上,其實並不是那麼方便和自然,後面我們找機會試試 Envoy Gateway,看看 K8s Gateway API 的體驗如何。

至此,我們已經體驗了整個 Envoy Go 的開發&使用流程,在雲原生時代,人均 Golang 的背景下,相信可以很好的完成閘道器場景的各種定製需求。

下一篇,我們將介紹,如何在 Go 擴充套件中使用非同步協程。這意味著,我們可以使用的是一個全功能的 Go 語言,而不是像 Go Wasm 那樣,只能用閹割版的。

敬請期待:MoE 系列(四)|Go 擴充套件的非同步模式

[1]Istio 的官方檔案:

https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/

相關文章