2026年8月3日

2026年8月3日

k3sでVPSにKubernetesクラスターを構築する方法|インストールから公開まで

k3sは、Kubernetesを1つのバイナリにまとめた軽量なディストリビューションです。インストールスクリプトを1行実行するだけでKubernetesのコントロールプレーンが起動し、kubectl、Ingressコントローラー(Traefik)、LoadBalancer 型のServiceを処理するServiceLBも最初から入っています。メモリの少ないVPS1台でも、Kubernetesの検証環境や小さな本番環境を作れます。

この記事では、Ubuntuなどの一般的なLinuxを入れたVPSにk3sを入れ、Webアプリを公開するまでを説明します。内容は2026年10月時点のk3s公式ドキュメント(docs.k3s.io)に合わせています。

必要なスペックと事前の準備

公式ドキュメントが示す最低限のスペックは次のとおりです。アプリを動かす分は、これに上乗せして見積もります。

役割 CPU メモリ
サーバー(コントロールプレーン) 2コア 2GB
エージェント(ワーカー) 1コア 512MB

あわせて次を確認します。

  • 複数台でクラスターを作る場合、ノードごとにホスト名が異なること(同じ場合はインストール時に環境変数 K3S_NODE_NAME で別の名前を付ける)
  • root権限(sudo)で作業できること
  • VPS会社の管理画面のファイアウォール(パケットフィルター)と、OSのファイアウォールの両方で、必要なポートを開けられること

開けるポート

k3sのノードが受け付ける主なポートです。インターネット全体に開けるのは、外部から kubectl で操作する場合の6443番と、Webアプリを公開する80番・443番だけにし、ノード間の通信用ポートはノード同士にだけ許可します。

プロトコル ポート 送信元 用途
TCP 6443 エージェント、kubectl を使う端末 k3sのsupervisorとKubernetes APIサーバー
UDP 8472 全ノード Flannel VXLAN(ノード間のPod通信)
TCP 10250 全ノード kubeletのメトリクスとAPI
TCP 2379-2380 サーバー 組み込みetcd(サーバーを複数台にする構成だけ)

公式ドキュメントは、ufwやfirewalldを無効にすることを推奨しています。有効のまま使う場合は、APIサーバーのポートと、PodとServiceのネットワーク(既定は 10.42.0.0/16 と 10.43.0.0/16)からの通信を許可します。

# ufw の場合
sudo ufw allow 6443/tcp
sudo ufw allow from 10.42.0.0/16 to any
sudo ufw allow from 10.43.0.0/16 to any

# Web アプリを公開する場合
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

k3sをインストールする

設定ファイルを用意する(任意)

外部のパソコンから kubectl で操作する予定があるなら、APIサーバーの証明書にVPSのIPアドレスかホスト名を入れておきます。k3sは /etc/rancher/k3s/config.yaml があれば、インストール方法にかかわらず読み込みます。203.0.113.10 と k3s.example.com は例なので、自分のVPSのものに置き換えてください。

sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/config.yaml > /dev/null << 'EOF'
tls-san:
  - "203.0.113.10"
  - "k3s.example.com"
EOF

インストールスクリプトを実行する

curl -sfL https://get.k3s.io | sh -

このスクリプトは、k3sをsystemdのサービス(k3s)として登録して起動します。サービスは再起動後や異常終了時に自動で立ち上がります。あわせて kubectl、crictl、ctr、k3s-killall.sh、k3s-uninstall.sh が入ります。

起動したかを確認します。

sudo systemctl status k3s
sudo kubectl get nodes

STATUS が Ready になれば、1台構成のクラスターができています。

kubeconfigを使えるようにする

k3sは管理者用のkubeconfigを /etc/rancher/k3s/k3s.yaml に書き出し、k3sに同梱の kubectl はこのファイルを自動で読み込みます。このファイルはrootしか読めないので、そのままでは sudo が必要です。一般ユーザーで使う場合は、自分用にコピーします。

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown "$(id -u):$(id -g)" ~/.kube/config
chmod 600 ~/.kube/config
export KUBECONFIG=~/.kube/config
kubectl get nodes

export の行は、~/.bashrc に追記しておくと次回のログインでも有効になります。Helmなど、k3s同梱ではないツールも環境変数 KUBECONFIG を見ます。

このkubeconfigは管理者の権限を持つので、ほかの人に渡さないでください。k3sは起動時に管理者用kubeconfigの証明書を作り直すことがあるため、コピーしたファイルで接続できなくなったら、もう一度コピーします。

自分のパソコンから操作する場合

/etc/rancher/k3s/k3s.yaml を自分のパソコンの ~/.kube/config にコピーし、server: の行(https://127.0.0.1:6443)をVPSのIPアドレスかホスト名に書き換えます。証明書にそのアドレスが入っていないとTLSのエラーになるので、上の tls-san を設定してからインストールしてください。

    server: https://203.0.113.10:6443

6443番は、VPSのファイアウォールで自分のIPアドレスからだけ許可するのが安全です。

ワーカーノードを追加する

1台で足りない場合は、別のVPSをエージェント(ワーカー)として追加できます。サーバーでトークンを確認します。

sudo cat /var/lib/rancher/k3s/server/node-token

追加するVPSで、サーバーのアドレスとトークンを環境変数で渡してインストールします。K3S_TOKEN の値は、上で表示したトークンに置き換えます。

curl -sfL https://get.k3s.io | K3S_URL=https://203.0.113.10:6443 K3S_TOKEN=サーバーで確認したトークン sh -

エージェントは k3s-agent という名前のサービスで動きます。サーバーで kubectl get nodes を実行し、ノードが増えたことを確認します。ノード間は、8472番(UDP)と10250番(TCP)が通る必要があります。プライベートネットワークがあるVPSなら、ノード間の通信はそちらを使うようにすると、インターネット側に開けるポートを減らせます。

アプリを公開する

例として、nginxを2つ動かし、Ingressで80番に公開します。k3sにはTraefikが入っていて、ServiceLBによってノードの80番と443番で待ち受けています。

マニフェストを web.yaml として保存します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:stable
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
spec:
  ingressClassName: traefik
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80

適用して、状態を確認します。

kubectl apply -f web.yaml
kubectl get deployments,pods,svc,ingress
curl -I http://203.0.113.10/

curl で HTTP/1.1 200 OK が返れば公開できています。ドメインで公開する場合は、Ingressの rules に host: を加え、DNSのAレコードをVPSのIPアドレスに向けます。

状態の確認とトラブルシューティング

確認したいこと コマンド
k3sのサービスが動いているか sudo systemctl status k3s(エージェントは k3s-agent)
k3s自体のログ sudo journalctl -u k3s -f
すべてのPodの状態 kubectl get pods -A
Podが起動しない理由 kubectl describe pod Pod名(末尾の Events を見る)
コンテナのログ kubectl logs Pod名
ノードのCPU・メモリ使用量 kubectl top nodes(k3s同梱のmetrics-serverを使う)

よくある原因は次のとおりです。

  • Podが Pending のまま: ノードのメモリやCPUが足りず、requests を満たせない。kubectl describe pod の Events に理由が出る
  • ImagePullBackOff: イメージ名やタグの誤り、または外部へのHTTPS通信がファイアウォールで止まっている
  • エージェントが NotReady のまま: サーバーの6443番に届かない、トークンが違う、ノード間の8472番(UDP)が通らない
  • 80番に接続できない: VPS会社のファイアウォールで80番が閉じている。kubectl get pods -n kube-system でTraefikのPodが動いているかも確認する

k3sを削除する

検証が終わったら、インストール時に入ったスクリプトで削除できます。クラスターのデータもすべて削除されます。

# サーバー
/usr/local/bin/k3s-uninstall.sh

# エージェント
/usr/local/bin/k3s-agent-uninstall.sh

まとめ

  • k3sは curl -sfL https://get.k3s.io | sh - で入り、kubectl、Traefik、ServiceLBが同梱されている
  • kubeconfigは /etc/rancher/k3s/k3s.yaml。一般ユーザーで使うときはコピーし、外部から使うときは tls-san を設定してから server: を書き換える
  • ワーカーは K3S_URL と K3S_TOKEN(/var/lib/rancher/k3s/server/node-token)を渡して追加する
  • 外部に開けるのは6443番(自分のIPだけ)と80番・443番にし、ノード間のポートはノード同士に限る

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲