Skip to content

필사 모드: k0s閉域網インストールとk0sctl自動化 — イメージバンドル作成から複数ノードアップグレードまで

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに — バイナリ一つとバンドル一つで終わらせるには

k0sの設計思想は単純です。単一バイナリ一つがコントロールプレーンでありワーカーであり、インストールスクリプトもパッケージリポジトリも必要ありません。閉域網の観点からこれは大きな利点です。搬入審議に上げるファイルが実質的に二つに減るからです。k0sバイナリ一つとイメージバンドル一つです。

ただしこの単純さには代償があります。k3sはリリースに上がったエアギャップアーカイブをそのままコピーすれば終わりですが、k0sは「何をバンドルに入れるか」を利用者が明示的に決める構造に近いです。だから自前のワークロードイメージを同じバンドルに合わせるのはむしろ簡単ですが、代わりにバンドル作成段階でインターネットにつながる機器にk0sバイナリを先に用意しておかなければなりません。

検証基準は以下のとおりです。

項目確認時点確認した出典
k0s最新安定版v1.36.3+k0s.0 (2026-07-27)2026-07-31k0sリリース
k0sctl最新版v0.32.2 (2026-07-28)2026-07-31k0sctlリリース
バンドル自動インポートデータディレクトリ下位のimages2026-07-31k0s Airgap Install
既定のデータディレクトリ/var/lib/k0s2026-07-31k0s Airgap Install

k0sctl v0.32.0で、ホスト接続・リモート実行レイヤーがrig v0.xからrig v2.0.0へ丸ごと入れ替わりました。リリースノートは接続・ファイル転送・OS検知領域の回帰に注意するよう明示しているので、閉域網に導入する際はステージングでファイルアップロード経路を必ず先に検証してください。

搬入対象の算出 — k0sが要求するファイル

k0sのリリースページには閉域網に必要な資産がすでに上がっています。v1.36.3+k0s.0基準で確認した主要資産は次のとおりです。

資産サイズ(確認時点)用途
k0s-v1.36.3+k0s.0-amd64約250 MBk0s単一バイナリ
k0s-airgap-bundle-v1.36.3+k0s.0-linux-amd64.tar約390 MB基本システムイメージバンドル(すぐ使用可能)
k0s-airgap-bundle-v1.36.3+k0s.0-linux-arm64.tar約357 MBarm64ノード用バンドル
airgap-imagesテキストファイル (amd64/arm/arm64)数KBバンドルに入ったイメージ一覧
SHA256チェックサムファイル数KB整合性検証

リリースが提供するバンドルをそのまま使えば、バンドル作成段階を飛ばせます。自前のイメージを混ぜる必要のない最初のインストールなら、この経路がもっとも速いです。

#!/usr/bin/env bash
# collect-k0s.sh — インターネットにつながるステージング機器
set -euo pipefail

K0S_VERSION="v1.36.3+k0s.0"
ARCH="amd64"
URLVER="${K0S_VERSION/+/%2B}"
BASE="https://github.com/k0sproject/k0s/releases/download/${URLVER}"
OUT="./k0s-airgap-${K0S_VERSION}"

mkdir -p "${OUT}" && cd "${OUT}"

curl -fL -o k0s "${BASE}/k0s-${K0S_VERSION}-${ARCH}"
chmod +x k0s

curl -fL -o "k0s-airgap-bundle-${K0S_VERSION}-linux-${ARCH}.tar" \
  "${BASE}/k0s-airgap-bundle-${K0S_VERSION}-linux-${ARCH}.tar"

# 搬入マニフェストは自分で作ります — 内側でメディアの破損を判別する唯一の根拠です
sha256sum k0s "k0s-airgap-bundle-${K0S_VERSION}-linux-${ARCH}.tar" > MANIFEST.sha256
echo "${K0S_VERSION}" > VERSION
ls -la

イメージバンドル作成 — list-imagesとbundle-artifacts

リリースバンドルを使わず、直接作らなければならない場合があります。自前のワークロードイメージを一緒に入れたい、基本CNIの代わりに別のものを使う、社内ポリシー上すべてのイメージを社内レジストリ経路にタグ付けし直して搬入しなければならない、といった場合です。

k0sは必要なイメージ一覧を自ら抽出してくれます。

# インターネットにつながる機器でk0sバイナリを使って実行
./k0s airgap list-images --all > airgap-images.txt
wc -l airgap-images.txt
cat airgap-images.txt

一覧が出たら、バンドルにまとめます。公式文書が提示する方法は三つで、それぞれ前提条件が違います。

# 方法A — k0s内蔵ツール(Dockerも動作中のk0sも不要)
./k0s airgap bundle-artifacts -v -o image-bundle.tar < airgap-images.txt
# 方法B — すでに動作中のワーカーノードのcontainerdストレージから書き出す
k0s ctr images export image-bundle.tar $(k0s airgap list-images | xargs)
# 方法C — Dockerがある機器で
k0s airgap list-images --all > airgap-images.txt
xargs -I{} docker pull {} < airgap-images.txt
docker image save -o image-bundle.tar $(xargs < airgap-images.txt)

三つの方法の実務上の違いはこうです。

方法前提条件閉域網搬入の観点からの評価
bundle-artifactsk0sバイナリとインターネットもっともすっきりしている。Dockerデーモン依存がなく審議用ステージング機器に適する
ctr images exportすでに動作中のk0sワーカーノードすでに検証済みのイメージをそのまま取れる利点。ステージングクラスターが必要
docker saveDockerデーモン馴染みはあるがDockerのインストールが必要。マルチアーキテクチャの処理がもっとも面倒

方法Aを基本とし、ステージングクラスターがすでにあれば方法Bで「実際に動いたイメージ」を取るほうが安全です。

公式文書はk0sが緩やかなプラットフォームマッチングを使うため、マルチアーキテクチャバンドルが異なるプラットフォームで動作すると明示しています。amd64ノードとarm64エッジノードが混在する閉域網でバンドルを一つで管理できるということなので、搬入単位を減らすのに活用できる余地があります。

自前のワークロードイメージを同じバンドルに合わせる

k0s文書は「k0sが既定で使わないコンテナイメージを含めるようバンドルを簡単にカスタマイズできる」とし、バンドルにまとめる前にイメージ一覧を確認・編集するよう案内しています。実際にはリストファイルに行を追加するだけでよいのです。

# 1) k0sシステムイメージ一覧を抽出し
./k0s airgap list-images --all > airgap-images.txt

# 2) 社内ワークロードイメージを同じ一覧に追記します
cat >> airgap-images.txt <<'EOF'
registry.internal.example:5000/apps/api:1.4.2
registry.internal.example:5000/apps/worker:1.4.2
registry.internal.example:5000/infra/postgres:16.4
registry.internal.example:5000/infra/prometheus:v3.1.0
EOF

# 3) 重複除去後一度にまとめる
sort -u airgap-images.txt -o airgap-images.txt
./k0s airgap bundle-artifacts -v -o image-bundle.tar < airgap-images.txt

# 4) マニフェスト更新
sha256sum image-bundle.tar >> MANIFEST.sha256

このリストファイルをGitに上げておくことを強くお勧めします。閉域網搬入は反復作業であり、「今回の搬入に何が入ったか」を後で再構成できなければなりません。リストがコードとして管理されれば、次の搬入時にdiffだけ見ればよくなります。

手動インストール — 単一ノードと、コントローラー・プラス・ワーカー

搬入が終わっていれば、インストール自体は短いです。バンドルをデータディレクトリ下位のimagesフォルダに置いてk0sを起動すると、k0sがそのフォルダを監視して自動的にインポートします。

#!/usr/bin/env bash
# install-k0s-single.sh — 閉域網単一ノード
set -euo pipefail
STAGE=/opt/staging/k0s-airgap-v1.36.3+k0s.0

# 0) まず整合性検証
cd "${STAGE}" && sha256sum -c MANIFEST.sha256

# 1) バイナリ配置
sudo install -m 0755 "${STAGE}/k0s" /usr/local/bin/k0s
k0s version

# 2) イメージバンドル配置 — 起動前に入れる必要があります
sudo mkdir -p /var/lib/k0s/images
sudo cp "${STAGE}"/k0s-airgap-bundle-*.tar /var/lib/k0s/images/image-bundle.tar

# 3) 単一ノードインストール
sudo k0s install controller --single
sudo k0s start

# 4) 状態確認(バンドルインポートに時間がかかるのですぐReadyにならないことがあります)
sudo k0s status
sudo k0s kubectl get nodes -o wide
sudo k0s kubectl -n kube-system get pods

コントローラーとワーカーを分ける配置ならこうなります。イメージバンドルはワーカーノードに必要です。 実際にイメージをpullしてコンテナを起動する側がワーカーだからです。コントローラーがワーカーを兼ねる場合は、コントローラーにもバンドルが必要です。

# コントローラーノード
sudo install -m 0755 /opt/staging/k0s /usr/local/bin/k0s
sudo k0s install controller --enable-worker --no-taints
sudo k0s start
sudo k0s status

# ワーカー参加用トークン発行(コントローラーで)
sudo k0s token create --role=worker > /opt/staging/worker.token
# ワーカーノード
sudo install -m 0755 /opt/staging/k0s /usr/local/bin/k0s
sudo mkdir -p /var/lib/k0s/images
sudo cp /opt/staging/image-bundle.tar /var/lib/k0s/images/image-bundle.tar
sudo k0s install worker --token-file /opt/staging/worker.token
sudo k0s start
sudo k0s status

外部pull試行を完全に阻止する

バンドルがきちんと入ったか確認するもっとも確実な方法は、外部からイメージを取得する経路自体を遮断してみることです。k0sはクラスター設定でこれをサポートします。

# k0s.yaml
apiVersion: k0s.k0sproject.io/v1beta1
kind: ClusterConfig
spec:
  images:
    default_pull_policy: Never

公式文書はこの設定が「PodのimagePullPolicyをNeverにし、インターネットからイメージを取得しないことを保証する」と説明しています。閉域網ではこの値を最初からオンにしておくほうがよいです。そうすればバンドルに漏れたイメージがあるとき、数分後のタイムアウトではなく即座に失敗するので、搬入リストの漏れをその場で見つけられます。

ただしこの値をオンにすると、社内レジストリから取得するイメージも影響を受ける構成になり得るので、アプリケーションPodまで一括適用されるかは、このクラスター設定を適用した状態で実際のデプロイで確認しなければなりません。システムコンポーネントだけに適用される範囲なのかワークロード全体なのかは、今回の確認範囲では文書の本文だけで断定できなかったので、ステージングで直接検証してください。

k0sctl自動化 — SSHでバンドルとバイナリを押し込む

ノードが三台を超えると、手動手順はすぐに崩れます。誰かが一台のノードでバンドルコピーを忘れ、そのノードだけおかしな動作をします。k0sctlはこの反復をYAML一枚で代替します。

核心はk0sctlが閉域網内側のジャンプホストで実行されるという点です。k0sctlはインターネットではなくSSHで対象ノードに接続するので、ジャンプホストにk0sバイナリとイメージバンドルさえあれば、残りはk0sctlが各ノードへ転送します。

# 閉域網ジャンプホストにk0sctlバイナリを配置(これも搬入対象です)
sudo install -m 0755 /opt/staging/k0sctl /usr/local/bin/k0sctl
k0sctl version

# 初期設定ファイル生成
k0sctl init > k0sctl.yaml
# k0sctl.yaml — 閉域網3ノード構成
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: onprem-airgap
spec:
  k0s:
    version: v1.36.3+k0s.0
    config:
      apiVersion: k0s.k0sproject.io/v1beta1
      kind: ClusterConfig
      spec:
        images:
          default_pull_policy: Never
  hosts:
    - role: controller
      uploadBinary: true
      k0sBinaryPath: /opt/staging/k0s
      ssh:
        address: 10.10.20.11
        user: k0sadmin
        keyPath: /home/k0sadmin/.ssh/id_ed25519
    - role: worker
      uploadBinary: true
      k0sBinaryPath: /opt/staging/k0s
      ssh:
        address: 10.10.20.21
        user: k0sadmin
        keyPath: /home/k0sadmin/.ssh/id_ed25519
      files:
        - src: /opt/staging/image-bundle.tar
          dstDir: /var/lib/k0s/images
          perm: 0755
    - role: worker
      uploadBinary: true
      k0sBinaryPath: /opt/staging/k0s
      ssh:
        address: 10.10.20.22
        user: k0sadmin
        keyPath: /home/k0sadmin/.ssh/id_ed25519
      files:
        - src: /opt/staging/image-bundle.tar
          dstDir: /var/lib/k0s/images
          perm: 0755

ここで閉域網にとって決定的なフィールドが二つあります。

  • uploadBinary: true — k0sctlが各ノードでk0sをダウンロードする代わりに、実行ホストのバイナリをアップロードします。この値がなければノードがリリースサーバーへの接続を試み、閉域網ではその場で失敗します。公式エアギャップ文書の例もこのフィールドを使います。
  • files — 任意のファイルをノードの指定経路へ転送します。エアギャップ文書の例がそのままイメージバンドルをこの方式でワーカーに乗せます。

k0sBinaryPathでアップロードするローカルバイナリの経路を明示する方式は実務で広く使われていますが、今回の確認時点で公式エアギャップ文書の本文でこのフィールド名自体を直接確認できませんでした。uploadBinaryだけでも動作するので、フィールド名が不確かなら先にuploadBinary: trueだけを置き、k0sctl apply --debugでどのバイナリがどこからアップロードされているか確認したうえで追加してください。同じ理由で、エアギャップ文書例のkind値がレンダリングによって違って見える場合があるため、ここではk0sctlインストール文書基準のkind: Clusterを使いました。

適用と接続は次のとおりです。

# 構成適用 — バイナリアップロード、バンドル転送、クラスター構成まで一度に
k0sctl apply --config k0sctl.yaml

# kubeconfig回収
k0sctl kubeconfig --config k0sctl.yaml > kubeconfig
kubectl --kubeconfig kubeconfig get nodes -o wide
kubectl --kubeconfig kubeconfig -n kube-system get pods

SSHアクセス要件は閉域網でむしろ厄介になり得ます。ジャンプホストから各ノードの22番ポートが開いていなければならず、鍵認証ができなければならず、対象ユーザーがパスワードなしでsudoを使えなければなりません。この三つのうち一つでも社内セキュリティポリシーと衝突すれば、k0sctl経路は諦めて手動インストールにするべきです。導入前に先に確認すべき項目です。

アップグレード経路とk0sctlの限界

k0sctlのもっとも大きな実務価値はインストールではなくアップグレードです。手順がインストールとまったく同じです。

# 1) 新バージョンのバイナリとバンドルをジャンプホストに搬入
sha256sum -c /opt/staging/k0s-v1.36.3/MANIFEST.sha256

# 2) k0sctl.yaml のバージョン文字列とファイル経路だけ更新
#    spec.k0s.version: v1.36.3+k0s.0
#    hosts[].files[].src: /opt/staging/k0s-v1.36.3/image-bundle.tar

# 3) 同じコマンドで適用 — k0sctlがノードを順番に処理します
k0sctl apply --config k0sctl.yaml

# 4) 検証
kubectl --kubeconfig kubeconfig get nodes -o wide
kubectl --kubeconfig kubeconfig get pods -A --field-selector=status.phase!=Running

新しいイメージバンドルを先に上げなければならない点が閉域網特有の順序です。files項目が前にあるのでk0sctlがバンドルを転送してからk0sを入れ替えますが、バンドルのファイル名が以前のものと同じなら上書きになり、違えば二つ積み上がります。ディスクが厳しいエッジノードでは、以前のバンドルの整理を別段階として入れる必要があります。

限界も明確です。公式文書はk0sctlがノードを追加できるが、既存ノードを削除できないと明言しています。閉域網でハードウェアを交換したりノードを減らしたりするとき、k0sctl設定から消してもクラスターから抜けないので、別途手順が必要です。

# ノード削除は手動です
kubectl --kubeconfig kubeconfig drain worker-03 --ignore-daemonsets --delete-emptydir-data
kubectl --kubeconfig kubeconfig delete node worker-03

# 該当ノードでk0s整理
sudo k0s stop
sudo k0s reset

ここで詰まります — k0s閉域網の失敗モードとk3sとの比較

症状原因確認方法
k0sは起動したがすべてのPodがImagePullBackOffバンドルを起動後に入れたか経路が間違っているls /var/lib/k0s/images とk0s ctr images lsを対照
ワーカーだけPodが起動しないバンドルをコントローラーだけに配置各ワーカーでimagesフォルダを確認
k0sctl applyがダウンロードで止まるuploadBinaryが漏れているk0sctl apply --debugで転送ログを確認
k0sctl applyがSSH段階で失敗鍵認証またはパスワードなしsudoが不可sshで直接接続後sudo -n trueを試行
ノードを外したのにクラスターに表示され続けるk0sctlはノード削除をしないkubectl delete nodeとk0s resetを手動実行
インポートに時間がかかりReadyが遅いバンドルサイズが数百MB — 正常動作journalctl -u k0scontroller またはk0sworkerでインポートログ確認
arm64ノードだけ失敗アーキテクチャ別バンドルを誤って配布バンドルファイル名とuname -mを対照

インポート所要時間について一言添えます。公式文書はk0sがimagesフォルダを監視して自動インポートするとだけ述べ、所要時間には言及していません。実際には数百MBのバンドルを展開してcontainerdストレージに入れる作業なので、ディスクが遅いエッジハードウェアでは数分かかることがあります。起動直後ノードがNotReadyだからといってすぐに失敗と判断せず、サービスログでインポートの進行状況を先に確認してください。

sudo journalctl -u k0scontroller -f    # コントローラー
sudo journalctl -u k0sworker -f        # ワーカー
sudo k0s ctr images ls | wc -l         # インポートされたイメージ数が増えているか

k3sの流れとの正直な比較

k3sk0s
イメージ搬入リリースアーカイブをイメージフォルダにコピーリリースバンドルのコピーまたはlist-imagesで直接作成
自前イメージの統合別のtarを追加で配置リストファイルに行を追加するだけで一つのバンドルに統合 — よりすっきり
インストール入口install.shと環境変数k0s installサブコマンド — スクリプト搬入が不要
複数ノード自動化別のツールが必要(Ansibleなど)k0sctlが公式ツールとして存在 — よりすっきり
外部pull遮断disable-default-registry-endpoint(ミラー設定対象のみ)default_pull_policy Never — 意図がより直感的
プライベートレジストリミラーregistries.yamlでrewriteまでサポートcontainerd設定を直接扱う必要 — 手間が増える
ノード削除手動手動(k0sctlが未サポート)
コミュニティ資料圧倒的に多い相対的に少なく問題解決が遅い — 閉域網で体感が大きい

まとめると、バンドル作成と複数ノード自動化はk0sが優れており、プライベートレジストリミラーリングと問題解決資料はk3sが優れています。 社内レジストリをすでに運用中でイメージ経路の書き換えが必要な環境なら、k3sのregistries.yamlが与える利点が大きいです。逆にレジストリなしでバンドルだけで複数ノードを繰り返し構築・アップグレードしなければならない環境なら、k0sctl一枚が与える利点が大きいです。

おわりに — 自動化ツールがSSHを使うという事実がすべてです

閉域網でk0sctlが有効な理由は機能が華やかだからではなく、インターネットではなくSSHを使うからです。搬入審議を通過したファイルがジャンプホストに置かれた瞬間から、クラスター構築が純粋な内部作業になります。この性質を持つツールかどうかが、閉域網ツール選定の第一の基準です。

そしてリストファイルをGitに入れてください。バンドルに何が入ったか記録していない搬入は、必ず次の搬入時に同じ調査を最初からやり直させます。

参考資料

현재 단락 (1/198)

k0sの設計思想は単純です。単一バイナリ一つがコントロールプレーンでありワーカーであり、インストールスクリプトもパッケージリポジトリも必要ありません。閉域網の観点からこれは大きな利点です。搬入審議に上...

작성 글자: 0원문 글자: 11,309작성 단락: 0/198