K3sを使ったUbuntu Server上でのマルチノードKubernetesクラスタ構築ガイド:インストール、Traefik Ingress、ロードバランシング

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

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ジョブを作成しておきましょう。ハードウェア障害が発生した場合でも、数分でクラスタを復旧できます。
Share: