自宅k3sクラスタにGCEのワーカーノードを追加してみる
ゴール(はじめに):k3sクラスタにGCEのワーカーノードを追加する方法をまとめる
自宅に構築しているk3sクラスタにワーカーノードを追加したくなったのでその方法をまとめました。
クラウドのインスタンスを使えば必要な時に必要な分だけリソースを追加できて便利ということで、今回はGoogle Compute Engine(GCE)をワーカーノードとして追加してみようと思います。
また、この構成だと各ノードは共通のプライベートネットワーク内にあるわけではないので、通信時のセキュリティ面も考慮した方法にします。
やったこと
tailscaleをk3sに統合することができるので、この機能を使って簡単にノードを追加することが可能になります。
やり方は公式ドキュメントに記載されているやり方で(まだ実験的機能のようですが)、この通りやれば動きました。
tailscaleを使うことでクラウドのインスタンスとプライベートなネットワークを構築できるので通信のためのポートの穴あけなどセキュリティリスクになるような手順が不要になります。
それでは順番に手順を説明していきます。
事前準備
- k3sクラスタ構築
k3sでKubernetesのクラスタを構築する前提とします。
k3sの基本的なインストール方法や仕様については言及しませんので、適宜公式ページを参照してください。
https://docs.k3s.io/quick-start
私の環境では既に自宅のマシンをマスターノードとして起動していたので、それを利用した手順となってます。 - tailscaleのインストール
今回はtailscaleというサービスを利用します。tailscaleというのは無料で利用できてかつ簡単に構築できるVPNサービスです。詳しくは以下ページから確認してください。
最初にアカウント登録が必要です。
https://tailscale.com/kb/1151/what-is-tailscale
GCEインスタンスの作成
まずはワーカーノードとして利用するGCEインスタンスを作成します。
スペックは適当な値で大丈夫です。ちなみにk3sの最小ではCPU:1 core, RAM: 512MBあれば動くようです。(GCEの無料枠でも動きます)
また作成したインスタンスはネットワークに接続できる必要があります。
今回はtest-agent-1
という名前で作成してます。
tailscaleの設定
以下を参考に必要な初期設定を行なっていきます。
-
tailscaleにログイン
https://login.tailscale.com/admin/machines -
Settings > Keys
のGenerate Auth Key
でkeyを作成します。k3sのインストール時に利用するので控えておいてください。 -
Access Control
のjsonに以下を追加します。
cidrはclusterの設定に合わせて修正してください。デフォルトだと以下で大丈夫です。
"autoApprovers": {
"routes": {
"10.42.0.0/16": ["your_account@xyz.com"],
"2001:cafe:42::/56": ["your_account@xyz.com"],
},
},
既存ノードにtailscaleを導入
既に存在するノードにもtailscaleの設定を追加する必要があります。
この作業は各マシンで行います。
tailscaleがインストールされてない場合はまずインストールします。
curl -fsSL https://tailscale.com/install.sh | sh
tailscaleをk3sに統合するにはk3sのインストールコマンドに--vpn-auth="name=tailscale,joinKey=$AUTH-KEY"
のオプションをつけることで可能です。$AUTH-KEY
は上で作成したtailscaleのauth keyを設定してください。
k3sに設定を適用します。すでにk3sのインストールがされている場合も以下のコマンドをそのまま実行すればtailscaleの設定が追加されるはずです。
--vpn-auth
以外の設定はそれぞれの設定に合わせてください。
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644 --disable=traefik --vpn-auth="name=tailscale,joinKey=$AUTH-KEY"
GCEをワーカーノードとして追加
いよいよGCEをk3sクラスタに追加します。
まずはGCEにssh接続し他マシンと同じようにtailscaleをインストールします。
curl -fsSL https://tailscale.com/install.sh | sh
次にワーカーノードとしてk3sを起動します。
ここでK3S_URL
はtailscaleのmachine一覧で表示されているserverノードのアドレス、$SEVER-TOKEN
はサーバーノードの/var/lib/rancher/k3s/server/node-token
に格納されているagentを追加するためのトークンを設定します。
ここでもこれまでと同じように$AUTH-KEY
が必要です。
curl -sfL https://get.k3s.io | K3S_URL=https://100.XX.XX.XX:6443 sh -s - agent --token $SEVER-TOKEN --vpn-auth="name=tailscale,joinKey=$AUTH-KEY"
これでGCEインスタンスがワーカーノードとして追加されていることが確認できると思います。
test-agent-1
がReadyになっていれば大丈夫です。
❯ kubectl get node
NAME STATUS ROLES AGE VERSION
pollux Ready control-plane,master 34d v1.29.6+k3s2
test-agent-1 Ready <none> 38m v1.29.6+k3s2
動作確認
ちゃんと動くか動作確認してみます。
まず今回追加したノードに適当なpodを起動します。
cat << EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: example-container
image: nginx
ports:
- containerPort: 80
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- test-agent-1
EOF
ちゃんとtest-agent-1
ノードに起動できています。
❯ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
example-pod 1/1 Running 0 4d23h 10.42.6.4 test-agent-1 <none> <none>
port-forwardしてレスポンスが返ってくるかも試します。
kubectl port-forward example-pod 8080:80
ちゃんと結果が返ってくれば大丈夫です。
❯ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
追加で他のノードからpod同士疎通できるかも試します。
マスターノードに新しく疎通用のpodを起動します。
❯ cat << EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: example-pod-2
spec:
containers:
- name: example-container
image: nginx
ports:
- containerPort: 80
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- pollux
EOF
❯ k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
example-pod 1/1 Running 0 4d23h 10.42.6.4 test-agent-1 <none> <none>
example-pod-2 1/1 Running 5 (50s ago) 4d23h 10.42.0.193 pollux <none> <none>
example-pod-2
に入ってexample-pod
に対してcurlを投げてみると結果がちゃんと返却されました。
10.42.6.4
はget podして得られるIPアドレスです。
❯ k iexec example-pod-2
# curl http://10.42.6.4:80 -vvv
* Trying 10.42.6.4:80...
* Connected to 10.42.6.4 (10.42.6.4) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.42.6.4
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.27.1
< Date: Fri, 30 Aug 2024 07:25:18 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Mon, 12 Aug 2024 14:21:01 GMT
< Connection: keep-alive
< ETag: "66ba1a4d-267"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 10.42.6.4 left intact
おわりに
tailscaleを利用して簡単にGCEインスタンスをk3sクラスタに追加することができました。
今までtailscale自体は知っていたのですが、k3s側に統合する機能があることを初めて知り、それを使うことで簡単に実現できました。
実現にあたっては各種公式ドキュメントがまとまっていて、結果としてそれに従ってやってみたらちゃんと動いた、というだけの記事になってます。
セキュリティに関しては素人ですが、tailscaleでプライベートネットワークを構成しているので、ノード間の通信をpublicで行うために穴あけとかをする必要がないので比較的安全なんじゃないかと思っています。
普段自宅でk3sを利用していてコンピュートリソースを追加したいけど、物理マシンを買ってセットアップするのはめんどくさいとかあくまで一時的な追加でいいというユースケースで参考になれば嬉しいです。
Discussion