Gateway API & Cilium でWebSocketが利用できるか確認してみる
背景
- Gateway APIは利用者が少ないのか情報がない。WebSocketをサポートしているのかもよくわからない
- WebSocketもすんなり利用できるのか、それとも色々頑張らないといけないのか、そもそも対応させることが不可能なのか切り分けたい
背景の背景
- CiliumとIstioを比較するとCiliumが軽量で魅力的なので使ってみたい
- kube-proxyが不要になるように設定済み
- Gateway APIが利用できるように設定済み
- 環境はEKS
- GitopsにFlux2 + Flaggerを入れたい (諦めてArgoCDを使えばいいのかもしれない)
- FlaggerはGateway APIをサポートしているので、Cilium + Gateway APIなら他にIngressControllerなどを入れる必要がない。非常にシンプルで嬉しい。
流れ
- Hasuraをk8s上で動かしてみてSubscription(WebSocket)が使えるのか検証をしてみる
準備
まずはPostgresを立ち上げておく。
Aurora Serverless v2でv15をつくってみる。立ち上げに20分ほどかかる。コードは割愛。
その間にHasuraのドキュメントをあさる。
いい感じのデプロイガイドがある。
公式で用意されているyamlを調整してPulumiで書く。Pulumiについては割愛。
- ServiceをLoadBalancerからClusterIPにする
- Service用のHTTPRouteを作成する
Pulumiで定義したHTTPRouteは以下のような感じ。thisで参照している部分は名前から察してください。
他にRouteはないので全てリクエストがHasuraに流れるはず。
new k8s.apiextensions.CustomResource("http-route", {
apiVersion: "gateway.networking.k8s.io/v1beta1",
kind: "HTTPRoute",
metadata: {
namespace: this.namespace.metadata.name,
name: "hasura",
},
spec: {
parentRefs: [
{
name: "gateway",
namespace: "kube-system",
},
],
rules: [
{
backendRefs: [
{
name: this.service.metadata.name,
port: this.service.spec.ports[0].port,
},
],
},
],
},
})
ぜんぜんAurora Serverless v2のインスタンスが立ち上がらない。
と思ったらできた!1820秒かかった…。
✗ pulumi up
Updating (example):
Type Name Status
pulumi:pulumi:Stack stack8-example
└─ stack8 stack8
└─ stack8:aws aws
+ └─ stack8:aws:Database database created (0.53s)
+ ├─ aws:rds:ParameterGroup cluster-parameter-group created (1s)
+ ├─ aws:rds:ParameterGroup instance-parameter-group created (0.94s)
+ ├─ aws:rds:SubnetGroup subnet-group created (0.82s)
+ ├─ aws:rds:Cluster cluster created (92s)
+ ├─ aws:rds:ClusterInstance cluster-instance-1c created (991s)
+ └─ aws:rds:ClusterInstance cluster-instance-1a created (1820s)
ではHasura用のリソースを入れてみる。
すんなりOK、とは行かず、Podが立ち上がらない。
Readiness probe failed
エラーが出ている。Ciliumか?
Ciliumのトラブルシューティング用のドキュメントにconnectivity-problems
があったので、まずはここを見てみる。
色々なProbeが設定されたDeploymentとServiceを入れて、問題が発生している箇所の確認ができるらしい。
入れてみる。
kubectl create ns cilium-test
kubectl apply --namespace=cilium-test -f https://raw.githubusercontent.com/cilium/cilium/v1.15.0-rc.0/examples/kubernetes/connectivity-check/connectivity-check.yaml
入ったPodがRunningになっていれば問題ないらしい。
✗ kubectl get pods -n cilium-test
NAME READY STATUS RESTARTS AGE
echo-a-84b5975d67-47g9l 1/1 Running 0 11s
echo-b-57dfc876d5-7qr6n 1/1 Running 0 11s
echo-b-host-587d44788b-tqws8 1/1 Running 0 11s
host-to-b-multi-node-clusterip-54b75f998d-td9tl 1/1 Running 0 10s
host-to-b-multi-node-headless-78bcbc6f9b-fwsbs 1/1 Running 0 10s
pod-to-a-68d9b9d5d-cxmsz 1/1 Running 0 10s
pod-to-a-allowed-cnp-85b8f754bd-fdn8p 1/1 Running 0 10s
pod-to-a-denied-cnp-5fdd4cdc58-72bsz 1/1 Running 0 10s
pod-to-b-intra-node-nodeport-6db7f65984-zcd97 1/1 Running 0 9s
pod-to-b-multi-node-clusterip-857855dc74-n2gfl 1/1 Running 0 10s
pod-to-b-multi-node-headless-788f886b4d-4tngv 1/1 Running 0 10s
pod-to-b-multi-node-nodeport-668df7b68d-w5w8w 1/1 Running 0 9s
pod-to-external-1111-656bc7c4d4-xl5t4 1/1 Running 0 10s
pod-to-external-fqdn-allow-google-cnp-f6df4f66-p6m6s 1/1 Running 0 10s
あれ、起動してる。Ciliumさん疑ってすみませんでした。
HasuraのPodをProbeをなくして起動するようにしてみたら、もう少し詳細なエラーログが確認できた。
{"detail":{"info":{"database_url":"postgres://postgres:...@s8-stack8-example.cluster-cdqwryow4hqg.ap-northeast-1.rds.amazonaws.com:5432/postgres","retries":1},"kind":"postgres_connection"},"level":"info","timestamp":"2024-01-10T08:08:02.696+0000","type":"startup"}
{"detail":{"message":{"host":"Unknown or invalid host","message":"Postgres connection failed","retry_attempt":0}},"level":"warn","timestamp":"2024-01-10T08:10:13.768+0000","type":"pg-client"}
RDSに繋げないらしい。
bashに入って疎通を確認する。
✗ kubectl exec --stdin --tty hasura-5ff4686f46-8hgxw -n example-app -- /bin/bash
root@hasura-5ff4686f46-8hgxw:/# nc -zv s8-stack8-example.cluster-cdqwryow4hqg.ap-northeast-1.rds.amazonaws.com 5432 -w 10
nc: connect to s8-stack8-example.cluster-cdqwryow4hqg.ap-northeast-1.rds.amazonaws.com (10.0.63.25) port 5432 (tcp) timed out: Operation now in progress
ダメそうだ。
EKS周りのセキュリティーグループがややこしくて適当に設定していたツケがここで回ってきたか。
というわけでEKSのセキュリティーグループについて理解してみた
この理解に従って実装してみる。実装内容については割愛。
ノードグループの更新に時間がかかるが、なんとか完了。
RDSに接続できるようになり、Readiness Probeも通るようになった。
Hasuraの管理画面が表示できた。
Subscriptionを呼び出して、WebSocketも問題なく疎通していることを確認。
よかった。
まとめ
Gateway API & Cilium でWebSocketは特に意識しなくても利用できるっぽい