ホーム » 技術 » Kickstartでさくらのクラウドのマイアーカイブを作ってみる

Kickstartでさくらのクラウドのマイアーカイブを作ってみる

さくらのクラウドには「アーカイブ」というのがあって、プレインストールされた様々なOSのディスクイメージが用意されている。代表的なOSや各種ディストリビューションが選べるようになっていて、選択してインストールするだけですぐに利用できるようになっている。ラインナップされたものを利用するだけならば、これで特に不満はないが、さくらが用意していないOSや、設定を変えたい(たとえばパーティショニングに不満があるとか)場合には、自分でインストールをし直すなどの手間暇をかける必要がある。

931

もちろんそのための手段は全部用意されている。具体的には、インストールISOイメージを用意してそこからVMをブートし、好きなようにインストールしてからディスクイメージを「マイアーカイブ」としてセーブしてしまえばいい。そこから作るサーバは自分のお好みの設定になっているという訳だ。

しかし、インストーラを使った作業というのは、ボタンをポチポチ押すのが面倒だ。インストール作業そのものは、そんなにしょっちゅうやることではないが、一度取り組むとピタリと狙ったものを作るまでに何度も作業を繰り返すことになったりする。そのたびに設定を変えながら繰り返し実行するのは面倒くさい。そこで設定をファイル化して、なるべくバッチ化・自動化したい。

そこで本稿では、インストール作業を自動化するKickstartの使い方を説明する。

Kickstart

KickstartはFedora/Redhat/CentOSで利用できるインストール自動化ツールだ。利用の流れを大雑把に説明するとこんな感じだ。

  1. 設定ファイルを用意しておく
  2. インストールメディアでブート
  3. 通常のインストールではなく、Kickstart設定ファイルを指定
  4. あとは完了するのを待つだけ

通常のインストールでは、GUIで様々な項目を指定・設定していくが、Kickstartの設定ファイルを書けば、ほぼすべての項目が設定できる。またKickstart内ではスクリプトも書けるし、対象マシンがネットに繋がっていれば外からデータも引っ張ってこられるので、事実上何でもできる。初期インストールでどこまでやるかはお好みの問題なので、ここでは必要最低限ということにしておき、例としてfail2banだけ追加する。さもないとsshポートにわんさかscanが来てしまうからだ。

設定ファイルをどう書くか

さてKickstartの設定ファイルをどう書けばよいだろうか。参考になる情報が2つある。ひとつは、手動でインストールしたときに生成される /root/anaconda-ks.cfg だ。実はこのファイルはKickstartの設定ファイルになっているので、これを調整すればお好みの設定にするのは比較的簡単だ。

もうひとつは、さくらインターネットが公開している「アーカイブを作成したときに使ったKickstart設定ファイル」だ。

これらを参考に、必要なものを入れ、不要なものを削除するというのがよいかもしれない。

Fedora 30用Kickstart

それではまず、現時点の最新であるFedora 30をインストールするKickstartを示そう。

#version=DEVEL
ignoredisk --only-use=vda
# System bootloader configuration
bootloader
# Clear the Master Boot Record
zerombr
# License agreement
eula --agreed
# Use text mode install
text
# Use CDROM installation media
cdrom
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8

# Firewall configuration
firewall --enabled
# Network information
network  --hostname=localhost.localdomain
# Root password
rootpw --iscrypted $6$otaxm.aCZGDxBs9R$bhSlTM8CTfne6kHYwITK3xKgO0Ow33eZbREzfzKCjcVh0iS74.B6bVFR2lOMQJCi7xFuncOokYWkGR0WEDxuN0
# SELinux configuration
selinux --disabled
# Run the Setup Agent on first boot
firstboot --enable
# Do not configure the X Window System
skipx
# System services
services --enabled="chronyd"
# System timezone
timezone Asia/Tokyo --isUtc --ntpservers=ntp1.sakura.ad.jp
# Disk partitioning information
part biosboot --fstype="biosboot" --onpart=vda1
part swap --fstype="swap" --onpart=vda2
part / --fstype="xfs" --onpart=vda3 --label=root

%pre
sgdisk -Z -n 1::+1M -n 2::+4G -n 3:: -t 1:ef02 -t 2::8200 -c 1:"BIOS boot partition" -c 2:"Linux swap" -c 3:"Linux filesystem" /dev/vda
%end

%post --log=/root/post-ks.cfg
set -x

dnf -y update

# fail2ban
dnf -y install fail2ban
cat <<EOL >/etc/fail2ban/jail.local
[sshd]
enabled = true
EOL
systemctl enable fail2ban

# network
cat <<EOL >/etc/sysconfig/network
NETWORKING=yes
HOSTNAME=localhost.localdomain
EOL

cat <<EOL >/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO="dhcp"
ONBOOT="yes"
EOL

cat <<EOL >/etc/resolv.conf
nameserver 133.242.0.3
nameserver 133.242.0.4
EOL

# grub
sed -i '/^GRUB_CMDLINE_LINUX/s/rhgb quiet/consoleblank=0 net.ifnames=0 biosdevname=0/' /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg

# sysctl
cat <<EOL >> /etc/sysctl.conf

# Do not accept RA
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.eth0.accept_ra=0
EOL

# cleanup batch
cat <<EOL > /root/clean.sh
rm -rf ../tmp/*
rm -rf ../var/log/anaconda*
rm -f ./*.cfg ./clean.sh
EOL
%end

%packages
@^server-product-environment
-cockpit*
gdisk
%end

ポイントとなる部分について、以下に説明していこう。

ディスクのパーティショニング

インストーラを使っていると、ディスクを思った通りにパーティショニングできずにイライラすることが多い。インストーラは万人に使えるようにしないければならないので仕方がないが、ぶっちゃけfdiskをそのまま開放してもらった方がずっと楽というのが自分の意見だ。Kickstartなら、それが思いのまま利用できる。

Kickstartでは %pre というディレクティブが利用できる。これはインストール処理の前に実行するスクリプトを記述できる。ただし実行環境はインストーラのramdisk上なので、非常に貧弱で限られたことしかできないことに留意しなければならない。とはいえやりたいことはパーティショニングなのでまったく問題はない。

%pre
sgdisk -Z -n 1::+1M -n 2::+4G -n 3:: -t 1:ef02 -t 2::8200 -c 1:"BIOS boot partition" -c 2:"Linux swap" -c 3:"Linux filesystem" /dev/vda
%end

sgdiskコマンドはgdisk(fdiskのGPT対応版)のスクリプト対応版で、コマンドラインでバッチ処理するときに便利だ。オプションをばらすとこういう意味になる。

-ZZap。ディスク全体を初期化する
-n 1::+1Mパーティション1を1MB切り出す
-n 2::+4Gパーティション2を4GB切り出す
-n 3::パーティション3を残り全部使って切り出す
-t 1:ef02パーティション1のラベルをEF02 (BIOS)にする
-t 2:8200パーティション2のラベルを8200 (swap)にする
-c …パーティションに名前を付ける

%preで処理が終わったら、Kickstartが処理を行う。具体的には

# System bootloader configuration
bootloader
# Clear the Master Boot Record
zerombr
# Disk partitioning information
part biosboot --fstype="biosboot" --onpart=vda1
part swap --fstype="swap" --onpart=vda2
part / --fstype="xfs" --onpart=vda3 --label=root

のあたりだ。特に35~37行が、各パーティションに具体的にBIOS、swap、/マウントポイントを割り当てている。ファイルシステムについてお好みに書き換えたいなら、ここを変更してもらいたい。

IPアドレスに関する事項

最近のIPアドレス周りの設定については、デバイス名が伝統的なeth0からens3(なんで3?)みたいなのに変更され、ちょっと面倒なことになっている。さくらのクラウドではこの変更を抑止し、伝統的なeth0、eth1…を使い続けている。これを実現するために、grubの設定に次のような設定を追記している。

net.ifnames=0 biosdevname=0

この上で、さくらのクラウドのシステムはインターネット上位側(バックボーン側)がeth0と仮定し(システム上そちら側を上位につなぐ仕様になっている)、設定ファイルを書き換えようとする。具体的には /etc/sysconfig/network-scripts/ifcfg-eth0 などのファイルだ。このルールに従っていれば、コンパネやAPIのIPアドレス変更が利用できる。

さてKickstartでこれを実現するにはどうすればよいだろうか。第一の方法として、Kickstart起動時に上記のgrubオプションを手動で指定する方法が使える。これをやるとインストール処理そのものをeth0でやってくれ、最終的な設定ファイルもifcfg-eth0でセーブしてくれる。だが手動で打ち込むべき手間が増える。

第二の方法はさくらのクラウドがやっているKickstart内で設定ファイルを書き換える方法だ。記述するべき内容は増えるが、実行するのはプログラムなので面倒はない。こっちに合わせておけばクラウドの仕様に合致するので無難ともいえる。

ネットワークの設定は、インストール処理が終わった後の %post ディレクティブ内で指定する。ちなみに%postディレクティブ内は、インストール処理後のディスクイメージにchrootした環境下で実行されるので、ほぼすべての処理が思いのままに実行できる。

# network
cat <<EOL >/etc/sysconfig/network
NETWORKING=yes
HOSTNAME=localhost.localdomain
EOL

cat <<EOL >/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO="dhcp"
ONBOOT="yes"
EOL

cat <<EOL >/etc/resolv.conf
nameserver 133.242.0.3
nameserver 133.242.0.4
EOL

# grub
sed -i '/^GRUB_CMDLINE_LINUX/s/rhgb quiet/consoleblank=0 net.ifnames=0 biosdevname=0/' /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg

ここでは3つのファイル(/etc/sysconfig/network、ifcfg-eth0、resolv.conf)を作成している。さくらのクラウドでは、VMインストール時にこれらをオーバーライトするので多少適当でもかまわない。特にIPアドレスはDHCP対応なので、このまま起動してもアクセスは可能だ。

最後のGRUBの設定はちょっとトリッキーだ。「rhgb」と「quiet」は起動時のグラフ表示を行うオプションだが、自分好みでないので削除している。代わりにコンソールのスクリーンセーブ機能のOFFと、eth0記法にするためのおまじないを入れる。そのうえでgrub2.cfgをアップデートして完了だ。

パッケージの追加

例示している設定ファイルではcockpitを削除している。cockpitの詳細は理解していないのだが、Webコンソールというのは気に食わないのでぜひ削除したい。そこで最初から削除しておきたい。

%packages
@^server-product-environment
-cockpit*
gdisk
%end

ところがこれを削除すると、一緒にgdiskも入れてもらえなくなるので、それを改めて追加している(ほかにもいろいろなくなるが、見たところ困らなそうだったのでgdiskだけ戻している)

このほかに、fail2banもぜひ入れておきたいが、指定してもうまくいかない。Kickstartのマニュアルによれば、指定できるパッケージ名は repodata/comps.xml を見よとある。これは要するに、インストールISO上のファイルと言うことだろうが、例示したり引用するのは面倒なのでやらない。いずれにしてもこれからパッケージ名を探すのはちょっと骨が折れそうだ。どちらかと言えば、%preの中からyum…じゃなかったdnfした方がいいような気がする。というわけでその方法でfail2banをインストールしてみる。

# fail2ban
dnf -y install fail2ban
cat <<EOL >/etc/fail2ban/jail.local
[sshd]
enabled = true
EOL
systemctl enable fail2ban

Fedoraのパッケージのfail2banは、デフォルトでは何もしてくれないので、自分でjail.localを書かなければならない。というわけで上記のようにファイルを用意してenableするコードを入れている。これで作成したサーバは最初から保護された状態になっている。

rootpw

rootのパスワードだが、もちろんこのままではいけない。適切にハッシュされた符号列を入れるべきだ。rootpwの行はこのone-linerの出力で丸ごと置き換えてほしい。

perl -e 'print "rootpw --iscrypted ", crypt("mypasswd", "\$6\$".substr(crypt(rand(1), "\$6\$"), 10, 16)), "\n";'

その他もろもろ

いろいろ細かいオプションがあるが、あまり変更するべきところはないと思う。強いて言えばkeyboardとlangぐらいだろうか?

Kickstartによるインストール手順

では具体的にKickstartでインストールしてみよう。さくらのクラウドでは、Fedora 30のISOイメージはパブリックISOイメージとして用意されているので、選択するだけでブートできる。

ISOイメージの選択

ISOイメージの指定のほかに、サーバの情報 >> タグ欄に「@boot-cdrom」という特殊タグを追加しておく。こうするとディスクより優先してISOイメージからブートするようになる。これは後の掃除のときに必要になる(掃除しなくてもよければ、この工程は不要だ)。

そうしておいてサーバを起動して、コンソールからアクセスすると、おなじみのインストーラが起動する。カウントダウンが始まっていると思うが、ここでTABキーを押す。するとインストーラに対してオプションを指定できるようになる。

Kickstart設定ファイルを与える方法はいくつかあるが、HTTP経由でネットワーク越しにアクセスさせる方法が一番楽だ。適当なWebサーバ上に、作成したKickstartファイルを置き、そのURLをインストール画面から入力する。「inst.ks=https://…」のように記入する。

Kickstartファイルの指定

できたらリターンキーを押す。後は終わるのを待つだけだ。

パーティショニングが終わったところ

例示したスクリプトにはdnf updateを含むので、終わるのに10分間ぐらいかかる。最後までいくと、こんな画面になって止まる。

無事にインストールが完了したところ

メッセージの通りにリターンキーを押してリブートする。上述の手順通りに「@boot-cdrom」タグをつけていれば、再びISOイメージからブートしてインストーラが起動するはずだ(さもないとインストールが完了したFedoraが起動する)。ここで、Troubleshootingを選択する。

Troubleshootingを選択

次に Rescue a Fedora system を選ぶ。

Rescue a Fedora systemを選択

これで、ramdisk上のシステムからディスクをマウントした状態でマシンをブートできる。途中で質問されるので、「1」と答えておく。

ディスクを/mnt/sysimageにマウントするよ?

最後にリターンキーを押せば、shellに落ちて何でもできるようになる。インストールが終わったディスクは /mnt/sysimage にあるので、これをチェックする。

インストールされたイメージのチェック

インストールの結果のログ、特に%post処理の結果は post-ks.cfg にセーブされているので、これをチェックしておく。もしanaconda全体の動作を確認したいなら、../var/log/anaconda/* を見ればよい。問題がないと判断できたら、clean.shというファイルがあるのでこれを実行しておく。

sh clean.sh

これは何をしているのかというと、Kickstart設定ファイルのここに書いてある。

# cleanup batch
cat <<EOL > /root/clean.sh
rm -rf ../tmp/*
rm -rf ../var/log/anaconda*
rm -f ./*.cfg ./clean.sh
EOL

ようするにログファイルを消し、/tmpをキレイにして、自分を消して終わる。お好み次第だが、実行しておくことをお勧めする。

最後にpoweroffして、ディスクを丸ごとアーカイブすれば終わりだ。

さくらのクラウドのディスク修正機能

さくらのクラウドにはディスク修正機能というのがあって、作成するサーバのIPアドレスやパスワードを書き換えられるようになっている。だがこれはさくらのクラウドが公式にサポートする「アーカイブ」で供給するイメージでないと利用できない。自作イメージである「マイアーカイブ」でも、仕様を一致させれば利用できなくはないが、前提条件が結構厳しい。マニュアルによると;

CentOS
最後の位置のパーティションのパーティションタイプが 8300 であること
最後の位置のパーティションのファイルシステムが ext4 であること
最後の位置のパーティションに ディスク修正での修正対象のファイル が存在すること
最後の位置のパーティションに /etc/redhat-release ファイルが存在し中身を初期状態から変更していないこと

https://manual.sakura.ad.jp/cloud/storage/modifydisk/about.html#centos

などとなっている。

白状すると、この機能の2番目のバージョンは自分で書いた(1番目は社長が書いた)のでどういう理屈かはよく分かっているのだが、特定ファイルを壊さないように変更するために、システムが本当に自分の知っているディストリビューションかどうかをチェックしようとして色々前提を置かざるを得ないのだ。このため、Fedoraを対応させたいと思っても、/etc/redhat-releaseの内容チェック(現在のバージョンでも変わっていなければ if (m/CentOS Linux release [67]\.\d+/) {...} みたいになっているはずだ)を書き換えてもらわなければならないのだ。で、これが結構大変なのである。というのも中途半端に対応してユーザのシステムを破壊したら大変なことになってしまうからだ。

この危険を承知で、ディスク修正機能をだますことは可能だ。というのは前提条件は上記の通り公開されているので、その通りにシステムを作れば書き換えてくれるのである。つまりFedoraでは /etc/redhat-release には

Fedora release 30 (Thirty)

と書いてあるわけだが、これを

CentOS Linux release 7.6.1810 (Core)

などと書き換えてしまえばいいのだ。しかしこんなことをして他の副作用はどうなるのか責任は負えない…。このほか、ファイルシステムにはxfsを指定しているがext4に戻さなければならなかったりする。現状ではDHCPでブートできるので、後からバッチで書き換えた方がいいように思われる。

参考リンク