pxeboot-alpine について

GitHubリポジトリ

GitHub - teityura/pxeboot-alpine
Contribute to teityura/pxeboot-alpine development by creating an account on GitHub.

pxeboot-alpine

「pxeboot-alpine is 何 ?」

  • OSのインストール(インストールメディアの作成)
  • ネットワークの設定変更(ブリッジ作成)
  • パーティション分割(LVMシンプロビジョニング)

これらが面倒なので PXEブート しよう。
docker-compose up -d でサクッと環境構築しよう。
というリポジトリです。

PXEブートの動作イメージ

各サービスの役割について

[volume] isosボリュームの役割

ダウンロードしたISOを配置する 名前付きのボリューム
isos:/isos/ のようにして バインドマウントさせる前提

[service] iso-mounterの役割

ミラーサイトからISOをダウンロードしてきて、
ダウンロードしたISOをマウントして、
/isos/centos-stream-release8/ 以下にコピーする

mountコマンドを実行するために、
privileged: true にしている

[service] dhcp-serverの役割

dhcpd.conf をマウントして dhcpd を動かす

  • DHCPでIPを割り当てる
  • TFTPサーバのアドレスを教える
  • ブートイメージファイル名を教える

ブートイメージファイル名は architecture-type を見て、
BIOSベースのものか、UEFIベースのものか、
どちらか適したものを渡すようにしている

[service] tftp-server

in.tftpd を動かして /tftpboot/ 以下を公開する

  • ブートイメージファイルを公開する
  • ブート構成ファイル名を教える

isosボリュームをマウントする
コンテナ起動後に docker-entrypoint.d/ 以下のスクリプトを順に実行する

# ディレクトリについて
pxelinux/ 以下が BIOSベース
uefi/ 以下が UEFIベース

# 各ファイルについて
pxelinux.0 が ブートローダ
grub.cfg が GRUBメニュー
vmlinuz が カーネルイメージ
initrd が 初期RAMディスク

[service] http-server

isos.conf をマウントして httpd を動かす

  • OS構成ファイルを公開する
  • OSイメージファイルを公開する

isosボリュームをマウントする
コンテナ起動後に docker-entrypoint.d/ 以下のスクリプトを順に実行する

[service] rsyslog-server

pxe.conf をマウントして rsyslogd を動かす

  • キックスタート時のログを送信する

キックスタート時に、
ネットワークの設定をやったり、
パーティションの設定をやったり、
初回起動時にシェルスクリプトを実行してパッケージを入れたり、
色々とやっているのでデバッグが大変 だったので、
そのときのログをrsyslogサーバに送信している。

[network] ネットワークについて

network_mode: host としている
serviceごとにポートを指定して公開するのが理想だが、
dhcp周りでハマりそうだったので、
Dockerホストと同じネットワークで、各サービスを動かすようにしている

インストールするOSを変更する

デフォルトの設定だと、以下のようになります

  • インストールするOS
    • CentOS Stream Release8 20211109
  • ダウンロード先
    • http://ftp.iij.ad.jp/pub/linux/centos/8-stream/isos/x86_64/CentOS-Stream-8-x86_64-20211109-dvd1.iso
  • 保存先
    • /isos/centos-stream-release8

例えば、Debianを利用する場合、このようになりそうです

# インストールするOS, ダウンロード先を変える
vim iso-mounter/docker-entrypoint.d/01_copy-isos-to-volume.sh

# 保存先を変える
find . -type f -not -path "./.git/*" -not -path "./README.md" \
  -exec sed -i "s/centos-stream-release8/debian-buster/g" '{}' \;

# url, repoを変える
mv http-server/kickstarts/centos-stream-release8.cfg http-server/kickstarts/debian-buster.cfg
vim http-server/kickstarts/debian-buster.cfg

自身の環境に合わせて設定を変更する

デフォルトの設定だと、以下のようになります

  • PXEブートクライアントは 3台(NUC101, NUC102, NUC103)
  • ディスク名は nvme0n1
  • DockerホストのIPは 192.168.1.100
項目名 NUC101 NUC102 NUC103
MACアドレス xx:xx:xx:xx:xx:01 xx:xx:xx:xx:xx:02 xx:xx:xx:xx:xx:03
IPアドレス 192.168.1.101 192.168.1.102 192.168.1.103
デフォルトゲートウェイ(共通) 192.168.1.1
サブネットマスク(共通) 255.255.255.0
DNSサーバ(共通) 8.8.8.8 8.8.4.4 192.168.1.1

環境に合わせて設定ファイルを書き換える

このように書き換えるとよいでしょう

# change ip address
find . -type f -not -path "./.git/*" -not -path "./README.md" \
  -exec sed -i "s/192.168.1.100/192.168.xxx.xxx/g" '{}' \;
# DockerホストのIPを変更

# set target info
vim dhcp-server/dhcpd.conf
# MACアドレスなど、適宜変更

# set disk name
vim http-server/kickstarts/centos-stream-release8.cfg
# パーティション情報を適宜変更(後述)
# ディスク名を変更(nvme0n1 -> sda)

rootパスワード生成

rootパスワードを生成して、
http-server/kickstarts/centos-stream-release8.cfg
に書いておく

# rootパスワード生成
cat << 'EOF' | python3
import crypt,getpass
print(
    crypt.crypt(getpass.getpass(),
    crypt.mksalt(crypt.METHOD_SHA512))
)
EOF
Password: ( Enter Password )
$6$LFPIARjoxZxl2a2F$zU5PDLxhM405CQ7yzKQxnAglERWp6aj5JnmA5/.JO9fEPR3BBGlQeplrZirqLGrAxhsm725CbPjF5LTA9l12V0

docker-compose up -d で サクッと上げる

docker-compose up -d
docker-compose ps
docker-compose logs -f

PXEブート完了後の状態

192.168.1.101 の固定IPが割り当てられていて、
パーティション設定が完了していて、
スナップショットが取得できています。

[root@localhost ~]# ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 192.168.1.101/24 brd 192.168.1.255 scope global noprefixroute br0
       valid_lft forever preferred_lft forever

[root@localhost ~]# pvs
  PV             VG  Fmt  Attr PSize   PFree
  /dev/nvme0n1p2 vg1 lvm2 a--  930.82g 932.00m

[root@localhost ~]# vgs
  VG  #PV #LV #SN Attr   VSize   VFree
  vg1   1   6   0 wz--n- 930.82g 932.00m

[root@localhost ~]# lvs
  LV                  VG  Attr       LSize   Pool  Origin  Data%  Meta%  Move Log Cpy%Sync Convert
  lv_home             vg1 Vwi-aotz--  10.00g pool1         6.01
  lv_home_01_deployed vg1 Vwi---tz-k  10.00g pool1 lv_home
  lv_root             vg1 Vwi-aotz-- 300.00g pool1         0.87
  lv_root_01_deployed vg1 Vwi---tz-k 300.00g pool1 lv_root
  lv_swap             vg1 Vwi-aotz-- <15.70g pool1         0.01
  pool1               vg1 twi-aotz-- 928.09g               0.36   2.34

スナップショット取得時の状態に戻す方法

# 何かしらの作業で環境が汚れた
yum install -y tcpdump
which tcpdump

# スナップショットをリストアする
lvconvert --merge vg1/lv_root_01_deployed
reboot

# 再起動後にssh
ping 192.168.1.101
ssh root@192.168.1.101

# 先にスナップショットを取得しておく
lvcreate -sn lv_root_01_deployed vg1/lv_root

# 汚れる前の状況に戻っていることを確認してみる
which tcpdump

キックスタートの内容について

  • br0を作成している
    • dhcpdで割り振られたIPを static ip として、固定している
  • LVMシンプロビジョニングしている
    • スナップショットを取得している

KVMホストとして利用する前提なので、ブリッジを作成していて、
OSインストール時の状態をスナップショットとして残している

firstboot.sh っていうシェルスクリプトを作成していて、
初回起動時だけ実行するように /etc/cron.d に firstboot.cron を設置して、
実行時に、firstboot.sh firstboot.cron を消すという、
ちょっと変なことをやっています。

kickstart の設定内容については、
下記の記事が大変参考になりましたので、参考にしてみるといいでしょう。
KickStartその1(KickStartによるLinux自動インストール概要)

何が楽になったか

プライベートクラウドの構築がすげー楽になる(はず)

AWSだと、インストール用のイメージ(Amazon Linux AMI)などが用意されていて、
インストールメディア(USBメモリ)を作成する必要がない。

スナップショットを取得することができて、
環境が汚れたら、スナップショット取得時の状態に簡単に戻せる。

オンプレだと、インストールメディアを作成して、
環境が汚れたら、OSインストールからやりなおすことがザラだったので、
PXEブートして、インストールからのやり直しがスゲー楽になった。

LVMシンプロビジョニングしていて、
スナップショットの取得, リストアも容易なので、クラウドに近い形で利用ができる。

自宅サーバ構築を極めてる感じがして、気持ちいい(ロマン)

コメント

タイトルとURLをコピーしました