如何使用 Go 開發 Apache APISIX 外掛

語言: CN / TW / HK

C T O

   

   

 

Go Rust Python Istio containerd CoreDNS Envoy etcd Fluentd Harbor Helm Jaeger Kubernetes Open Policy Agent Prometheus Rook TiKV TUF Vitess Argo Buildpacks CloudEvents CNI Contour Cortex CRI-O Falco Flux gRPC KubeEdge Linkerd NATS Notary OpenTracing Operator Framework SPIFFE SPIRE     Thanos

如何使用 Go 開發 Apache APISIX 外掛

Apache APISIX 允許使用者通過外掛來擴充套件功能。鑑權、限流、請求重寫等功能都是通過外掛實現的。…

本文詳細解釋瞭如何使用 Go 開發 Apache APISIX 外掛。通過擁抱 Go 生態系統, Go 使 Apache APISIX 變得更好!

安裝 Go Runner

使用 Go Runner 作為庫, apisix-go-plugin-runnercmd/go-runner 中的官方示例展示瞭如何使用 Go Runner SDK Go Runner SDK 未來還將支援通過 Go Plugin 機制載入預編譯外掛。

https://github.com/apache/apisix-go-plugin-runner

開發 Go Runner

使用 Go Runner SDK 進行開發 官方示例的目錄結構如下圖所示。

$ tree cmd/go-runner
cmd/go-runner
├── main.go
├── main_test.go
├── plugins
│   ├── say.go
│   └── say_test.go
└── version.go

main.go 是入口點,這裡是最關鍵的部分。

cfg := runner.RunnerConfig{}
...
runner.Run(cfg)

RunnerConfig 可用於控制日誌級別和日誌輸出位置。 runner.Run 將使應用程式監聽目標位置,接收請求並執行註冊的外掛。應用程式將保持此狀態,直到退出。開啟 plugins/say.go .

func init() {
  err := plugin.RegisterPlugin(&Say{})
  if err != nil {
    log.Fatalf("failed to register plugin say: %s", err)
  }
}

由於 main.go 匯入了外掛包,

import (
  ...
  _ "github.com/apache/apisix-go-plugin-runner/cmd/go-runner/plugins"
  ...
)

這在 Say 執行 plugin.RegisterPlugin 之前註冊 runner.Run。 Say 需要實現以下方法。該 Name 方法返回外掛名稱。

func (p *Say) Name() string {
  return "say"
}

ParseConf 將在外掛配置更改時呼叫,解析配置並返回外掛特定的配置上下文。

func (p *Say) ParseConf(in []byte) (interface{}, error) {
  conf := SayConf{}
  err := json.Unmarshal(in, &conf)
  return conf, err
}

外掛的上下文如下:

type SayConf struct {
  Body string `json:"body"`
}

Filter 將在每個 Say 配置了外掛的請求上執行。

func (p *Say) Filter(conf interface{}, w http.ResponseWriter, r pkgHTTP.Request) {
  body := conf.(SayConf).Body
  if len(body) == 0 {
    return
  }

  w.Header().Add("X-Resp-A6-Runner", "Go")
  _, err := w.Write([]byte(body))
  if err != nil {
    log.Errorf("failed to write: %s", err)
  }
}

可以看到 Filter 把配置裡面 body 的值作為 response body 。如果直接在外掛中做出響應,則會中斷請求。詳情請參考 Go Runner SDK API 文件。

https://pkg.go.dev/github.com/apache/apisix-go-plugin-runner

構建應用程式後( make build 在示例中),需要在執行時設定兩個環境變數。

  • 1、APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock

  • 2、APISIX_CONF_EXPIRE_TIME=3600 像這樣:

APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock APISIX_CONF_EXPIRE_TIME=3600 ./go-runner run

應用程式將 /tmp/runner.sock 在執行時進行監聽。

設定 Apache APISIX(開發)

第一步是安裝 Apache APISIX ,它需要與 Go Runner 位於同一例項中。

上圖左邊是 Apache APISIX 的工作流程,右邊的 plugin runner 負責執行用不同語言編寫的外部外掛。 apisix-go-plugin-runner 就是這樣一個支援 Go 語言的執行器。

Apache APISIX 中配置外掛執行器時, Apache APISIX 會將外掛執行器視為自己的子程序,與 Apache APISIX 程序屬於同一使用者,當我們重新啟動或重新載入 Apache APISIX 時,外掛執行器也會重新啟動.

如果為給定路由配置了 ext-plugin-* 外掛,則命中該路由的請求將觸發 Apache APISIX 通過 unix 套接字對外掛執行器進行 RPC 呼叫。通話分為兩個階段。

ext-plugin-pre-req :在實現大部分 Apache APISIX 內建外掛( Lua 語言外掛)之前

  • ext-plugin-post-req :執行 Apache APISIX 內建外掛( Lua 語言外掛)後

請根據需要配置外掛執行器的執行時間。外掛執行器處理 RPC 呼叫,在其中建立模擬請求,然後執行用其他語言編寫的外掛並將結果返回給 Apache APISIX 。這些外掛的執行順序在 ext-plugin-* 外掛配置條目中定義。與其他外掛一樣,它們可以即時啟用和重新定義。為了展示如何開發 Go 外掛,我們首先設定 Apache APISIX 進入開發模式。將以下配置新增到 config.yaml

ext-plugin:
  path_for_test: /tmp/runner.sock

這個配置意味著在命中路由規則後, Apache APISIX 會向 /tmp/runner.sock 發起 RPC 請求。接下來,設定路由規則。

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
  "uri": "/get",
  "plugins": {
    "ext-plugin-pre-req": {
      "conf": [
        {"name":"say", "value":"{\"body\":\"hello\"}"}
      ]
    }
  },
  "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}
'

注意外掛名配置在 name ,外掛配置( JSON 序列化後)放在 value . 如果您在開發期間看到 refresh cache and try againApache APISIX 上的 key not found 警告和 Runner 上的警告,這是由於配置快取不一致造成的。由於 Runner 在開發狀態下不受 Apache APISIX 管理,內部狀態可能不一致。別擔心 ,Apache APISIX 會重試。然後我們請求: curl 127.0.0.1:9080/get

$ curl http://127.0.0.1:9080/get
HTTP/1.1 200 OK
Date: Mon, 26 Jul 2021 11:16:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Resp-A6-Runner: Go
Server: APISIX/2.7

hello

可以看到介面返回 hello ,並沒有訪問任何上游。

設定 Apache APISIX(執行)

下面是一個 go-runner 的例子,只需在 ext-plugin 中配置執行命令列即可執行。

Apache APISIX 將外掛執行器視為自己的子程序並管理其整個生命週期。

注意:此時不要配置 path_for_test。Apache APISIX 會自動為執行程式分配一個 unix 套接字地址,以便在它啟動時進行監聽。不需要手動設定。

概括

Go Plugin Runner 仍處於早期開發階段,我們將繼續改進其功能。歡迎您參與 apisix-go-plugin-runner 的開發,讓我們一起架起 Apache APISIX Go 之間的橋樑!

https://github.com/apache/apisix-go-plugin-runner

相關文章

如何用 Java 編寫 Apache APISIX 外掛

https://medium.com/@ApacheAPISIX/how-to-write-an-apache-apisix-plugin-in-java-3fb7b75444fa

關於 Apache APISIX

Apache APISIX 是一個動態、實時、高效能的 API 閘道器。 Apache APISIX 提供了豐富的流量管理功能,例如負載均衡、動態上游、金絲雀釋出、熔斷、身份驗證、可觀察性等。您可以使用 Apache APISIX 來處理傳統的南北向流量,以及服務之間的東西向流量。它也可以用作 k8s 入口控制器。

Github:https ://github.com/apache/apisix 網站:https ://apisix.apache.org

參考地址 [1]

參考資料

[1]

參考地址: https://apisix.apache.org/blog/2021/08/19/go-makes-Apache-APISIX-better/