PreseedによるUbuntuの自動インストール入門

  • 76
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

追記 11/09
今日、久しぶりにPreseedを走らせようと思ったらcfgファイルの取得に失敗したので、gistは消してないのにおかしいなあ、ネットワーク周りのせいかなあとおもったのですが、gistへのHTTP経由でのアクセスがいつのまにかできなくなっていました。残念です。

なので、GitHub Pagesにアップすることにしました。
こっちはHTTPアクセスもOKですし。
公開リポジトリで gh-pages ブランチを切ってpushすれば完了。
詳細は後ほど。


最近、OpenStackをUbuntu Serverにインストールして遊んでいるのですが、
中身がごちゃごちゃになってくると原因の切り分けが難しくなるのでクリーンインストールしたくなります。
しかしクリーンインストールするたびにソフトウェアRAID1構築して、LVM設定して、
swapパーティション切って・・・ってやってるとげんなりします。
仮想マシンならVagrant一回boxファイル作って、chef-soloでちゃちゃっと環境構築できちゃうと思いますが、
私の場合、物理サーバーそのものにUbuntuをインストールしないといけないのでVagrantは使えません。
こういう刺し身タンポポな作業はCentOS系列ではKickstart、Ubuntu系列ではPreseedを使ってサーバーセットアップを自動化します。

必要最小限なインストールが完了したらchefでちゃっちゃと料理してあげればいいのではないでしょうか。(勉強中)

どのインストール方式を選択するか

この記事はPreseedによるUbuntuインストールの自動化を勉強をしようとしている方向けに書いています。

Preseedを使うと言ってもインストールの仕方にはいろいろあって、一長一短です。
ざっと方法を並べると以下のとおりです。

  1. ISOイメージに preseed.cfg を同梱して専用のDVDを作ってインストールする。
  2. PXEブート方式。pxelinuxのイメージをTFTPで取得して preseed.cfg をネットから取得して、 それにしたがってネットワークインストールする。DVDいらずです。
  3. (1)で作成するISOイメージで preseed.cfg の設定はネットワーク上からHTTPで取得する。 パッケージのインストールは主にDVDから行う。

大規模なインフラを構築する場合は(2)のPXEブート方式が一番自由度が高くていいのですが、
なにぶん、セットアップがめちゃくちゃ大変でネットワークからパッケージを引っ張ってくるのでものすごく遅いです。
実験用途で preseed.cfg をちょっと書き換えてテストするのには遅いし、ハードルが高めです。
これを高速化しようとすると apt のミラーをローカルに構築しなきゃいけないので、どんどん深みにハマっていつの間にか目的を見失ってしまいます。

preseed.cfg に関するドキュメントが全然なくて日本語の情報も少ないので何度も何度も
トライ・アンド・エラーすることになるので、 DVDが何十枚あっても足りないです。preseed.cfg はネットから取得するようにしたいですね。
なので、(3)を選択します。

Tips

  • まずはVirtualBoxで何度もpreseedのテストをするといいです。
  • スクリーンショットもとれる。
  • Alt+F4 でログを見れる。(Macは option+fn+F4

システム構成

  • isoイメージを作成する母艦: Ubuntu 13.04 Desktop
  • 今回カスタマイズするもの: Ubuntu Server 12.04.3 LTS amd64
  • DHCP環境必須(静的IPをサーバーに設定するつもりでも必須です)

カスタムDVDを作成する

手順としては以下のとおりとなります。

  1. isoイメージをダウンロード
  2. 母艦となるUbuntuでそのisoをマウントしてisolinuxの設定を書き換える
  3. カスタムisoイメージを作成
  4. それをDVDに焼く
  5. サーバーにDVDを入れて自動インストール
  6. 完了

ダウンロード

まずはUbuntu ServerのISOイメージを母艦にダウンロードします。

Download Ubuntu Server | Ubuntu

必要なパッケージをインストール

sudo apt-get -y install syslinux mtools mbr genisoimage dvd+rw-tools

作業ディレクトリ作成

mkdir -p /var/tmp/ubuntu1204/{dvd,dvdr}
cd /var/tmp/ubuntu1204/

マウント

isoイメージはループバックデバイスだから他に何かオプション指定しないといけない気がしたんだけど。

sudo mount -t iso9660 /var/tmp/ubuntu-12.04.3-server-amd64.iso /var/tmp/ubuntu1204/dvd

isoイメージからファイルコピー

cd dvd
find . ! -type l | cpio -pdum ../dvdr/
1340648 ブロック

展開された中身を見ると以下のようになっています。

cd ..
ls dvdr -F
EFI/                boot/          dists/  install/   md5sum.txt  pool/
README.diskdefines  cdromupgrade*  doc/    isolinux/  pics/       preseed/

isolinux.cfg ファイルの編集

これはブート時のメニュー定義ファイルです。
dvdr/isolinux/isolinux.cfg の中身を以下の内容で全置換します。
読み取り専用になってるので ! を付加して強制的に書き込みます。
ごちゃごちゃしていて不安になるかもしれませんが、appendでくっつけているオプションは消すと自動化できません。
インストール時に確認画面が出てしまいます。

# dvdr/isolinux/isolinux.cfg
default install
label install
  menu label ^Install Ubuntu Server
  kernel /install/vmlinuz
  append DEBCONF_DEBUG=5 auto=true locale=en_US.UTF-8 console-setup/charmap=UTF-8 console-setup/layoutcode=us console-setup/ask_detect=false pkgsel/language-pack-patterns=pkgsel/install-language-support=false interface=eth0 hostname=localhost domain=localdomain url=http://gist.github.com/wnoguchi/6578034/raw/preseed.cfg vga=normal initrd=/install/initrd.gz quiet --
label hd
  menu label ^Boot from first hard disk
  localboot 0x80

DEBCONF_DEBUG=5 はデバッグ用のオプションでインストール時に Alt+F4 で仮想ターミナルを切り替えると preseed のログを見ることができます。
それとそのログは /var/log/installer/syslog に保存されるので後で眺めると勉強になります。ただし超長いです。

以下、簡単な説明です。

インストーラに与える引数

これはpreseed.cfgにも記入するのですが、append行でもくっつけておかないと確認画面が出てしまいます。
注意です。

auto=true locale=en_US.UTF-8 console-setup/charmap=UTF-8 console-setup/layoutcode=us console-setup/ask_detect=false pkgsel/language-pack-patterns=pkgsel/install-language-support=false interface=eth0 hostname=localhost domain=localdomain

preseed.cfg を読み込む先の指定

url=http://gist.github.com/wnoguchi/6578034/raw/preseed.cfg

でpreseed.cfgを読み込む先を設定します。インストーラはいったんDHCPでネットワークを解決してからこのファイルを取りに行きます。
ここではgistから読み込むようにしています。

なぜgistから読み込むようにしているか。
  • gistなら手軽にバージョン管理できてどこを変更したのか一目瞭然
  • 手元のパソコンの好きなエディタで編集してgistにぺたっと貼り付けてUpdate。
    FTPでアップロード、SSHでサーバーに接続してファイルを直接編集するなどしなくていいので実験しやすい。
  • プライベートgistが作れるからなかなか他人に見つかりにくい。
    gistはプライベートgistを作れてもURLばれたら他人から丸見えです。注意。
    機密な環境でやってる場合はローカルな閉じた環境のHTTPサーバーを読み込む先に指定するのが吉です。

Gistでpreseed.cfgの履歴を見ているところ

ちなみにサンプル中で僕のsecret gistのURLが貼ってありますがこれは仕様です。見られても問題ないので書いています。

gistを使う上での注意点

プロトコルはHTTPじゃないと読み込めないので注意(SSLのやり方知らない)

gistのファイルのURLはrawだと

http://gist.github.com/wnoguchi/6578034/raw/38eba11433ef26b57e0a9b85aa2a0f3eeadfc5c5/preseed.cfg

な感じになりますが、これだと特定のコミットハッシュを読みに行ってしまうので、最新のmasterを見に行くようにします。
そうするとURLは以下のようになります。

http://gist.github.com/wnoguchi/6578034/raw/preseed.cfg

preseed.cfgを作成する

gistで次の2つのファイルを作成します。

prescript.sh
#!/bin/sh
killall.sh; netcfg
preseed.cfg
#===========================================================================================
# BOOT SEQUENCE CONFIGURATIONS START
# ENDの設定のところまではDVDメディア、USBメディアに同梱している場合にのみ有効になる設定。
# PXEブートの場合はこのセクションは無視される。
# この場合はpxelinuxのconfigのappendに直接記述する必要がある。
#===========================================================================================
d-i debian-installer/language string en
d-i debian-installer/country string US
d-i debian-installer/locale string en_US.UTF-8
d-i localechooser/supported-locales en_US.UTF-8
d-i console-setup/ask_detect boolean false
d-i console-setup/layoutcode string us
d-i console-setup/charmap select UTF-8

# キーボードレイアウトの特性の設定(日本語キーボード)
d-i keyboard-configuration/layoutcode string jp
d-i keyboard-configuration/modelcode jp106

#===========================================================================================
# ネットワークまわりの設定
#-------------------------------------------------------------------------------------------
# 静的IP
#-------------------------------------------------------------------------------------------
# preseed.cfgを外から持ってこようとするとどうしてもいったんDHCP解決しないといけない。
# そして以下の netcfg 項目は一回目は無視されるので d-i preseed/run のところで
# ネットワーク設定をリセットするハックが必要になる。
# そうすると静的IPとして設定を直してくれるようになる。
#
# 詳しくは以下:
# - https://help.ubuntu.com/lts/installation-guide/i386/preseed-contents.html
# - http://debian.2.n7.nabble.com/Bug-688273-Preseed-netcfg-use-autoconfig-and-netcfg-disable-dhcp-doesn-t-work-td1910023.html
#
# 以下の2項目を設定しないと静的IPとして処理されないので重要
d-i netcfg/use_autoconfig boolean false 
d-i netcfg/disable_autoconfig boolean true 

d-i netcfg/choose_interface select eth0 
d-i netcfg/disable_dhcp boolean true 
d-i netcfg/get_nameservers string 8.8.8.8 
d-i netcfg/get_ipaddress string 192.168.1.201 
d-i netcfg/get_netmask string 255.255.255.0 
d-i netcfg/get_gateway string 192.168.1.1 
d-i netcfg/confirm_static boolean true 
d-i netcfg/get_hostname string stack01 
d-i netcfg/get_domain string pg1x.com 
d-i netcfg/wireless_wep string 
#-------------------------------------------------------------------------------------------
# DHCPのとき
#-------------------------------------------------------------------------------------------
#d-i netcfg/choose_interface select eth0 
#d-i netcfg/disable_autoconfig boolean false
#d-i netcfg/get_hostname string openstack 
#d-i netcfg/get_domain string sv.pg1x.com 
#d-i netcfg/wireless_wep string 

# いったんリセット
d-i preseed/run string http://gist.github.com/wnoguchi/6578034/raw/prescript.sh
#===========================================================================================
# BOOT SEQUENCE CONFIGURATIONS END
#===========================================================================================

# インストーラパッケージをダウンロードするミラーを選択する
#d-i mirror/protocol http
d-i mirror/country string manual
d-i mirror/http/hostname string jp.archive.ubuntu.com
d-i mirror/http/directory string /ubuntu/
d-i mirror/http/proxy string

# インストールするスイートを選択
d-i mirror/suite precise

d-i clock-setup/utc boolean false 
d-i time/zone string Japan 
d-i clock-setup/ntp boolean false 

#===========================================================================================
# PARTMAN PARTITIONING SECTION START
#===========================================================================================
# すべてのRAIDデバイス構成を破棄する
d-i partman-md/device_remove_md boolean true
# すべてのLVMデバイス構成を破棄する
d-i partman-lvm/device_remove_lvm boolean true

d-i partman/confirm_nooverwrite boolean true

d-i partman-auto/disk string /dev/sda
d-i partman-auto/method string regular
d-i partman-auto/expert_recipe string root :: 19000 50 50000 ext4 \
        $primary{ } $bootable{ } method{ format } \
        format{ } use_filesystem{ } filesystem{ ext4 } \
        mountpoint{ / } \
    . \
    16384 90 32768 linux-swap \
        $primary{ } method{ swap } format{ } \
    . \
    100 100 10000000000 ext3 \
        $primary{ } method{ format } format{ } \
        use_filesystem{ } filesystem{ ext4 } \
        mountpoint{ /srv/extra } \
    .
d-i partman-auto/choose_recipe select root
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select Finish partitioning and write changes to disk
d-i partman/confirm boolean true
#===========================================================================================
# PARTMAN PARTITIONING SECTION END
#===========================================================================================

d-i base-installer/install-recommends boolean true 
d-i base-installer/kernel/image string linux-generic 

d-i passwd/root-login boolean true 
d-i passwd/make-user boolean false 
d-i passwd/root-password password password 
d-i passwd/root-password-again password password 
d-i passwd/user-fullname string testuser 
d-i passwd/username string testuser 
d-i passwd/user-password password insecure 
d-i passwd/user-password-again password insecure 
d-i user-setup/allow-password-weak boolean true 
d-i user-setup/encrypt-home boolean false 

d-i apt-setup/use_mirror boolean true 

d-i debian-installer/allow_unauthenticated boolean true 
tasksel tasksel/first multiselect none 
d-i pkgsel/include string openssh-server build-essential
d-i pkgsel/upgrade select none 
d-i pkgsel/update-policy select none 
d-i pkgsel/install-language-support boolean true 
popularity-contest popularity-contest/participate boolean false 
d-i pkgsel/updatedb boolean true 

# GRUBインストーラー
d-i grub-installer/grub2_instead_of_grub_legacy boolean true 
d-i grub-installer/only_debian boolean true 
d-i grub-installer/bootdev string /dev/sda

# インストールが終了したらサーバー再起動
d-i finish-install/reboot_in_progress note

ちなみに上のレシピは

Preseed Recipe: Basic Configuration

で提供しています。

カスタムisoイメージを作成する

いよいよISOイメージに固めます。

cd /var/tmp/ubuntu1204
sudo genisoimage -N -J -R -D -V "PRESEED" -o ubuntu-12.04-server-amd64-preseed.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table dvdr

(snip)

 93.17% done, estimate finish Mon Aug 26 23:25:33 2013
 94.65% done, estimate finish Mon Aug 26 23:25:33 2013
 96.13% done, estimate finish Mon Aug 26 23:25:33 2013
 97.61% done, estimate finish Mon Aug 26 23:25:34 2013
 99.08% done, estimate finish Mon Aug 26 23:25:34 2013
Total translation table size: 2048
Total rockridge attributes bytes: 371263
Total directory bytes: 1908736
Path table size(bytes): 12978
Max brk space used 369000
338099 extents written (660 MB)

実行してみる

いきなり物理マシンにやるのはけっこうしんどいので仮想マシンでやってみます。
うまくいきましたか?
何も聞かれずにインストールが進む様は気持ちがいいですね。

ソフトウェアRAID1構成、LVM構成をやってみたい方はこちらのレシピをどうぞ。

Preseed Recipe: Soft RAID1, LVM

それでは、よいDevOpsライフを。

参考サイト