K3s(ケー・スリー・エス)は、Kubernetesを100MB未満の単一バイナリにまとめた軽量ディストリビューションです。CNCFの適合性認定を受けたKubernetesなので、kubectlやHelmはそのまま使えます。上流と違うのは、データストアの既定がetcdではなくSQLiteであること、Ingressやロードバランサーまで同梱していること、Linuxなら curl -sfL https://get.k3s.io | sh - の1行でクラスタが立ち上がることの3点です。既存のマニフェストやHelmチャートを移すときは、IngressコントローラーやStorageClassの違いに合わせた確認が要ります。
以下、版やコマンドは2026年10月24日時点の公式ドキュメントとstableリリース(v1.36.5+k3s1)に基づきます。メモリ使用量などの数値は、同じ版を手元で起動して測ったものです。
まとめ:K3sの要点
- 正体:Rancher(現SUSE)が開発したKubernetesディストリビューション。フォークではなく、上流Kubernetesに1,000行未満のパッチを当てて同梱物を足したもの。2020年8月からCNCFのSandboxプロジェクト。
- 読み方:公式の読み方も正式名称も無い。k8sの半分(10文字の半分=5文字)という意味でK3s。
- k8sとの違い:単一バイナリ、既定データストアがSQLite、containerd・Flannel・CoreDNS・Traefik・ServiceLB・local-path-provisionerを同梱。
- 最小要件:サーバーが2コア・2GB、エージェントが1コア・512MB。Linux(x86_64・armhf・arm64)専用で、Windowsはネイティブ非対応。実測では、ワークロードなしの標準構成で約672MiBを使った(docker statsの表示値)。
- インストール:
curl -sfL https://get.k3s.io | sh -。入るのはstableチャネルの版(v1.36.5+k3s1)で、最新版(v1.37.1+k3s1)ではない。 - HA:組み込みetcdで3台以上の奇数サーバー、または外部のMySQL・PostgreSQL等。SQLiteのままではサーバーを増やせない。
- 選び分け:エッジ・ARM・小規模本番・CIはK3s、手元のDockerで試すならk3dやkind、コントロールプレーンを分離してSSHで一括構築したいならk0s+k0sctl、政府調達・FIPS要件ならRKE2。
K3sの名前の由来と読み方
公式README(k3s-io/k3s)では、名前の由来を次のように説明しています。Kubernetesは10文字なので「k8s」と略される。メモリ使用量が半分のKubernetesなら5文字、だから「K3s」。さらに「3」は「8」を縦半分に切った形でもある、という二重の洒落です。同じ箇所に「K3sには正式な長い名称も、公式の読み方もない」と明記されています。
そのため特定の読み方だけが正しいわけではありません。アルファベットをそのまま「ケー・スリー・エス」と読めば、誤解なく伝わります。
位置づけも押さえておくと誤解が減ります。READMEは「これはフォークではなくディストリビューション」と述べ、上流から乖離させる意図はなく、保守しているパッチは1,000行を大きく下回るとしています。CNCFには2020年8月19日にSandbox成熟度で受け入れられ、2026年10月時点でもSandboxのままです(Incubating・Graduatedではありません)。Kubernetesそのものの仕組みはKubernetes(クバネティス)とは?メリット・デメリットと仕組み、Dockerとの違いを解説で扱っています。
K3sとk8s(Kubernetes)の違い
K3sは上流Kubernetesの機能を削った「簡易版」ではありません。CNCFの適合性テストに通っているので、Deployment・Service・Ingress・CRDといったAPIは同じように使えます。違いは配布の仕方と、最初から入っている部品にあります。
| 項目 | K3s | kubeadmで組む上流k8s |
|---|---|---|
| 配布形態 | 単一バイナリ(100MB未満) | コンポーネントごとに別 |
| 既定のデータストア | SQLite(kine経由) | etcd |
| コンテナランタイム | containerd同梱 | 別途導入 |
| CNI | Flannel同梱 | 別途導入 |
| Ingress | Traefik同梱 | 別途導入 |
| LoadBalancer | ServiceLB同梱 | クラウド連携か別途導入(無ければpendingのまま) |
| ストレージ | local-path-provisioner同梱 | 別途導入 |
| サーバー最小要件 | 2コア・2GB | 2コア・2GB(kubeadm) |
最小要件の数字は並べると同じです。軽さの差は、コントロールプレーンの各コンポーネントを1プロセスにまとめたことと、etcdの代わりにSQLiteを使えることから生まれます。
単一バイナリと同梱コンポーネント
v1.36.5+k3s1(2026年9月30日公開)のリリースノートに載っている同梱物の版は、containerd v2.3.4、Flannel v0.28.4、CoreDNS v1.14.7、Traefik v3.7.13、metrics-server v0.9.0、local-path-provisioner v0.0.37です。このほか、ネットワークポリシーを処理するkube-routerのコントローラーと、HelmChartカスタムリソースを処理するhelm-controllerも入っています。GitHubのリリースに置かれたamd64用バイナリ k3s は79,077,538バイト(約75MiB)、arm64用は71,434,402バイトでした。
もう1つの違いが通信の向きです。上流ではコントロールプレーンが各ノードのkubelet(10250番)へ接続しますが、K3sではエージェントがサーバーの6443番へ外向きに接続し、APIサーバーからkubeletへの通信はそのトンネルを通ります。ただし、トンネルが運ぶのは制御用の通信だけです。Pod間通信には別途ノード同士の到達性が要り、既定のFlannel VXLANならノード間の8472/UDPを許可します。metrics-serverを使うなら、10250番もノード間で開けておく必要があります。
データストアの選択肢:SQLite・組み込みetcd・外部DB
他の設定が無く、ディスク上にetcdのファイルも無ければ、K3sは組み込みSQLiteを使います。シングルサーバーには十分ですが、SQLiteのままサーバーを2台以上にすることはできません。HAにするときは次の2つから選びます。
- 組み込みetcd:1台目を
--cluster-initで起動し、3台以上の奇数台でクォーラムを組む。etcdを別に運用する必要はない。 - 外部データストア:
--datastore-endpointで接続文字列を渡す。認定されている版はetcd 3.5.21、MySQL 8.0/8.4、MariaDB 10.11/11.4、PostgreSQL 15.12/16.7/17.3。
外部DBには制約が2つあります。kineはリビジョンが1ずつ増える前提なので、auto_increment_increment を1より大きくするGaleraのようなマルチマスター構成は使えません。プリペアドステートメントも必須なので、トランザクションプーリングのPgBouncerを挟むなら追加設定が要ります。
実測:K3s v1.36.5を起動して見えた構成とメモリ
公式イメージ rancher/k3s:v1.36.5-k3s1 を、Mac上のcolima(x86_64のLinux VM・4コア・約6GB)のDockerで --privileged 付きのサーバーとして起動し、中身を確かめました。コンテナで動かしているため、ホストに直接入れた場合と数値は多少ずれます。
docker run -d --name k3s-test --privileged --tmpfs /run --tmpfs /var/run \
rancher/k3s:v1.36.5-k3s1 server
docker exec k3s-test kubectl get nodes -o wide
# VERSION v1.36.5+k3s1 / CONTAINER-RUNTIME containerd://2.3.4-k3s1.36
イメージの取得を含めて25秒でノードがReadyになりました。数分後には次のPodが揃います。
| Pod(kube-system) | 状態 | 役割 |
|---|---|---|
| coredns | Running | クラスタDNS |
| local-path-provisioner | Running | 既定のStorageClass |
| metrics-server | Running | kubectl top の元データ |
| traefik | Running | Ingressコントローラー |
| svclb-traefik | Running | ServiceLBがTraefikの80・443番をノードで受けるPod |
| helm-install-traefik/helm-install-traefik-crd | Completed | helm-controllerがTraefikのチャートを入れたジョブ |
上流のkubeadm構成と違い、kube-apiserverやkube-schedulerのPodはありません。それらは k3s server という1プロセスの中で動いています。TraefikのServiceは LoadBalancer 型で、クラウドが無くてもServiceLBのおかげでノードのIP(172.17.0.2)がEXTERNAL-IPに入りました。データストアは /var/lib/rancher/k3s/server/db/state.db というSQLiteファイル1つで、起動直後は約11.9MB(WAL約6.3MB)でした。
メモリは、ワークロードを置かない状態で docker stats --no-stream の表示がコンテナ全体で約672MiBでした。別の時点にプロセスごとのRSSを読むと、k3s server が約631MiB、containerdが約177MiBです。Dockerの表示値はキャッシュ分を差し引いた値なので、これらのRSSは672MiBの内訳ではありません。同じ版を --disable=traefik --disable=servicelb --disable=metrics-server 付きで起動すると、Podはcorednsとlocal-path-provisionerの2つだけになり、約444MiBまで下がりました。公式の最小要件である2GBはK3s本体と同梱コンポーネントのための基礎要件で、アプリのワークロードが必要とするメモリは別途確保します。
K3sの動作要件とポート
公式の最小要件は、ワークロード分を含まない基礎値です。
| ノード | CPU | メモリ |
|---|---|---|
| サーバー | 2コア | 2GB |
| エージェント | 1コア | 512MB |
対応アーキテクチャはx86_64、armhf(32ビットARM)、arm64です。OSは「現代的なLinuxのほとんど」で、Windowsはネイティブに対応していません。macOSでも直接は動かないので、手元のMacで試すならDocker上で動かすk3d(後述)か、Linux VMを使います。
サーバー1台で抱えられるエージェント数の目安は、2コア・4GBで350台まで、4コア・8GBで900台まで、8コア・16GBで1,800台までです。公式のサイジング目安では、3台のHA構成でエージェント数を約50%増やせるとしています。ただしワークロードによって変わり、255ノードを超える構成では既定のcluster-cidrの変更も必要です。
ディスクはSSDを推奨しています。etcdは書き込みが多く、Raspberry PiのSDカードやeMMCでは負荷に耐えられないので、組み込みetcdを使うなら外付けSSDにします。
開けるポートとファイアウォール
| ポート | 送信元→送信先 | 用途 |
|---|---|---|
| 6443/TCP | エージェント→サーバー | K3sスーパーバイザーとAPIサーバー |
| 8472/UDP | 全ノード間 | Flannel VXLAN(既定) |
| 10250/TCP | 全ノード間 | kubeletのメトリクスとAPI |
| 2379-2380/TCP | サーバー間 | 組み込みetcdでHAにする場合のみ |
| 51820/UDP | 全ノード間 | Flannel WireGuard(IPv4)を使う場合のみ |
8472番をインターネットに晒すと、誰でもクラスタ内ネットワークに入れてしまいます。VXLANのポートは必ずファイアウォールかセキュリティグループの内側に置いてください。公式はufwやfirewalldを止めることを推奨していますが、残すならPod用の10.42.0.0/16とService用の10.43.0.0/16を許可する必要があります。
K3sのインストール手順(シングルノード)
サーバー1台で、データストア・コントロールプレーン・kubelet・コンテナランタイムまで揃った完全なクラスタになります。
# サーバーをインストール(systemd または OpenRC のサービスとして登録される)
curl -sfL https://get.k3s.io | sh -
# 動作確認
sudo k3s kubectl get nodes
sudo k3s kubectl get pods -A
インストールスクリプトは、k3sバイナリに加えて kubectl・crictl・ctr のシンボリックリンク、k3s-killall.sh、k3s-uninstall.sh を /usr/local/bin に置きます。kubeconfigは /etc/rancher/k3s/k3s.yaml に書かれ、同梱のkubectlは自動でこれを読みます。
入る版はstableチャネル:版を固定する方法
見落としやすい点です。インストールスクリプトの INSTALL_K3S_CHANNEL の既定値は stable で、2026年10月24日時点のstableはv1.36.5+k3s1です。同じ9月30日に出たv1.37.1+k3s1はlatestチャネルの対象で、stableチャネルの対象ではありません。「最新のKubernetesを試したい」なら明示が要り、本番では逆に版を固定しておかないと、ノードを後から足したときに別の版が入ります。チャネルごとの現在の版は https://update.k3s.io/v1-release/channels がJSONで返します。
# 版を固定する(本番はこちら)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.36.5+k3s1 sh -
# latest チャネルから入れる
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=latest sh -
設定ファイルconfig.yamlとkubeconfigの扱い
起動オプションはコマンドライン引数でも渡せますが、/etc/rancher/k3s/config.yaml に書いておくと再インストールやアップグレードのときに漏れません。
# /etc/rancher/k3s/config.yaml
tls-san:
- k3s.example.internal
node-label:
- "env=dev"
k3s.yaml は system:masters グループの資格情報で、クラスタ内の全リソースを無制限に操作できます。手元のPCから操作したいときは、このファイルを ~/.kube/config としてコピーし、server の 127.0.0.1 をサーバーのIPかホスト名に書き換えます。権限を緩める write-kubeconfig-mode: "0644" は、共用マシンでは全ユーザーに管理者権限を渡すのと同じなので避けてください。RBACで権限を絞った利用者を作る手順は上流Kubernetesと同じです。サーバー外へコピーしたkubeconfig内の証明書は自動更新されないため、期限切れを防ぐにはコピー側も更新する必要があります。
アプリのデプロイとTraefik経由の公開確認
同梱のTraefikは既定のIngressClass(traefik (default))として登録されるので、ingressClassName を書かないIngressもTraefikが拾います。前章の実測環境で、次のマニフェストを適用しました。
# 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: web
image: nginx:1.29-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: web.localtest.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
docker exec -i k3s-test kubectl apply -f - < web.yaml
docker exec k3s-test kubectl rollout status deployment web --timeout=180s
docker exec k3s-test kubectl get ingress web
# NAME CLASS HOSTS ADDRESS PORTS
# web traefik web.localtest.me 172.17.0.2 80
docker run --rm --network container:k3s-test curlimages/curl:8.17.0 -s -o /dev/null -w "%{http_code}\n" -H "Host: web.localtest.me" http://172.17.0.2/
# 200
colimaのDockerを既定のコンテキストにしていない場合は、各 docker コマンドに --context colima を付けます。172.17.0.2は検証時のノードIPなので、kubectl get ingress のADDRESSに出た値に置き換えてください。curlは検証コンテナとネットワークを共有するコンテナから送っています。ノードのIPの80番にHostヘッダ付きで送ると、Traefikを通ってnginxが200を返しました。追加のIngressコントローラーやロードバランサーを入れずにここまで届くのが、上流k8sとの体感上の一番の違いです。
エージェントの追加と高可用性(HA)構成
エージェントノードの参加手順と認証トークン
参加用トークンはサーバーの /var/lib/rancher/k3s/server/node-token にあります。エージェント側で K3S_URL と K3S_TOKEN を付けてスクリプトを流すと、サーバーではなくエージェントとして登録されます。
# サーバーでトークンを確認
sudo cat /var/lib/rancher/k3s/server/node-token
# エージェントで実行(SERVER_IP と TOKEN を置き換える)
# サーバーの版を固定した場合は、同じINSTALL_K3S_VERSIONも指定する
curl -sfL https://get.k3s.io | K3S_URL=https://SERVER_IP:6443 K3S_TOKEN=TOKEN sh -
ホスト名が重複するノードは参加できません。クローンしたVMやRaspberry Piを並べるときは、--with-node-id でランダムな接尾辞を付けるか、K3S_NODE_NAME で一意の名前を渡します。
組み込みetcdによる3台HA構成の作成手順
# 1台目:クラスタを初期化
curl -sfL https://get.k3s.io | K3S_TOKEN=SHARED_SECRET sh -s - server --cluster-init
# 2台目・3台目:1台目に参加
curl -sfL https://get.k3s.io | K3S_TOKEN=SHARED_SECRET sh -s - server --server https://SERVER1_IP:6443
サーバーを奇数台にするのはetcdのクォーラムのためです。n台ならクォーラムは過半数、つまりn÷2の小数部分を切り捨てて1を足した台数で、3台なら1台、5台なら2台の故障まで耐えます。4台にしても耐えられる故障は3台と同じ1台で、故障しうる台数が増えるだけです。エージェントや外部のkubectlが接続する先を固定したいときは、ロードバランサーやDNSの固定アドレスを用意し、その名前を --tls-san で証明書に入れておきます。
Traefik・ServiceLBなど同梱機能の外し方と設定変更
同梱物は、サーバーの /var/lib/rancher/k3s/server/manifests に置かれたマニフェストから自動デプロイされるものがあります。実測環境では、このディレクトリに ccm.yaml・coredns.yaml・local-storage.yaml・metrics-server/・rolebindings.yaml・runtimes.yaml・traefik.yaml がありました。ServiceLBは組み込みコントローラーで、対応するマニフェストファイルはありません。保守が継続しているIngressコントローラーやMetalLBに置き換えるなら、--disable で外します。
# インストール時に Traefik と ServiceLB を外す
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik --disable=servicelb" sh -
# Flannel も外して別の CNI を入れる場合
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--flannel-backend=none --disable-network-policy" sh -
--disable は既存のクラスタに後から付けても効き、該当コンポーネントをクラスタから削除してマニフェストファイルも消します。実測でも、--disable=traefik --disable=servicelb --disable=metrics-server で起動したサーバーのmanifestsからは traefik.yaml と metrics-server/ が無くなっていました。HA構成では全サーバーに同じ指定を入れてください。Flannelの設定もサーバー間で同一である必要があり、別のCNIを入れる場合はCNI側のポリシーエンジンと衝突しないよう --disable-network-policy も付けるのが公式の推奨です。
もう1つの方法が、マニフェストと同じ名前の .skip ファイル(例:traefik.yaml.skip)です。初回起動前に置けばデプロイされませんが、既にデプロイ済みのものは消えず、以後のアップグレードでも更新されなくなります。既存クラスタで外すなら --disable を使ってください。
Traefikを残したまま設定を変えるときは、traefik.yaml を直接編集しても起動時に既定値で上書きされます。同じディレクトリに HelmChartConfig を置いて値を渡すのが公式の方法です。
# /var/lib/rancher/k3s/server/manifests/k3s-traefik-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
service:
spec:
type: ClusterIP
注意したいのはキーの位置です。2026年6月のリリース(v1.33.13+k3s1、v1.34.9+k3s1、v1.35.6+k3s1、v1.36.2+k3s1)からTraefikのチャートがv40になり、Serviceの型は service.type から service.spec.type へ移りました。古い service.type はエラーにならずに無視され、Serviceは LoadBalancer に戻ります。実測したv1.36.5のチャートも traefik-40.1.5+up40.1.0 でした。古い記事の例をそのまま写すと、設定したつもりの変更が効かない状態になります。
manifestsディレクトリには自作のマニフェストも置けます。拡張子を除いたファイル名が管理用のAddOnリソース名になるので、アンダースコアを含む名前(example_manifest.yaml など)は検証エラーになります。ベアメタルでLoadBalancerを本格的に使うならMetalLBとは?ベアメタルKubernetesでLoadBalancerを使う仕組みとL2・BGPの選び方も参考になります。
K3sのアップグレードとアンインストール
手動アップグレードは、初回と同じオプションでインストールスクリプトを再実行します。実行前に、データストアとサーバートークンをバックアップし、復元手順を確認してください。順序には決まりがあり、サーバーを1台ずつ先に上げ、エージェントは後にします。エージェントがサーバーより新しい状態はKubernetesのバージョンスキューポリシー上認められないためです。マイナー版を飛ばすのも不可で、1.35から1.37へ上げるなら1.36を経由します。
# サーバー用:初回の起動設定をすべてconfig.yamlに保存している場合の例
# 初回に引数・環境変数で渡した設定は再指定が必要
# エージェントでは参加先・トークンとagent起動指定も維持する
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.37.1+k3s1 sh -
台数が多いなら、Rancherのsystem-upgrade-controllerを入れて、Planカスタムリソースで宣言的に上げる方法があります。ただしこのコントローラー自体はマイナー版の飛び越しを防がないので、Planの版指定は自分で1段ずつ進めます。Kubernetes本体の版ごとのサポート期限はKubernetesの最新バージョンは1.37|確認方法・EOL一覧とアップグレード手順で確認できます。
アンインストールは、サーバーなら /usr/local/bin/k3s-uninstall.sh、エージェントなら /usr/local/bin/k3s-agent-uninstall.sh です。アンインストールはローカルのデータストアとlocal-path-provisionerの永続ボリュームのデータまで消します(外部DBの中身は消えません)。同じノードを再参加させる場合は、先にクラスタから kubectl delete node でノードを消しておかないと、ノードパスワードのSecretが残り、再登録が拒否される原因になります。
K3sのセキュリティ設定:Pod Security AdmissionとCIS準拠
旧来のPodSecurityPolicy(PSP)はKubernetes 1.25で削除されました。K3s v1.25以降は、Pod Security Admission(PSA)の設定ファイルをAPIサーバーに渡して制御します。以下は公式のCISハードニングガイドを基に、PSAの強制設定などを抜き出した例です。これだけでCIS準拠になるわけではなく、監査ログやNetworkPolicy、ホスト側の設定も必要です。
# /var/lib/rancher/k3s/server/psa.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: "restricted"
enforce-version: "latest"
exemptions:
namespaces: [kube-system]
# /etc/rancher/k3s/config.yaml に追記
kube-apiserver-arg:
- "admission-control-config-file=/var/lib/rancher/k3s/server/psa.yaml"
secrets-encryption: true
protect-kernel-defaults: true
secrets-encryption はサーバーの初回起動時に指定すると、保存時のSecret暗号化を有効にし、鍵と暗号化設定を自動生成します。protect-kernel-defaults はカーネルパラメータがkubeletの期待値と違うときに起動を止める設定で、先にsysctlを合わせておかないとサーバーが立ち上がりません。いきなり enforce: "restricted" にすると既存のPodが作れなくなることがあるので、まず warn と audit だけで違反を洗い出す順が安全です。既存のsystemd環境で設定を変更した場合は、必要なファイルとsysctl設定を整えた後に sudo systemctl restart k3s を実行し、起動ログとPodの状態を確認してください。
K3s・k0s・k3d・MicroK8s・minikube・kind・RKE2の使い分け
「軽量Kubernetes」と呼ばれるものは、実行場所と目的がそれぞれ違います。各プロジェクトの公式ドキュメントの説明を基に並べると次のとおりです。
| 名前 | 動く場所 | 主な用途 |
|---|---|---|
| K3s | Linuxホストに直接 | エッジ・IoT・ARM・小規模本番・CI |
| k0s | Linuxホストに直接(Docker内でも可) | エッジから大規模まで・SSHで一括構築(k0sctl) |
| k3d | Docker上(K3sをコンテナで起動) | 手元での複数ノード検証 |
| kind | Docker・Podman・nerdctl(ノード=コンテナ) | Kubernetes自体のテスト・CI |
| minikube | macOS・Linux・Windows | ローカルでのアプリ開発 |
| MicroK8s | snapで入るLinux | 開発機・エッジ(Canonical製) |
| RKE2 | Linuxホストに直接 | CIS準拠・FIPS 140-2が要る環境 |
K3sとk0sの違い
k0sもKubernetesを単一バイナリにまとめたCNCF認定のディストリビューションで、K3sと並べて比較されます。商用サポートはMirantisが提供しており、CNCFには2025年1月19日にSandboxとして受け入れられました。配布形態は似ていますが、既定の構成がはっきり違います。
| 項目 | K3s | k0s |
|---|---|---|
| 商用サポート | SUSE | Mirantis |
| CNCF | Sandbox(2020年8月〜) | Sandbox(2025年1月〜) |
| 既定のデータストア | SQLite(--cluster-init で組み込みetcd) |
単一ノードはSQLite、複数ノードはetcd |
| 既定のCNI | Flannel | kube-router(Calicoも選べる) |
| Ingress・LoadBalancer | Traefik・ServiceLBを同梱 | READMEの機能一覧には無い(挙がる同梱物はKonnectivity・CoreDNS・Metrics Server) |
| コントロールプレーン | サーバーノードもワークロードを実行 | 既定で分離(同居させるなら --single か --enable-worker) |
| 複数台への配布 | ノードごとにスクリプト実行(k3sup・k3s-ansibleも) | k0sctlがYAMLを基にSSHで一括構築 |
| 2026年10月24日時点の安定版 | v1.37.1+k3s1(stableチャネルはv1.36.5) | v1.36.4+k0s.1(1.37はalphaのみ) |
選び方の軸は「入れた直後に外部へ公開できるか」と「構築を宣言的に回したいか」です。1台のエッジ機器でIngressまで含めてすぐ動かしたいならK3s、コントロールプレーンをワークロードから分けたうえで、手元の端末から複数台をまとめて構築・更新したいならk0sが合います。
k0sctlは、k0sctl init で雛形を作り、ホストとroleを書いた k0sctl.yaml を k0sctl apply で適用するツールです。アップグレード専用のサブコマンドは無く、spec.k0s.version を上げて再度 apply します。バックアップは k0sctl backup、復元は k0sctl apply --restore-from です。v0.33.1(2026年9月21日公開)のトップレベルのコマンドは version・apply・kubeconfig・init・reset・backup・config(edit・status)・completionで、ネット上で見かける k0sctl upgrade や k0sctl status は存在しません。
k3d・MicroK8s・kind・minikubeとの違い
k3dとK3sの違いは「同じK3sをどこで動かすか」だけです。k3dはK3sをDockerコンテナとして起動する補助ツールで、MacやWindowsのDocker Desktop上でも複数ノード構成を作れます。前述の実測で公式イメージを docker run したのと同じ仕組みを、ノードの追加やポート公開まで含めて自動化したものです。ただしk3dはコミュニティ主導のプロジェクトで、SUSEの公式製品ではありません。本番のノードにはK3sを直接入れます。
MicroK8sとK3sの違いは配布経路と作り手です。MicroK8sはCanonicalがsnapパッケージとして配り、最小構成の上流Kubernetesに microk8s enable dns のようにアドオンを足していく方式です。snapを使わずに導入したい場合、K3sは候補になります。ただしエアギャップ環境では、バイナリだけでなくコンテナイメージやインストールスクリプトなどの事前搬入も必要です。
手元でKubernetesを学ぶだけなら、Docker上で完結するkindやminikubeでも十分です。kindの手順はk8sをローカルで動かす手順|kindでクラスタ構築からDeployment公開・撤収までに、minikubeはminikubeとは?v1.39のインストール・dashboard起動・アンインストール手順にまとめています。
K3sを選ばない方がよい条件
- Windowsノードが要る:K3sはWindowsにネイティブ対応していない。
- コンポーネントごとにログを分けたい:Kubernetesの主要コンポーネントが同一プロセスで動き、klogの設定を共有するため、それらのログレベルや出力先を個別に変えられない。
-vや--vmoduleを渡しても期待どおりには効かない。 - SDカードのRaspberry Piで組み込みetcdのHA:公式が性能問題を警告している。外付けSSDにするか、シングルサーバー+SQLiteに留める。
- 既存のGaleraクラスタを外部DBに使いたい:前述のとおりkineの前提と合わない。
- FIPSやSELinux MCSの要件がある:同じRancher系でもRKE2が対象としている領域。
K3sで組むかマネージドKubernetesに載せるかを含め、本番クラスタの構成や運用体制づくりは、弊社のインフラ構築(AWS・Google Cloud・Azure)でも支援しています。
K3sが起動しない・ノードが参加しないときの確認ポイント
最初に見るのはログとOS設定です。
# systemd のログ
sudo journalctl -u k3s -f # サーバー
sudo journalctl -u k3s-agent -f # エージェント
# カーネル設定・cgroup の不足を検査
sudo k3s check-config
- Raspberry Pi OSで起動しない:標準ではcgroupが無効。
/boot/firmware/cmdline.txtの行末にcgroup_memory=1 cgroup_enable=memoryを足して再起動する(Debian 11以前は/boot/cmdline.txt)。 - エージェントが参加しない:サーバーの6443番に届くか、トークンが
node-tokenの値と一致するか、ホスト名が他ノードと重複していないかを確認する。 - Pod間通信だけが通らない:ノード間の8472/UDPがセキュリティグループやufwで止められていることが多い。
- RHEL 8.4より前でネットワークがおかしい:NetworkManagerの既知の不具合。
nm-cloud-setupを無効化して再起動する。 - 80/443番が既存のnginx等とぶつかる:ServiceLBは既定で全ノードの80・443番をTraefikに割り当てるので、同じポートを使うHostPortやNodePortのPodは置けない。
--disable=traefikで外すか既存サービスを移す。 - HelmChartConfigでTraefikのService型を変えたのに効かない:チャートv40以降は
service.spec.typeに書く。service.typeは黙って無視される。
Podのログは /var/log/pods、containerdのログは /var/lib/rancher/k3s/agent/containerd/containerd.log にあります。コンテナランタイムの仕組みはcontainerdとは?Dockerとの関係・runc/CRIの仕組みとKubernetesでの役割を解説で解説しています。
K3sに関するよくある質問
K3sの読み方は何ですか?
公式の読み方は定められていません。READMEに「正式名称も公式の読み方も無い」と書かれています。アルファベットどおり「ケー・スリー・エス」と読めば誤解なく伝わります。
K3sは本番環境で使えますか?
使えます。公式はK3sを「本番運用可能で、CNCF認定のKubernetesディストリビューション」と位置づけています。コントロールプレーンの停止を許容できない本番環境では、組み込みetcdの3台構成、または複数サーバーと高可用な外部DBでHAを組みます。停止を許容する単一拠点のエッジ用途ではSQLite構成も選択肢とし、いずれも版を固定してバックアップと復旧手順を用意してください。
K3sはどれくらいのメモリで動きますか?
公式の最小要件はサーバー2GB・エージェント512MBです。v1.36.5を実際に起動したところ、ワークロードなしの標準構成で約672MiB、Traefik・ServiceLB・metrics-serverを外すと約444MiBでした。アプリを載せる分はこれに上乗せになります。
K3sはMacやWindowsで動きますか?
直接は動きません。K3sはLinux専用です。MacやWindowsで試すなら、Docker上でK3sを動かすk3dを使うか、Linux VMを立ててその中にインストールします。
K3sとk0sの違いは何ですか?
どちらも単一バイナリのCNCF認定Kubernetesですが、K3sはTraefik・ServiceLB・Flannelを同梱し、サーバーノードでもワークロードを動かします。k0sは既定でコントロールプレーンを分離し、CNIはkube-router、複数ノードのデータストアはetcdで、k0sctlを使ってSSH越しに複数台をまとめて構築します。
K3sとk3dの違いは何ですか?
k3dはK3sをDockerコンテナとして起動するための補助ツールで、中身のKubernetesは同じK3sです。手元で複数ノードを試すならk3d、実機やVMで動かすならK3sを直接入れます。
K3sとMicroK8sの違いは何ですか?
どちらも軽量なCNCF認定Kubernetesですが、K3sは単一バイナリをスクリプトで入れ、既定のデータストアがSQLiteです。MicroK8sはCanonicalがsnapで配布し、アドオンを有効化して機能を足します。snapを使わずに導入したい場合はK3sが候補になります。エアギャップ環境では、必要なイメージや依存パッケージを事前搬入できるかも比較してください。