Kubernetes(K8s)と聞くと、多くの開発者は大がかりなシステムを思い浮かべるでしょう。数十GBものRAMを消費し、専任の運用チームが必要になることも珍しくありません。しかし、手元にあるのがUbuntu Serverを搭載した2〜3台の安価なVPS(1〜2GB RAM程度)だけの場合はどうでしょうか?K3sこそが最適な選択肢です。軽量かつ高速で、ハードウェアリソースを圧迫することなく、自己修復機能や負荷分散機能を十分に提供してくれます。
1. クイックスタート:5分でマルチノードK3sクラスタを構築する
最小限のラボ構成として、内部ネットワークで相互通信が可能なUbuntu Server(22.04または24.04 LTS)のVPSまたは仮想マシンが2台必要です:
- Masterノード(Server): IP
192.168.1.10(最小 1 vCPU、1.5GB RAM) - Workerノード(Agent): IP
192.168.1.11(最小 1 vCPU、1GB RAM)
ステップ1:MasterノードにK3sをインストールする
MasterマシンにSSH接続し、以下のコマンドを1行実行します:
curl -sfL https://get.k3s.io | sh -
K3sがバイナリを自動ダウンロードし、systemdサービスを初期化して、kubectlを事前設定します。このプロセスは通常30秒もかかりません。
続いて、Workerノードがクラスタに参加するためのシークレットトークンを取得します:
sudo cat /var/lib/rancher/k3s/server/node-token
(このトークン文字列をコピーします。例:K10abcd1234...::server:5678efgh)
ステップ2:Workerノードをクラスタに参加させる
Workerマシンのターミナルを開き、以下のコマンドを実行します(MasterのIPとトークンをご自身の環境に合わせて置き換えてください):
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.10:6443 K3S_TOKEN="取得したトークン文字列" sh -
ステップ3:クラスタの状態を確認する
Masterノードに戻り、クラスタ内のノード一覧を確認します:
sudo k3s kubectl get nodes
両方のマシンが Ready 状態になっていれば、K8sクラスタの準備は完了です:
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 3m v1.30.2+k3s1
worker01 Ready <none> 45s v1.30.2+k3s1
2. K3sの仕組みと軽量である理由
標準のKubernetesはいわば18輪の大型トレーラーのようなものです。非常にパワフルですが、巨大で燃料消費も激しくなります。拠点間で数個の小さな荷物を運ぶだけなら、大型トレーラーを走らせるのは過剰で無駄が多くなります。
Rancher Labsは、K3sを機動力の高いピックアップトラックのように設計しました。開発チームは不要なクラウドドライバを削減し、etcdデータベースをSQLite/kineに置き換え、すべてを100MB未満の単一バイナリファイルにパッケージ化しました。
このアーキテクチャのおかげで、Masterノードはバックグラウンド動作時で約450MB〜512MBのRAMしか消費しません。HetznerやLinode、国内クラウドなどの月額5〜10ドル程度の低価格VPSプランでも安心して運用できます。
クラスタ内の役割分担モデル
- Serverノード(Control Plane): ユーザーからのデプロイコマンドを受け付け、Podのヘルスチェックを行い、コンテナを適切なノードにスケジューリング・配置します。
- Agentノード(Worker): コンテナイメージのプルを担当し、組み込みの
containerdランタイムを通じてPodを実行します。 - Traefik Ingress Controller: デフォルトのトラフィック受信用ゲートウェイ(リバースプロキシ&ロードバランサー)。ポート80/443への外部リクエストはすべてTraefikを経由してから各コンテナへ振り分けられます。
3. 実践:Ingressの設定と負荷分散(ロードバランシング)
ノード間に分散された3つのレプリカ(replicas)で構成されるWebアプリケーションをデプロイし、実際の負荷分散の挙動を確認します。
Deploymentと負荷分散Serviceの作成
Masterノード上で app-demo.yaml ファイルを作成します:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
labels:
app: web-demo
spec:
replicas: 3
selector:
matchLabels:
app: web-demo
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-demo-service
spec:
type: ClusterIP
selector:
app: web-demo
ports:
- port: 80
targetPort: 80
クラスタに設定を適用します:
sudo k3s kubectl apply -f app-demo.yaml
ドメインルーティング用Ingressの設定
続いて ingress-demo.yaml ファイルを作成し、ドメイン demo.itfromzero.local を先ほど作成したServiceに向けます:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-demo-ingress
spec:
ingressClassName: traefik
rules:
- host: demo.itfromzero.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-demo-service
port:
number: 80
Ingressを適用します:
sudo k3s kubectl apply -f ingress-demo.yaml
実際の負荷分散をテストする
cURLを使用してMasterノードにテストリクエストを送信します:
curl -H "Host: demo.itfromzero.local" http://192.168.1.10
コマンドを実行するたびに、レスポンス内の Hostname フィールドのPod名が切り替わります(例:web-demo-6d4c5-abc1 から web-demo-6d4c5-xyz2 へ)。Traefik Ingressがラウンドロビンアルゴリズムに従い、MasterおよびWorker上の各Podへトラフィックを自動的かつ均等に分散していることが確認できます。
4. VPSでK3sを運用する際の実践ノウ豪
以下は、メモリ不足やセキュリティリスクを回避し、K3sクラスタを長期にわたって安定稼働させるための4つの実践的チューニングポイントです:
- ローカルPCからのクラスタ管理: クラスタ設定ファイルは
/etc/rancher/k3s/k3s.yamlに配置されています。このファイルを開発マシンの~/.kube/configにダウンロードし、127.0.0.1をMasterノードのパブリックIPに変更します。これにより、SSH接続しなくてもk9sやLens、VS Codeから直接クラスタを管理できます。 - 不要なコンポーネントの無効化: ホスト側にすでにNginxがある場合や、さらに150MB程度のRAMを節約したい場合は、インストール時にデフォルトのTraefikとLocal Storageを無効化できます:
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik --disable local-storage" sh - - ファイアウォール(UFW)の厳格な設定: Masterノードのポート
6443はWorkerの内部IPからのみアクセスを許可します。外部アクセスを受け付けるポート80, 443のみ一般公開します。Kubernetes API Serverへの自動スキャン攻撃を防ぐため、ポート6443をインターネット全体に開放することは避けてください。 - Control Planeデータの定期バックアップ: K3sの内部データベースは
/var/lib/rancher/k3s/server/db/に保存されています。毎晩このディレクトリを圧縮してS3やCloud Storageに同期するcronジョブを作成しておきましょう。ハードウェア障害が発生した場合でも、数分でクラスタを復旧できます。
