🚀

K8S Dashboard を Cloudflare Tunnel 経由で公開する

2024/12/01に公開

microk8s のダッシュボードアドオンをインターネットからアクセスできたら便利なので、色々やってみる。インターネットへの公開は直接晒すと何かとくないので、Cloudflare Zero Trust の Tunnel や Access 機能を用いて間接的に公開するようにする。

ちなみに、本当はこんなことを本番環境でやるとだいぶ良くないと思われるのだが、テスト環境でやるので深く考えないことにする。

前提

  • Ubuntu
  • Snap + microk8s
  • シングルノード構成前提につき、マルチノードの場合は色々考えることが増えるかも?

本編

microk8s と追加パッケージのインストール

microk8s と ingress アドオン、dashboard アドオンを入れる。これで着信処理を捌いてダッシュボードをインターネットに公開する準備を整えられるようになる。

具体的には Deployment やら Service やらがこれで勝手に K8S に仕込まれる。つまり K8S の中では以下を実行した時点でダッシュボードの展開が済むので、他にやることはインターネットから着信を待ち受けるようにすることだけである。

snap install microk8s --classic
microk8s enable ingress
microk8s enable dashboard

Ingress 定義のデプロイ

nginx で着信を待ち受けて、着信が特定のバーチャルホスト宛であるときダッシュボードのサービスにトラフィックを誘導させる。

microk8s kubectl apply -f ingress-k8s-dashboard-internet.yaml
microk8s kubectl apply -f ingress-k8s-dashboard-intranet.yaml
  • ingress-k8s-dashboard-internet.yaml: インターネットからのアクセス
  • ingress-k8s-dashboard-intranet.yaml: LAN からのアクセス

この時点で、理屈の上ではノードの OS にログインした後ノードの内側で(バーチャルホスト宛に)curl などをしてやるとダッシュボードにアクセスは出来るはずである。

Cloudflare Zero Trust の設定

  1. Cloudflare Tunnel を K8S のノード宛にどうにかして通す
  2. Cloudflare Tunnel の Public Hostname で、上記のバーチャルホストを https://localhost にリダイレクトするように設定する
  3. Cloudflare Access の Application でバーチャルホストにマッチするアプリを作って特定のユーザーからしかログインできないようにする

導通確認

Cloudflare Tunnel で設定したバーチャルホストにアクセスすればダッシュボードが見えるようになってるはず?

TODO

  • MetalLB して LoadBalancer を用いてもインターネットに公開できないか試してみる
    • Ingress → Service する場合と Service の type: LoadBalancer する場合の違いがよくわからない。MetalLB で各サービスに(ノード外からアクセスできる)IP アドレスを割り当てたとしても、アドレスにドメインを割り当てるにはどうすれば?特にマルチノード構成の場合はよくわからなくなってくる。

補遺

NGINX Ingress が HTTP 400 を返す件

microk8s kubectl logs -n ingress nginx-ingress-microk8s-controller-brb8x すると以下のようなログが出ることがある。

2024/08/25 03:51:34 [error] 3001#3001: *57878 recv() failed (104: Connection reset by peer) while reading upstream, client: 10.10.0.9, server: example.local, request: "GET / HTTP/2.0", upstream: "http://10.1.107.132:8443/", host: "linoleum.local", referrer: "https://10.10.0.5:10443/"
10.10.0.9 - - [25/Aug/2024:03:51:34 +0000] "GET / HTTP/2.0" 400 48 "https://10.10.0.5:10443/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0" 20 0.001 [kube-system-kubernetes-dashboard-8443] [] 10.1.107.132:8443 48 0.001 400 225c6aa8a71fc44a27e3a4c98bfc08b9

これは ingress-nginx は Ingress の metadata.annotations に以下の設定を入れないと HTTP 400 を返してしまうせいである。多分 K8S Dashboard が HTTPS で終端しているのが原因である。

metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/configuration-snippet: |-
      proxy_ssl_server_name on;
      proxy_ssl_name $host

参考:

Discussion