外部ネットワークから完全に隔離されたエアギャップ環境において、Kubesprayを用いたKubernetesクラスタの自動構築を行う場合、ブートストラップ処理やOSレベルの初期化に必要なパッケージ群を事前調達しておく必要があります。インターネット接続が可能な環境から単純に単一のRPMパッケージのみを取得して持ち込んでも、OSのマイナーバージョンや依存関係ツリーの欠損により、プロビジョニング中にパッケージインストールのエラーが発生する事例が多発します。
本稿では、Rocky Linux 9.7環境を前提とし、インターネット接続が可能なステージングホスト上で dnf の依存解決フラグを利用して必要なすべてのRPMパッケージを完全収集し、内部ネットワークのWebサーバー上にローカルYumリポジトリを構築・検証する手順を整理します。
1. ステージング環境の準備と依存解決メカニズム
インターネットに接続されたステージングホストは、ターゲットとなるエアギャップノードと同じOSディストリビューションおよびアーキテクチャで構成します。パッケージ依存ツリーを走査し、ダウンストリームの全依存関係を漏れなく収集するため、dnf-plugins-core プラグインを導入した上で dnf download コマンドを使用します。
sudo dnf install -y dnf-plugins-core
# ペイロード格納用ディレクトリの作成
mkdir -p /data/kubespray-rpms/os
mkdir -p /data/kubespray-rpms/docker-ce-stable
dnf download コマンドの主要オプション仕様
依存関係のダウンロードには以下のフラグを指定します。
--resolve: 指定したパッケージに必要な依存関係グラフを自動的に全件解析します。--alldeps: ステージングホスト上に既にインストールされているパッケージであっても、依存ツリーに含まれるすべてのRPMファイルを強制的にダウンロード対象とします。
dnf download --resolve --alldeps --destdir=<target_directory> <package_name>
2. RPMパッケージの取得手順
2.1 OS基本パッケージおよびKubernetesネットワーク依存関係のダウンロード
Ansibleの実行やKubesprayのノードセットアップに必要な基本ツール、ネットワーク制御ユーティリティ、Pythonバインディングを収集します。
sudo dnf download --resolve --alldeps \
--destdir=/data/kubespray-rpms/os \
python3 \
python3-libselinux \
conntrack-tools \
socat \
iproute \
iproute-tc \
iptables \
ipset \
ipvsadm \
ethtool \
chrony \
rsync \
tar \
unzip \
curl \
openssl \
ca-certificates \
ebtables
※ Rocky Linux 9などのEnterprise Linux 9系リポジトリにおいて ebtables パッケージが提供されていない、あるいは非推奨化されている場合は、対象リストから ebtables を除外して実行します。
sudo dnf download --resolve --alldeps \
--destdir=/data/kubespray-rpms/os \
python3 python3-libselinux conntrack-tools socat iproute iproute-tc \
iptables ipset ipvsadm ethtool chrony rsync tar unzip curl openssl ca-certificates
2.2 コンテナランタイム依存関係(containerd.io)の取得
標準のOSリポジトリにはプロダクションレベルの containerd.io パッケージが含まれていないため、公式のDocker CEリポジトリを登録して取得します。
# Docker CE Stableリポジトリの追加
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# containerdおよびSELinuxポリシーのダウンロード
sudo dnf download --resolve --alldeps \
--destdir=/data/kubespray-rpms/docker-ce-stable \
containerd.io \
container-selinux
Kubesprayで container_manager: containerd 構成を採用する場合、フルセットの docker-ce エンジンは不要であり、containerd.io および container-selinux のみで構成可能です。
3. アーカイブの作成とローカルリポジトリの展開
取得したパッケージ群の容量を確認し、圧縮アーカイブとしてまとめます。
cd /data
tar czf kubespray-rpms-rocky9.7.tgz kubespray-rpms
作成したアーカイブを内部のミラーサーバー(Nginx等)に転送し、ドキュメントルート下に展開します。
sudo mkdir -p /usr/share/nginx/html/ROCKY_9.7
sudo tar xzf kubespray-rpms-rocky9.7.tgz -C /usr/share/nginx/html/ROCKY_9.7
展開後、createrepo_c ユーティリティを実行してリポジトリのメタデータ(repodata)を生成します。
sudo createrepo_c /usr/share/nginx/html/ROCKY_9.7/kubespray-rpms/os
sudo createrepo_c /usr/share/nginx/html/ROCKY_9.7/kubespray-rpms/docker-ce-stable
4. クライアントノードの設定と検証
エアギャップ環境内のターゲットノードにおいて、外部リポジトリ設定を無効化し、作成したローカルリポジトリを参照するよう /etc/yum.repos.d/kubespray-local.repo を作成します。
[kubespray-os]
name=Kubespray OS RPMs
baseurl=http://harbor.devstack.co.kr/ROCKY_9.7/kubespray-rpms/os
enabled=1
gpgcheck=0
[kubespray-containerd]
name=Kubespray Containerd RPMs
baseurl=http://harbor.devstack.co.kr/ROCKY_9.7/kubespray-rpms/docker-ce-stable
enabled=1
gpgcheck=0
Troubleshooting
発生ケース1: ミラーサーバー側に createrepo_c が存在しない
エアギャップ環境内のリポジトリサーバー自身に createrepo_c コマンドがインストールされていない場合、メタデータの生成が行えず dnf makecache が失敗します。
対処手順:
インターネット接続のあるステージングホスト側で、あらかじめ createrepo_c 自体も依存関係を含めて取得し、ペイロードに同梱して持ち込みます。
sudo dnf download --resolve --alldeps \
--destdir=/data/kubespray-rpms/os \
createrepo_c
発生ケース2: リポジトリインデックス同期エラーとパッケージ見つからない問題
ローカルリポジトリ設定後、dnf list 実行時に旧キャッシュが残っていると、パッケージが発見できないエラーが発生します。キャッシュのクリアとインデックス再構築を明示的に実行する必要があります。
検証ログ例:
$ sudo dnf clean all
15 files removed
$ sudo dnf makecache
Kubespray OS RPMs 3.2 MB/s | 2.1 MB 00:00
Kubespray Containerd RPMs 1.8 MB/s | 12 kB 00:00
Metadata cache created successfully.
$ sudo dnf repolist
repo id repo name
kubespray-containerd Kubespray Containerd RPMs
kubespray-os Kubespray OS RPMs
$ dnf list containerd.io conntrack-tools socat
Available Packages
conntrack-tools.x86_64 1.4.7-2.el9 kubespray-os
containerd.io.x86_64 1.7.25-3.1.el9 kubespray-containerd
socat.x86_64 1.7.4.1-5.el9 kubespray-os
Lessons Learned
- 依存関係の強制全取得:
--alldepsオプションを付与しない場合、ステージングホストの導入済みパッケージがスキップされ、エアギャップ環境のノードで依存不足が発生するリスクがあります。 - コンテナランタイムの分離管理:
containerd.ioはDocker CEリポジトリから個別に取得し、OS標準リポジトリと分離してインデックス化することで、バージョン競合を回避できます。 - repodataの事前生成: リポジトリサーバー上で
createrepo_cによるメタデータ作成を行ってからクライアントに公開することが、健全なYum/DNFパッケージ配布の必須要件となります。</package_name></target_directory>