自宅K8Sクラスタを作る
ゴール
自宅でk8sクラスタを運用する
後からマシン増やせるようにする
別の自宅サーバと連携したい
こっちはデカいストレージを持っている
買った
TRIGKEY Green G4 https://amzn.to/3Ks0coA
N100マシン
RAM 16GiB
SSD 500GiB
情報収集
Proxmox
仮想環境管理アプライアンス
これ自体がコンテナを走らせることもできる
こいつの上にOSを入れていろいろ楽する
k3s https://k3s.io
k8sの小さい実装
バイナリがとてもちっこい
いくつかの機能を簡略化したk8s、みたいな感じ
パチモンではなくて、れっきとしたk8s
CNCF認定
Rancher社が作ってる
SUSEがコントリビュートしてる
etcdがsqliteになってるなどの軽量化がほどこされている
各種ARM対応を重点的にやっている
全体的にエッジ感が強い
MicroOS
SUSEが出したエッジ用OS
このテのコンテナ運用に便利なイミュータブルOS
システムの更新はすべてスナップショットを取ってトランザクショナルに行なわれる
自宅K8Sクラスタを作る/ストレージ
Rancher
k8sクラスタ監視くん
ArgoCD
CDしてくれるやつっぽい
external-dns
k8s上の公開サービスのIPを自動的に外部のDNSに登録してくれる君
たとえばRoute53を更新してもらう、といった便利機能が使える
サービス自体をLAN外部に公開しなくても、DNSだけ使ったりできる
cloudflareも使えてべんり
自宅 k8s クラスタのサービスに FQDN で繋がるようにした - 勇往邁進
CoreDNSという選択肢もあるっぽい
入れる
とりあえずProxmoxは入れるのでインストールする。
BIOSでSecureBootを切って仮想化機能をオンにする。
つっても 最初から問題なかった。
公式手順に従う。
https://www.proxmox.com/en/
ストレージはVMレベルで暗号化したいができてない
自宅内DNSでa.k8s.(ドメイン)を割り当てた
192.168.34.1に割り当てた
別の自作マシンからアクセスできない
digはできてるのでrouteがうまくいってない?
ゲートウェイのポート設定でeth4(N100マシンがつながってるハブと結線)がスイッチに参加してなかった
参加させる
つながった!
ディスク暗号化
https://forum.proxmox.com/threads/adding-full-disk-encryption-to-proxmox.137051/
Longhorn側でやってもいい
https://longhorn.io/blog/longhorn-v1.2/#encryption-volume-and-backup
下のMicroOSレベルでやってもいい
https://microos.opensuse.org/blog/2023-12-20-sdboot-fde/
これでいいと思う
OS入れる
ところでProxmoxとかでOS入れるときってどうするんだ
cloud-initという概念があるらしい
要するに設定ファイルを押し付ければその通りにセットアップできるよ、みたいな機構
もともとはAmazon EC2用に開発されたツールらしい
cloud-initを使ったLinux OSの初期設定 #AWS - Qiita
その書式がcloud-config
ほかにもシェルスクリプト走らせるなどいろいろあるらしい
それとは別に、ProxmoxレベルでVMのテンプレートがある
のちのちマシンを買い足したときなどに便利そう
とりあえずOSを何も考えずに1つ入れてみる
https://scrapbox.io/files/665b568b8ab785001cd58bd2.png
ここからISOイメージをアップしておく
URLからダウンロードを選んで、https://get.opensuse.org/ja/microos/#download にあるインストール用ISOのリンクを渡す
名前解決失敗した
なんかDNSの設定ミスしたかな
unboundのアクセス制御にノードのIPレンジが入ってなかった
入れて解消
普通にインストールできてる
最後の段階でディスク暗号化を選ばないと飛ばされてしまう
雑にOS入れた感想
ssh鍵どうしようね
Yubikeyがあるのでその公開鍵を入れさせるしかない
なんか便利な仕組みないか
暗号化どうしようね
途中でなんかいい感じにしたい
宅内DHCPつかんで別のレンジにIPが生えてしまった
できればホストと同じところに生えてほしい
rootパスワードとか毎回入れないといけない
cloud-initの出番?
https://en.opensuse.org/Portal:MicroOS/cloud-init
OpenStack用のMicroOSでないと使えない雰囲気
MicroOS的にはignitionという仕組みを使ってほしそう
https://ja.opensuse.org/Portal:MicroOS/Ignition
楽そうなこれで
MicroOS/Ignition
結局ignitionを入れたUSBをうまく認識してくれなかった?ので手でfull disk encryptionなどの設定した。次回はまたがんばる
k3s入れる
https://k3s.io にある通り
MicroOSの場合パッケージマネージャにあるのでこれで入れたらいい
transactional-update pkg in k3s-install
reboot
k3s-install
注意!! このあと、Rancherは最新のk3sで動かないことがわかるのでINSTALL_K3S_VERSION=v1.28.10+k3s1 k3s-installすることになりました。
どのバージョンまで行けるかは Rancher Manager v2.8.4 | SUSE で確認できる
systemctl start k3s
(Kubeconfig is written to /etc/rancher/k3s/k3s.yaml)
code:check
a:~ # k3s kubectl get node
NAME STATUS ROLES AGE VERSION
a.a.k8s.3qe.us Ready control-plane,master 69s v1.29.5+k3s1
ウェイ〜
Rancher入れる
Rancherでクラスタの様子を見られるようにする。
https://ranchermanager.docs.rancher.com/getting-started/quick-start-guides/deploy-rancher-manager/helm-cli#install-rancher-with-helm
k8s世界ではhelmというパッケージマネージャが登場していて、便利にデプロイできるようになっているとのこと。
事実上の標準ツールとなっているKubernetes向けデプロイツール「Helm」入門 | さくらのナレッジ
まずhelmを入れる。helmもパッケージマネージャにあるのでこれで入れていい。
transactional-update pkg in helm
reboot
helmでは、パッケージのことをchartという。Rancherのchartもあるので、これを入れる。
chartはリポジトリから提供されるが、Linuxディストリビューションのリポジトリとは違って、インストール直後は何も設定されていない:
code:list
a:~ # helm repo list
Error: no repositories to show
あとは公式の手順に従う:
code:install-rancher.sh
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
kubectl create namespace cattle-system
(cert-managerは最新のバージョンを確認すること)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.crds.yaml
ここでクラスタに接続できないと言われた。設定を読み込めてないっぽいので.bashrcに仕込む:
code:.bashrc
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
cf. https://9to5answer.com/error-kubernetes-cluster-unreachable-get-quot-http-localhost-8080-version-timeout-32s-quot-dial-tcp-127-0-0-1-8080-connect-connection-refused
再度applyしたら成功したので続き。
code:install-rancher.sh
helm install rancher rancher-latest/rancher \
--namespace cattle-system \
--set hostname=a.a.k8s.3qe.us \
--set replicas=1 \
--set bootstrapPassword=foobar(初期パスワードを設定する)
kubeVersionがデカすぎると怒られてしまった。知らねーよそんなの
code:err
Error: INSTALLATION FAILED: chart requires kubeVersion: < 1.29.0-0 which is incompatible with Kubernetes v1.29.5+k3s1
うーん、とはいってもパッケージマネージャで入れたやつのバージョン下げてよいものか・・・
とはいえパッケージマネージャで入れたk3sはインストーラなので、これでうまいことやったらちょっと古いk3s入れられるのでは
code:install.sh
INSTALL_K3S_VERSION=v1.28.10+k3s1 k3s-install
code:version
a:~ # kubectl get node
NAME STATUS ROLES AGE VERSION
a.a.k8s.3qe.us Ready control-plane,master 40m v1.28.10+k3s1
うまくいった。
もう一度Rancherを入れたらうまく入った。
自宅DNSの設定をしてa.a.k8s.3qe.usがこのIPを向くように設定しておく(略)。
なんかこのへんk3sクラスタにNSで放り投げたりできないもんですかね
あとでやることになる
MicroOSにアクセスするとRancherが立っている。ウェ〜イ
https://scrapbox.io/files/665b8a3ef744c5001dede12e.png
メモリがすこしパツってるのであとでVMに割り当てるメモリをもっと上げとこう
https://scrapbox.io/files/665b8a7361b995001df2ba7f.png
ストレージ
自宅K8Sクラスタを作る/ストレージ
ロードバランサ
MetalLBを入れる。k3sには最初からLBが搭載されているが、あまり相性が良くないのですてる。
CoreDNSによる自宅内サービスディスカバリ
自宅K8Sクラスタを作る/CoreDNSによる自宅内サービスディスカバリ
勝手にrebootしないで
https://www.reddit.com/r/openSUSE/comments/ooxcif/question_about_microos_updates_does_it_reboot/
Microosはアプデが来たりすると勝手に再起動してしまう。full-disk encryptionと相性が悪すぎるのでいったん無効化する
systemctl --now disable transactional-update.timer
https://documentation.suse.com/en-us/sle-micro/5.2/pdf/article-administration-slemicro_en.pdf
コンテナレジストリを用意する
自宅K8Sクラスタを作る/コンテナレジストリを用意する
Cloudflareでトンネル掘る
CloudflareのTunnelでKubernetes上のサービスを公開 #kubernetes - Qiita の真似をする
rpm -ivh https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm
cloudflared tunnel login
capslock.devをつないでみた
code:result
You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/windymelt/.cloudflared/cert.pem
もろもろの変数を設定する。このへんはPulumiで自動化したいなぁ
code:setup.sh
% export CF_TUNNEL_NAME=k8s-testtunnel
% export CF_TUNNEL_DOMAIN=k8s-testtunnel.capslock.dev
% cloudflared tunnel create $CF_TUNNEL_NAME
Tunnel credentials written to /home/windymelt/.cloudflared/c6c77936-fa45-4f0f-a0a3-c67bcab213df.json. cloudflared chose this file based on where your origin certificate was found. Keep this file secret. To revoke these credentials, delete the tunnel.
Created tunnel k8s-testtunnel with id c6c77936-fa45-4f0f-a0a3-c67bcab213df
↑ここのIDを覚えておく
% cloudflared tunnel route dns $CF_TUNNEL_NAME $CF_TUNNEL_DOMAIN
% kubectl -n pulumi-test create secret generic ${CF_TUNNEL_NAME}-credentials \
--from-file=credentials.json=$HOME/.cloudflared/c6c77936-fa45-4f0f-a0a3-c67bcab213df.json
↑ここでID必要になる。namespaceはお好みで
元記事ではDeploymentを使って2つトンネル用の仕組みを動かしているが、今回は簡単のために1つにしとく
https://github.com/windymelt/pulumi-k8s-cf-tunnel-exercise/blob/main/Main.scala
これってCloudflareがIngressになるわけではないのか
CloudflareのArgoTunnelをKubernetesのIngressに使ってみる によれば、Ingressとして設定もできそう?
見たところ関係なかった
今回は勝手にTLSまわりをやってもらったけど、自前で用意することもできるはず
→Besomで作る
dd if=/dev/urandom bs=32 count=1 | base64
認証
Cloudflareでトンネル掘れるようになったけど、外部からは当然見える状態になっているので認証もしたい
Cloudflare Access -- Cloudflare標準で使える
「海の向こう」で認証してくれる
リバースプロキシにAutheriaやHankoをつけて認証する
こちらの岸で認証する
Cloudflare Access
https://scrapbox.io/files/6668806f2c9a66001cd4f981.png
OpenID ConnectでGitHubにつないでおく
https://scrapbox.io/files/66687ff2d27532001dd592a1.png
するとorgとかemail単位で認証できるようになる。あとは普通にCF Tunnelとかをつなげば終わり。
CD
ArgoCDが有名だけど、Rancherからすぐ使えるFleetというのがある。これもSUSE謹製。
ConfigMap
k8sにはConfigMapなる便利な機構がある
要するに設定ファイルから読み取るタイプのアプリケーションとコンテナの特性とをうまく擦り合わせるための機構
dataフィールドとbinaryDataフィールドを持つ
どちらを使ってもよい
格納されるものがバイナリかどうかしか違いはない
シークレットではない
格納する目線からすると、dataフィールドはKVSである
JAVA_OPTS: '-Xmx8Gi'みたいな感じのものを格納したり
code:file_example.yaml
settings.json: |
{
"foo": "bar"
}
のようなファイルっぽいものも格納できる
要するにデータであればなんでもいい
使う目線からすると、ConfigMapは以下の方法で利用できる
コマンドと引数として
典型例: -in foo.txt
環境変数として
典型例: JAVA_OPTS
ボリューム上のファイルマウントとして
典型例: config.json
API経由で
ファイルとしてConfigMapを利用するのがけっこう便利で、ちょっとしたファイルを外部から注入できる
Cloudflare Tunnelの設定
MySQLの初期化ファイル
アプリケーションをk8s化する
自宅K8Sクラスタを作る/jarで走るアプリケーションをk8s化する
table:infobox
やったことを簡潔に