汎用的なAILERON Gatewayを試してみる

最近OSSとして登場したAILERON Gatewayを触ってみます。
https://aileron-gateway.github.io/docs/

AILERON Gatewayは、Go言語で実装されたシンプル・軽量な汎用ゲートウェイで、Layer4, Layer7でのトラフィックルーティングや認証・認可機能などを備えているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116164/e566feab-452f-44a2-a19a-b034f10bfe88.png)

Exampleを見てみると、gRPCのプロキシなども対応している様子。
https://github.com/aileron-gateway/aileron-gateway/blob/main/_example/proxy-grpc/README.md

# ダウンロード
以下からv1.0.1のバイナリをダウンロードできるので、windows向けのバイナリを選択。
https://github.com/aileron-gateway/aileron-gateway/releases/tag/v1.0.1
https://github.com/aileron-gateway/aileron-gateway/releases/download/v1.0.1/aileron-windows-amd64.exe

他にも様々なバイナリが用意されているようです。
https://aileron-gateway.github.io/docs/installation/pre-built-binary/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116164/67a08032-ab04-48b2-a7cf-26af14c6327f.png)

# 起動
ダウンロードしたバイナリは素直に動作しました。
```
C:\opt\aileron>aileron-windows-amd64 -v
v1.0.1
```

なので、Getting StartedページのReverse Proxyのサンプルを動かしてみます。
https://aileron-gateway.github.io/docs/getting-started/reverse-proxy/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116164/d1e4f63a-f335-46f2-9beb-4c210f9bb4be.png)

config.ymlで以下の流れの設定を定義します。
1. Entrypointでリクエストを受け付けるサーバモジュール（HTTPServer）を指定
2. サーバモジュールからリバースプロキシモジュール（ReverseProxyHandler）を指定
3. リバースプロキシモジュールでは、アップストリームにhttp://httpbin.org を指定

自分の欲しい処理を差し込んでいく感じがシンプルで分かりやすいですね。

```yaml:config.yml
apiVersion: core/v1
kind: Entrypoint
spec:
  runners:
    - apiVersion: core/v1
      kind: HTTPServer

---
apiVersion: core/v1
kind: HTTPServer
spec:
  addr: ":8080"
  virtualHosts:
    - handlers:
        - handler:
            apiVersion: core/v1![aileron.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116164/f71bbfaf-f447-47c7-9079-d74f52e22ab9.png)

            kind: ReverseProxyHandler

---
apiVersion: core/v1
kind: ReverseProxyHandler
spec:
  loadBalancers:
    - pathMatcher:
        match: "/"
        matchType: Prefix
      upstreams:
        - url: http://httpbin.org
```

上記のyamlファイルを指定して起動します。
```
C:\opt\aileron>aileron-windows-amd64 -f config.yml
{"time":"2025-04-14 00:04:59","level":"INFO","msg":"server started. listening on [::]:8080","datetime":{"date":"2025-04-14","time":"00:04:59.044","zone":"Local"},"location":{"file":"httpserver/server.go","func":"httpserver.(*runner).Run","line":56}}
```

curlで動作確認すると問題なくアップストリームに転送されてますね。
```
C:\opt\aileron>curl http://localhost:8080/get
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/8.10.1",
    "X-Amzn-Trace-Id": "Root=1-67fbd320-0b8a6783728059020142ef8b",
    "X-Forwarded-Host": "localhost:8080"
  },
  "origin": "::1, XXX.XXX.XXX.XXX",
  "url": "http://localhost:8080/get"
}
```

# 他のモジュールを試す
Design DocやExampleを見ると、OPAによる認可、流量制御、ロードバランシングなどいろいろ対応してそうなので、他のモジュールの動作も軽く試してみます。

https://aileron-gateway.github.io/aileron-gateway/app/
https://github.com/aileron-gateway/aileron-gateway/tree/main/_example

以下の構成を実現してみます。
* OPAモジュールによりGETリクエストのみ許可（policy.regoに認可ルールを記載）
* ロードバランシングモジュールによりMockbinにラウンドロビンで負荷分散

![aileron.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116164/0ff56249-6b5c-4448-a481-22042d45a9a9.png)

定義は以下のとおり。
（https://mockbin.io/ でそれぞれ異なる応答を返すようにしています。便利ですね..）

```yaml:config.yml
apiVersion: core/v1
kind: Entrypoint
spec:
  runners:
    - apiVersion: core/v1
      kind: HTTPServer

---
apiVersion: core/v1
kind: HTTPServer
spec:
  addr: ":8080"
  virtualHosts:
    - middleware:
        - apiVersion: app/v1
          kind: OPAAuthzMiddleware
      handlers:
        - handler:
            apiVersion: core/v1
            kind: ReverseProxyHandler

---
apiVersion: app/v1
kind: OPAAuthzMiddleware
spec:
  regos:
    - queryParameter: "data.example.authz.allow"
      policyFiles:
        - ./policy.rego

---
apiVersion: core/v1
kind: ReverseProxyHandler
spec:
  loadBalancers:
    - pathMatcher:
        match: "/"
        matchType: Prefix
      lbAlgorithm: RoundRobin # Use RoundRobin load balancer (Default).
      upstreams:
        - url: https://33549c080ed24e79899c8506960feb7b.api.mockbin.io/ #Server1
        - url: https://8e3fbecc44af4cbc85ddf1c12accefc9.api.mockbin.io/ #Server2
```
```rego:policy.rego
package example.authz

import future.keywords.if

default allow := false

allow if {
    input.method == "GET"
}
```

最初と同様に起動します。
```
C:\opt\aileron>aileron-windows-amd64 -f config.yml
{"time":"2025-04-14 00:24:16","level":"INFO","msg":"server started. listening on [::]:8080","datetime":{"date":"2025-04-14","time":"00:24:16.245","zone":"Local"},"location":{"file":"httpserver/server.go","func":"httpserver.(*runner).Run","line":56}}
```

curlで動作確認すると、POSTメソッドだと拒否、GETメソッドだと2つのMockbinにロードバランスされてますね！良い感じです。
```
C:\opt\aileron>curl -X POST http://localhost:8080/get
{"status":403,"statusText":"Forbidden"}
C:\opt\aileron>
C:\opt\aileron>curl -X GET http://localhost:8080/get
{
  "message": "Server1, Hello!"
}
C:\opt\aileron>
C:\opt\aileron>curl -X GET http://localhost:8080/get
{
  "message": "Server2, Hello!"
}
C:\opt\aileron>
C:\opt\aileron>curl -X GET http://localhost:8080/get
{
  "message": "Server1, Hello!"
}
C:\opt\aileron>
```

# おわりに
プラガブルに自分の欲しい処理を書いていく感じが面白いな感じました。
独自の処理もMiddlewareとして追加できそうなので、対応できる範囲も広そうです。（業務ロジックやら何でもかんでもAILERONに実装してしまうとカオスになりそうなので、そこは注意かなと思いますが）
https://aileron-gateway.github.io/docs/how-it-works/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116164/4f3681bc-b690-4c29-879b-0e7c52e5ecf1.png)

まだ他にも様々なモジュールが用意されているので、次は別のモジュールを試してみます。