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番にし、ノード間のポートはノード同士に限る
関連記事: