自宅のK8sに外部からアクセスしたい。が、ポート開放はあまりしたくない&技術的に興味があるのでCloudflare Tunnelを使ってみようと思う。
Cloudflare Zero Trustを使って認証もできるのでセキュアっぽい。
その前にNASとしてUgreenの新しいやつを導入した。それにあたって今までNASとして利用してきたミニPCが空いたので、こいつにもUbuntuをインストールして新しいNodeとして活躍してもらおうと思う。スペックはN95とかそんなんだった気がする。メモリが多分8GBかな?
過去の記事を読んでIPアドレスを設定したいのだが既に存在するクラスタのノード数は五個、にも関わらず記事には六個分のIPが書かれている。確かにマスターノードは三つあるはずなのでワーカーノードが一個分嘘ついてるっぽい。せっかくだしこのワーカーノードのIPとして最後に列挙されてる172.28.6.23を指定すれば上手く動くだろう。多分知らんけど
その前にそもそもしばらく放置されてたので各ノードのアップデートもしておこう。IPアドレスの確認もできるはずだ。
...
というわけで新しいノードには172.28.6.23を付与してワーカーノードとして働いてもらう。
アップデートやらインストールに時間がかかるのでRevolution Idleを眺めつつマリカワールドをプレイする。
インストールは完了したがsshログインするための諸々を入れ忘れた。
sudo apt update
sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
sudo systemctl status ssh
sudo ufw allow ssh
適当にこの辺をやってsshで入れるようにした。
...
マリカワールドのエンディングが流れ始めたので続きをやっていく
sudo snap install microk8s --classic
ワーカーにclassicが必要なのかはよく分からないがどうせ自宅用なのでつけておこう。
microk8s status --wait-ready
これをやる。
/home/worker3/.kube
が存在しないと言われてしまった。
ChatGPTに聞いたら
mkdir -p ~/.kube
microk8s config > ~/.kube/config
sudo chown -R $(whoami) ~/.kube
sudo snap alias microk8s.kubectl kubectl
とやれと言われたのでやる。前もこんなのやったっけ?
よくよく考えなくても最後のkubektlは必要ないな。
適当な既存のノードで
microk8s add-node
として出てきたコマンドを新しいノードで叩くと登録されるはず。された。
クラスタに外部からアクセスしようとしたがtlsのエラーが出てしまった。failed to verify certificateらしい。
改めてconfigを作ったりもしたがだめ
マスターでip aしてみるとvip先生のIPが表示されない。podは存在しているっぽいが
とりあえずvip先生のpodを再起動
改めてマスターでip aしてるとipは紐付いている。
microk8s kubectl configしたconfigを持ってくると、こいつでは繋がるがvip先生のipでは繋がらない。
/var/snap/microk8s/current/certs/csr.conf.templateを見てみるとvip先生のipが消えていたので、再度vip先生のipを追加してconfigを再発行したがまだ動かない。
一旦もろもろのバージョンを上げてみる。
そもそもkube-vipの入れ直しの段階でip aしてみたらまたvip先生のipが消えていたので何かがおかしそうだ。
しかし動かない\(^o^)/
再びマスターでip aしてみるとまたvip先生のipが消えていた。
そういえばログ読んだときにworker3に処理を任せたぜみたいな記述があったのを思い出した。
もしかしてと思いworker3でsudo microk8s configして発行した中身をクライアントの~/.kube/configに入れてみる。もちろん動くがipをvip先生のものにすると動かない。そういえばcrtのテンプレートを編集するのを忘れていた。
sudo vim /var/snap/microk8s/current/certs/csr.conf.template
をして
IP.3 = 172.28.6.100
を追加。
sudo microk8s refresh-certs --cert server.crt
としてみたらようやく動いた。めでたしめでたし。

ノードがたくさんあると気分が良いね。ラズパイとかも混ぜてみたいけどアーキテクチャ変わるからめんどくさそうな予感しかしない。
microk8sのバージョンが古いのでここで一通り上げておこう。
sudo snap refresh microk8s --channel=latest/stable
を実行すればよしなにしてくれるみたい。
クライアントとしてk9sを使っているけど、バージョンアップして自動で再起動されたことが確認できた。無停止ってのは気分が良い。
そういえばこのクラスタではnginx ingressを入れている。なので各ノードでnginx ingressのコントローラが動いているはずなのだが、どうにも新しいノードで立ち上がっていないっぽい。
podをdescribeしてみると、どうにもこのクラスタではciliumをCNIとして使っているのだが、デフォルトのCNIであるcalicoを使おうとして見つからないとエラーが出ているようだ。
そういえばcilium用の設定ファイルを追加する必要があったんだった。
/etc/cni/net.d/05-cilium-cni.conf
に、他のノードから持ってきた中身をコピペ、適当に再起動したら動いた。
{
"cniVersion": "0.3.1",
"name": "cilium",
"type": "cilium-cni",
"enable-debug": true,
"log-file": "/var/run/cilium/cilium-cni.log"
}
中身はこんなん。
そういえばciliumのアップデートはどうするんだろう。microk8sのaddon機能で入れたけども、どうにもdisableしてからenableするらしい?ほんまか?
やってみたらバージョンは上がったっぽいけどどうにも腑に落ちない。
一旦使える状態にはなった気がする。
改めてCloudflare Tunnelを使って外部からアクセスできるようにしよう。
developers.cloudflare.com
このページを参考に設定。マニフェストデプロイの時にconfigMapを弄ってビルトインのhello_worldを表示するようにしてみる。
apiVersion: v1
kind: ConfigMap
metadata:
name: cloudflared
data:
config.yaml: |
# Name of the tunnel you want to run
tunnel: coil398-k8s-tunnel
credentials-file: /etc/cloudflared/creds/credentials.json
# Serves the metrics server under /metrics and the readiness server under /ready
metrics: 0.0.0.0:2000
# Autoupdates applied in a k8s pod will be lost when the pod is removed or restarted, so
# autoupdate doesn't make sense in Kubernetes. However, outside of Kubernetes, we strongly
# recommend using autoupdate.
no-autoupdate: true
# The `ingress` block tells cloudflared which local service to route incoming
# requests to. For more about ingress rules, see
# https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/ingress
#
# Remember, these rules route traffic from cloudflared to a local service. To route traffic
# from the internet to cloudflared, run `cloudflared tunnel route dns <tunnel> <hostname>`.
# E.g. `cloudflared tunnel route dns example-tunnel tunnel.example.com`.
ingress:
- hostname: k8s.coil398.io
service: hello_world
- service: http_status:404
多分こんな感じ。
ついでに本体の方のimageを2025.5.0にする。
https://k8s.coil398.ioにアクセスしたら動いた。やったね。

そしたらマスターノードにアクセスできるようにしたい。正確にはVIP先生に繋がるようにしたい。
ついでにダッシュボードとargocdにもアクセスできるようにしよう。
ingress:
- hostname: master.k8s.coil398.io
service: https://172.28.6.100:16443
originRequest:
noTLSVerify: true
- hostname: dashboard.k8s.coil398.io
service: https://dashboard-cloudflared.kube-system.svc.cluster.local
originRequest:
noTLSVerify: true
- hostname: argocd.k8s.coil398.io
service: https://argocd-cloudflared.argocd.svc.cluster.local
originRequest:
noTLSVerify: true
- hostname: k8s.coil398.io
service: hello_world
- service: http_status:404
このように書き換え
それでトンネルにこれらのFQDNを登録
cloudflared tunnel route dns coil398-k8s-tunnel dashboard.k8s.coil398.io
cloudflared tunnel route dns coil398-k8s-tunnel argocd.k8s.coil398.io
cloudflared tunnel route dns coil398-k8s-tunnel master.k8s.coil398.io
で、アクセスしてみると
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
というエラー。調べてみると
developers.cloudflare.com
どうやらCloudflaredのデフォルトの証明書ではサブドメイン一階層までしかカバーされないらしい。
なので別途金を払って証明書を追加する。月10$ならまぁ、うん。
これで無事ダッシュボードとArgoCDにアクセスできるようになった。
一方でmasterへのアクセスはうまくいかない。よくよく考えると外部からマスターにアクセス可能になったとしてどうやって認証情報を手に入れれば良いんだ?
一旦先にZero Trustによる認証機能をつけようと思う。
Zero Trustは普通に申し込めば無料で使える。
躓きそうなポイントとしては
認証方法の追加はsettings -> Authenticationから
自分はGithub認証にした。テストの段階でこけることがあるが、しばらく経つと上手くいく。
基本的には右にあるガイドに従えば良い。
チーム名は最初に決めるが、なかなか書いてあるところが見つからない。
settings -> Custom Pagesを見たら書いてあった。
あとはAccess -> Applicationsから追加していけば良い。
多分URLごとにアプリケーションを作る必要がある。
アプリケーションの追加ではSelf-hostedを選択
Application nameは適当に
Add public hostnameで追加する。
ポリシーはGithubのEmailにAlowを付与した。これで自分しかアクセスできなくなるはず。
それ以外は特に弄らずボタンポチポチで完成。
dashboardは認証をつけたのでデフォルトの認証を無効にしたい。
deploymentを弄ろうと思ったがmicrok8sのaddonで入れているので存在しない。
面倒なので直接deploymentを編集して
- --enable-skip-login
- --disable-settings-authorizer
をspec.template.spec.containers[0].argsに入れた。これで外からでも快適にアクセスできる。
そして本命のvip先生への外部からのアクセスだが、さすがに疲れたのでこの辺で一旦終わる。