Kong Gateway Operatorのkind: AIGatewayを試す

Kong Gateway、Kong Ingress Controller(以下KIC)を簡単にデプロイ・管理するためのOperatorとして[Kong Gateway Operator](https://github.com/Kong/gateway-operator)(以下KGO)というものがある。
このOperatorが提供するカスタムリソースの中に[`kind: AIGateway`](https://docs.konghq.com/gateway-operator/latest/reference/custom-resources/#aigateway)というリソースがexperimentalで用意されており、Kong GatewayをAI Pluginを入れ込んだ形で簡単にデプロイ出来るようになっている。
これを試してみる。

## `kind: AIGateway`の仕組み
`kind: AIGateway`をapplyすると、Operatorが以下のリソースを自動で生成、展開する。
```mermaid
flowchart LR
    AIGateway --> Gateway
    AIGateway --> HTTPRoute
    AIGateway --> KongPlugin
    AIGateway --> Service
    Gateway --> ControlPlane
    Gateway --> DataPlane
    Gateway --> NetworkPolicy
    ControlPlane --> Deployment1["Deployment,ReplicaSet,Pod,Service"]
    DataPlane --> Deployment2["Deployment,ReplicaSet,Pod,Service"]
    style AIGateway stroke:#f00
    style KongPlugin stroke:#f00
    style ControlPlane stroke:#f00
    style DataPlane stroke:#f00    
    style Gateway stroke:#0f0   
    style HTTPRoute stroke:#0f0   
```
赤枠がKGOが提供するカスタムリソースで、緑枠がGatway APIが提供するカスタムリソースである。
上記のカスタムリソースのうち、KGOが提供するカスタムリソースの役割は以下となる。(参考：[Custom Resource Definitions API Reference](https://docs.konghq.com/gateway-operator/latest/reference/custom-resources/))
|リソース名|役割|
|---|---|
|ControlPlane|デプロイするKong GatwayのControlPlaneを定義する|
|DataPlane|デプロイするKong GatwayのDataPlaneを定義する|
|KongPlugin|`Namespace`単位でKong Gatewayの[プラグイン](https://docs.konghq.com/gateway/latest/key-concepts/plugins/)を定義|
|AIGateway|[AI向けPlugin](https://docs.konghq.com/hub/?category=ai)を設定する|

まとめると、`AIGateway`リソースを展開することで以下が自動で行われる。
- Kong Gatewayそのものがデプロイされる（`ControlPlane`、`DataPlane`）
- Kong Gateway内にAI用Pluginが導入・設定される（`KongPlugin`）
- Kong Gatewayにアクセス・利用するためのルーティング設定が行われる（`Gateway`、`HTTPRoute`、`Service`、`NetworkPolicy`）

これにより、「Kubernetesのリソースがたくさんあって構築・管理がムズカシイ！」という人でも簡単にKong AI Gatewayが利用できるようになる。はず。

## KGOの導入
`kind: AIGateway`を試すためにKGOをインストールし、カスタムリソースを展開する。
KGOはKongのHelmチャートのリポジトリに含まれている。
```sh
NAME                 	CHART VERSION	APP VERSION	DESCRIPTION
kong/kong            	2.38.0       	3.6        	The Cloud-Native Ingress and API-management
kong/gateway-operator	0.1.4        	1.2.0      	Deploy Kong Gateway Operator
kong/ingress         	0.12.0       	3.6        	Deploy Kong Ingress Controller and Kong Gateway
```
なので、Kongのチャートリポジトリを追加してHelmでインストールする。
```sh
helm repo add kong https://charts.konghq.com
helm repo update kong
helm upgrade --install kgo kong/gateway-operator -n kong-system --create-namespace 
```
インストールすると以下のようにOperatorのPodが展開される。
```sh
$ kubectl get pod -n kong-system
NAME                                                       READY   STATUS      RESTARTS   AGE
gateway-operator-admission-t4pvp-6pg8w                     0/1     Completed   0          2m20s
kgo-gateway-operator-controller-manager-6654b9f6d4-ggdbb   2/2     Running     0          22m
```

なお、KGOインストール時にGateway APIのカスタムリソースも自動で導入されるため、別途インストールする必要はない。
KGOの導入としては上記手順で終了だが、`kind: AIGateway`を使うには追加の設定が必要となる。
`kind: AIGateway`はまだアルファ版レベルの実験的機能で、'24/4時点ではデフォルトで機能に蓋がされている。
以下を実行し環境変数をOperator側に設定することで[利用できるようになる](https://docs.konghq.com/gateway-operator/latest/guides/ai-gateway/#enable-the-ai-gateway-controller)。
```sh
kubectl set env -n kong-system deployments/kgo-gateway-operator-controller-manager -c manager GATEWAY_OPERATOR_ENABLE_CONTROLLER_AIGATEWAY="true"
```
また、`AIGateway`作成時にどのGateway Controllerを使うか指定する必要があるため、`GatewayClass`も作成しておく
```yaml
cat <<EOF | kubectl apply -f -
kind: GatewayClass
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: kong
spec:
  controllerName: konghq.com/gateway-operator
EOF
```

## 動作確認

[AI Gateway](https://docs.konghq.com/gateway-operator/latest/guides/ai-gateway/)のページを参考にAI Gatewayを検証する
ここでは検証にお金が掛からない[Cohere](https://cohere.com/)のAPIトークンを使って検証する。
最初にCohereのAPIトークンをSecret化する。
```sh 
COHERE_KEY=NZv930oWCxxxxxx
kubectl create secret generic acme-ai-cloud-providers --from-literal=cohere=$COHERE_KEY -n demo
```
`Secret`のキー名はLLMのプロバイダによって決まる。cohere以外のものを選ぶ場合は`kubectl explain aigateway.spec.cloudProviderCredentials`とかで確認するとよい。
次に`AIGateway`リソースを作成する。なおこのリソースを作成した時点で`Gateway`、`HTTPRoute`、`KongPlugin`、`ControlPlane`、`DataPlane`といったリソースが自動で作成される。
```yaml
cat <<EOF > ./cohere.yaml
apiVersion: gateway-operator.konghq.com/v1alpha1
kind: AIGateway
metadata:
  name: kong-aigateway
spec:
  gatewayClassName: kong
  largeLanguageModels:
    cloudHosted:
    - identifier: devteam-chatgpt
      model: command
      promptType: chat
      aiCloudProvider:
        name: cohere
  cloudProviderCredentials:
    name: acme-ai-cloud-providers
EOF
kubectl apply -f ./cohere.yaml -n demo
```
`gatewayClassName`にはKGOインストール時に作成した`GatewayClass`を指定する。
`cloudHosted`内の設定値についてはAI Proxy Pluginの[Cohereの設定](https://docs.konghq.com/hub/kong-inc/ai-proxy/how-to/cohere/)を参考に設定した。
個別の設定が必要な場合は`cloudHosted`内に書いていく。
`identifier`はRouteのパスになるため、デプロイ後は\<`Gateway`のアドレス/`identifier`\>にアクセスするとCohereを叩くことになる。
`cloudProviderCredentials`には先程作成したAPIトークンが入った`Secret`を指定する。`Secret`のvalueの指定などは不要。
リソースが作成された後、正常にOperatorが動作すれば以下のような形で`Gateway`等のリソースが作成される。
```sh
$ kubectl tree aigateway kong-aigateway -n demo
NAMESPACE  NAME                                                                         READY  REASON  AGE
demo       AIGateway/kong-aigateway                                                     -              14h
demo       ├─Gateway/kong-aigateway                                                     True   Ready   14h
demo       │ ├─ControlPlane/kong-aigateway-r7phq                                        True   Ready   14h
demo       │ │ ├─Deployment/controlplane-kong-aigateway-r7phq-8rhmn                     -              14h
demo       │ │ │ └─ReplicaSet/controlplane-kong-aigateway-r7phq-8rhmn-75d7fb69f7        -              14h
demo       │ │ │   └─Pod/controlplane-kong-aigateway-r7phq-8rhmn-75d7fb69f7-nx8d7       True           14h
demo       │ │ ├─Secret/controlplane-kong-aigateway-r7phq-4f6dc                         -              14h
demo       │ │ ├─Secret/controlplane-kong-aigateway-r7phq-rw598                         -              14h
demo       │ │ ├─Service/controlplane-webhook-kong-aigateway-r7phq-25snf                -              14h
demo       │ │ │ └─EndpointSlice/controlplane-webhook-kong-aigateway-r7phq-25snf-z9mtn  -              14h
demo       │ │ └─ServiceAccount/controlplane-kong-aigateway-r7phq-s7ftm                 -              14h
demo       │ ├─DataPlane/kong-aigateway-g2pbv                                           True   Ready   14h
demo       │ │ ├─Deployment/dataplane-kong-aigateway-g2pbv-glbj4                        -              14h
demo       │ │ │ └─ReplicaSet/dataplane-kong-aigateway-g2pbv-glbj4-85ff4b799            -              14h
demo       │ │ │   └─Pod/dataplane-kong-aigateway-g2pbv-glbj4-85ff4b799-pnv2q           True           14h
demo       │ │ ├─Secret/dataplane-kong-aigateway-g2pbv-dj498                            -              14h
demo       │ │ ├─Service/dataplane-admin-kong-aigateway-g2pbv-68sp7                     -              14h
demo       │ │ │ └─EndpointSlice/dataplane-admin-kong-aigateway-g2pbv-68sp7-mhg6c       -              14h
demo       │ │ └─Service/dataplane-ingress-kong-aigateway-g2pbv-clrdp                   -              14h
demo       │ │   └─EndpointSlice/dataplane-ingress-kong-aigateway-g2pbv-clrdp-cbfkx     -              14h
demo       │ └─NetworkPolicy/kong-aigateway-g2pbv-limit-admin-api-q6vpt                 -              14h
demo       ├─HTTPRoute/devteam-chatgpt-egress                                           -              14h
demo       ├─KongPlugin/devteam-chatgpt-ai-proxy                                        -              14h
demo       └─Service/kong-aigateway-ai-sink                                             -              14h
```
なお、うまく展開されたかどうかは`AIGateway`リソースを確認しても分からないため、`Gateway`リソースが展開されたかどうか等で確認した方がよい。
（おそらくまだ実験的機能なので実装が追いついていない）
LLMに関する設定は`KongPlugin`内に設定されている。
```json
$ kubectl get kongplugin -n demo devteam-chatgpt-ai-proxy -o jsonpath={.config} | jq
{
  "auth": {
    "header_name": "Authorization",
    "header_value": "Bearer NZv930oWxxxxxx"
  },
  "logging": {
    "log_payloads": false,
    "log_statistics": true
  },
  "model": {
    "name": "command",
    "options": {},
    "provider": "cohere"
  },
  "route_type": "llm/v1/chat"
}
```

早速使ってみる。
最初に`Gateway`のアドレスを環境変数に設定する。
```sh
export PROXY_IP=$(kubectl get gateway kong-aigateway -o jsonpath='{.status.addresses[0].value}')
```
Kong Gatewayをcurlで叩く。
```sh
curl -s -X POST $PROXY_IP/devteam-chatgpt -H "Content-Type: application/json" --data-raw '{
    "messages": [{
    "role": "user",
    "content": "What is Kong Gateway?"
  }] }'
```
帰ってきた結果はこちら。
```
{"object":"chat.completion","model":"command","choices":[{"finish_reason":"stop","index":0,"message":{"content":"Kong Gateway is an open-source API Gateway solution. It is a microservices-oriented middleware solution that serves as a centralized gateway to handle all API traffic for infrastructure and applications. Kong facilitates governance, securing, and management of APIs and microservices in any architecture, including hybrid, multi-cloud, and distributed architectures.\n\nSome of the main features and functionalities of Kong Gateway are:\n1. **API Proxy** - Kong can proxy all requests to APIs and microservices in the underlying infrastructure. As a result, all services in the backend are completely shielded from clients. This decoupling provides agility in the infrastructure as backend services can be created, updated, and removed without the need for clients to change code or configurations.\n2. **Load Balancing** - Kong can distribute incoming API traffic across a number of services, ensuring that no single service is overwhelmed with too much traffic. This creates a highly available and fault-tolerant infrastructure.\n3. **Security** - Kong provides various mechanisms to secure APIs, such as SSL/TLS, authentication, and authorization. It allows for certificate provisioning and revocation, OCSP response caching, and automated renewal via an integrated certificate manager. It supports over a dozen authentication plugins, including native OAuth support, with which users can integrate with existing identity providers. It also provides support for token-based authentication, such as JWT, and declarative ACLs (Access Control Lists) to enforce authorization.\n4. **Data Aggregation and Transformation** - Kong allows for data aggregation by transforming requests and responses on the fly. It can transform requests from multiple clients into a standardized format for consumption by different services, and it can also be used to create a unified response format.\n5. **Analytics** - Kong provides analytics on API usage, such as the number of hits, the slowest requests, and traffic graphs. This enables teams to monitor and assess the performance of their APIs and microservices and plan for improvements or optimizations.\n6. **Management** - Kong has a GUI and a CLI that make it easy to manage APIs and microservices. Through these, you can configure APIs, manage plugins and certificates, view analytics, and manage authentication. Further, Kong provides a Developer Portal where developers can find documentation and test APIs via interactive docs. \n\nOverall, Kong Gateway is a powerful and comprehensive solution for managing and orchestrating APIs and microservices. It is widely used in modern application architectures to provide improved agility, security, and governance.","role":"assistant"}}],"id":"5e5a13c1-5ef8-4e8a-b5bd-f25d7456c47d","usage":{}}
```
ということで、Kong Gateway経由でCohereに簡単にアクセスすることが出来た。

## 所感

Kong GatewayやAI Pluginを難しく考えずに簡単にデプロイする仕掛けとして`kind AIGateway`は面白そうだ。
ただ、まだ実装途中の機能が多く、以下のような不満はあった。
- リソースの状態表示などが不十分（でも`kubectl explain`をしっかり書いてるのは立派）
- リコンサイルの仕掛けが不十分で、ぶら下がってるリソースを削除しても復旧してくれない
- PATCHに未対応なため、デプロイ後にmodel変更とかが出来ない。

中の人に聞いたところ、まだまだ絶賛実装中とのことで、上記の点も修正されるっぽいので将来が楽しみではある。
バージョンがあがったらまた試そうと思う。