午前2時の悪夢:大規模環境で外部ミラーが失敗する理由
午前2時14分。30台のウェブサーバー全体に重大なゼロデイ脆弱性のパッチを適用しようとしていた私は、「Connection Timed Out」エラーを凝視していました。オフィスのアップリンク帯域は飽和状態で、apt-get updateを実行するたびに、成功するかどうかは運任せの状態でした。プロダクション環境のサーバー群で外部ミラーに依存するのは、いつか失敗する賭けをしているようなものです。帯域幅を消耗し、CI/CDパイプラインを停滞させ、アップストリームの障害に振り回されることになります。
その時、ローカルリポジトリが必要だと痛感しました。エアギャップ環境を堅牢にするためであれ、単にデプロイ時間を短縮するためであれ、独自のパッケージミラーをホストすることは、Linuxエンジニアにとって不可欠なスキルです。私の4GB RAMを搭載したUbuntu 22.04ノードでは、この設定により15分かかっていたアップデートサイクルが10秒未満に短縮されました。スピードは重要です。数ギガバイトのセキュリティヘッダーを取得する際、10Gbpsのローカルネットワークは1Gbpsの商用ファイバー回線を圧倒します。
ローカル運用のメリット
- 帯域幅の劇的な節約: 50MBのパッケージを一度ダウンロードすれば、LAN経由で1,000台のサーバーに配布できます。
- 圧倒的なスピード: 数ギガバイトのセキュリティヘッダーを取得する際、10Gbpsのローカルネットワークは1Gbpsの商用ファイバー回線を圧倒します。
- バージョンの固定: クラスター内のすべてのサーバーで、全く同じパッケージビルドが実行されていることを保証できます。
- セキュリティの強化: ゲートを制御するのは自分自身です。検証済みのソフトウェアのみをプロダクション環境に導入できます。
基盤構築:必要なリポジトリツール
データを保存する場所と、それを配信する方法が必要です。私は、軽量で安定しており、静的ファイルを驚異的な速さで配信できるNginxを使用しています。このガイドでは、Debianベース(Apt)とRHELベース(Yum/Dnf)の両方のワークフローについて説明します。
ストレージの準備
ストレージを過小評価してはいけません。Ubuntu’のフルミラーは、簡単に250GBを消費します。専用のパーティションや外部のNVMeボリュームを使用してください。この例では、/var/repoを使用します。
sudo mkdir -p /var/repo/{ubuntu,centos}
sudo chown -R $USER:$USER /var/repo
同期ソフトウェアのインストール
Ubuntu/Debianでは、apt-mirrorが標準です。RHELやAlmaLinuxでは、createrepoとyum-utilsを利用します。
# Ubuntu/Debian リポジトリサーバー用
sudo apt update && sudo apt install apt-mirror nginx -y
# RHEL/AlmaLinux/CentOS リポジトリサーバー用
sudo dnf install yum-utils createrepo nginx -y
設定:パッケージの同期と配信
次に、どのリポジトリをクローンし、クライアントにどのように見せるかを定義します。ここでの正確な設定が、後の依存関係の破損を防ぎます。
1. Aptミラーの設定 (Ubuntu/Debian)
/etc/apt/mirror.listを編集します。このファイルは、apt-mirrorに対してファイルの出力先と、取得するアーキテクチャを指示します。
############# 設定 #############
set base_path /var/repo/ubuntu
set nthreads 20
set _crypto_md5 1
############# 設定終了 #########
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-security main restricted universe multiverse
clean http://archive.ubuntu.com/ubuntu
初回の同期を開始します。注意:100Mbpsの回線では、最初の200GBのプルに数時間かかります。
sudo apt-mirror
2. Yumミラーの設定 (RHEL/AlmaLinux)
RHELベースのシステムでは、reposyncでRPMを取得し、createrepoでクライアントがパッケージツリーを探索するために必要なメタデータを生成します。
# リポジトリを同期する
reposync -p /var/repo/centos --repo=baseos --download-metadata
# リポジトリのメタデータを生成する
createrepo /var/repo/centos/baseos
3. Nginxによる配信
これらのファイルにアクセスできるようにしましょう。/etc/nginx/sites-available/repoにNginxの設定を作成します。安全のため、アクセスはローカルサブネットに制限します。
server {
listen 80;
server_name repo.local.network;
root /var/repo;
location / {
autoindex on;
allow 192.168.1.0/24; # 内部ネットワークのみ許可
deny all;
}
}
サイトを有効化し、Nginxを再起動して変更を適用します:
sudo ln -s /etc/nginx/sites-available/repo /etc/nginx/sites-enabled/
sudo systemctl restart nginx
検証:ミラーの健全性を維持する
設定は戦いの半分に過ぎません。接続を確認し、データを最新の状態に保つ必要があります。ミラーが数ヶ月間放置され、同期スクリプトが密かに失敗していたために、プロダクションサーバーが脆弱な古いソフトウェアを実行し続けていたケースを私は見てきました。
クライアントマシンでのテスト
Ubuntuクライアントでは、/etc/apt/sources.listが新しい内部サーバーを指すように設定します:
deb http://repo.local.network/ubuntu/mirror/archive.ubuntu.com/ubuntu/ jammy main restricted
sudo apt updateを実行します。一瞬で終われば成功です。
AlmaLinuxクライアントでは、/etc/yum.repos.d/local.repoを作成します:
[local-baseos]
name=ローカル BaseOS
baseurl=http://repo.local.network/centos/baseos/
gpgcheck=0
enabled=1
アップデートの自動化
これらを手動で実行してはいけません。午前2時(今度は実際に眠れていることを願いますが)に実行されるようにcronジョブを設定します。/etc/cron.d/repo-syncを作成します:
0 2 * * * root /usr/bin/apt-mirror > /var/log/apt-mirror.log 2>&1
# または Yum の場合
0 2 * * * root reposync -p /var/repo/centos --repo=baseos --download-metadata && createrepo --update /var/repo/centos/baseos
「ディスク容量不足」の警告
最後に一つアドバイスを。ストレージを監視してください。リポジトリは増大します。私はパーティションの使用率が85%に達したときに警告を出すシンプルなシェルスクリプトを使用しています。ディスクがいっぱいになると同期が失敗し、メタデータが破損して、次の緊急事態がさらに大きな頭痛の種に変わってしまいます。
ローカルリポジトリの構築は、一度設定すれば長年にわたって恩恵を受けられる「セット・アンド・フォーゲット(設定して後は忘れる)」タスクです。外部世界への不安定な依存を、堅牢で制御された内部サービスに置き換えます。まずは小さく始め、実際に使用するスイートのみをミラーリングして、デプロイ速度が飛躍的に向上するのを実感してください。

