TX1310 M3にUbuntu 18.04をPreseedでインストールしてみた

# はじめに

TX1310 M3は比較的安価に入手できる富士通製のサーバー機です。Kubernetesを導入するため、とりあえず4台ほど入手しました。まず準備として全台を同じ環境にするために、Preseedを利用して初期化用の自動インストーラーを作成することにしました。

BIOSについては、参考資料のTX130 S3pのMBRと違い、TX1310 M3はUEFIがデフォルト設定です。これまでUEFI+Software RAID1構成のpreseed.cfgファイルは作成していないので、今回メモを残すことにしました。

## Software RAIDの利用について

過去に業務で使用していたサーバーは、小型なものでもHardware RAIDチップを搭載していて、SCSI/SASディスクを2台搭載しているRAID1構成機でした。ずいぶん昔のスペックの低いサーバーの話しですが、HDDとはいえ読み込み時にはストライピングしてくれていたのか、レスポンスについては申し分なく、現在でも懐しく思うほどです。

LinuxのSoftware RAIDは便利ですし、業務でも利用可能な安定性を持っていると思います。最近ではSSDの登場など、ハードウェアは高性能になっていますが、可用性を確保するためにRAID1を導入するなどの対応は、まだ一般消費者に近い層では行なわれていないように感じています。

もし、規模は小さくとも、業務で使用する安価なサーバーを考えているのであれば、まずSoftware RAIDではなく、LSI Corp.(現Broadcom)の廉価(でも本物)なHBA/RAIDカードを使い、ディスク管理はHBA/RAIDカードに任せるのがお勧めです。残念ながらTX1310は内部の配線などの関係で、簡単にはRAIDカードを使わせてくれませんが、Software RAIDを使うことができます。

検索すると、安価なファイルサーバーを作ろうと、TX1310のようなエントリーレベルのサーバーとデスクトップ用HDD+Software RAIDを利用する例が散見されますが、もし業務での利用を考えているのであれば、24時間稼動が前提のニアライン以上のHDDを使う事、ファイルのバックアップをUSB接続のRAID0ディスク(WD Book DUO等)で取得すること、利用者を個別に認証するぐらいは、検討する必要があります。

> これまで個人事務所+αのような小規模環境で廉価なサーバー機にデスクトップ用HDDを複数台載せて、Sambaを動かすファイルサーバーを構築している事例をみたことがあります。しかし、ファイルサーバー上に保存したファイルのバックアップが検討されていなかったり、ユーザー認証が適切に利用されていなかったり、OSの定期的なアップデート＆再起動が検討されていないなど、不十分な運用が行なわれていました。最近はSynologyやQnapのようなNAS専用機があって、その上でdockerが動いたりするので、LDAP等のサービスを動かすことが可能です。High-Availability構成が取れるものがほとんどなので、費用面では同機種を2台導入するなど高価になりますが、サポートも得やすいので、技術力が不足する現場では、こういった製品の機能をうまく使って欲しいと思います。

# 参考資料

* TX1310 M3注意事項 http://jp.fujitsu.com/platform/server/primergy/manual/pdf/tx1310m3/ca92344-1920-05.pdf
* [TX120 S3pにpreseedでRAID1構成なUbuntu 18.04.2を導入してみた](https://qiita.com/YasuhiroABE/items/d960263843a23f8f5ec2)  (※ 基本的には、この作業結果をUEFI対応にするだけ。preseed.cfgファイル全体を残していないので、これを残すのが今回の主な目的)
* [PreseedでUbuntu 18.04をProvisioningした作業メモ (UEFI対応版)](https://qiita.com/YasuhiroABE/items/135a5507b6d47363ab31)  (※ RAID1ではないバージョン)
* [Installing EFI to Raid 1 using partman and seed file, on both drives](https://askubuntu.com/questions/497719/installing-efi-to-raid-1-using-partman-and-seed-file-on-both-drives)
* [UEFI booting and RAID1](https://outflux.net/blog/archives/2018/04/19/uefi-booting-and-raid1/)
* [今更ながら，UEFI 環境での grub-install と update-grub 方法](http://nort-wmli.blogspot.com/2016/12/uefi-grub-install-grub-update.html)

# ISOイメージを作成する基本的な作業手順

これまでに書いたものが分散しているので、ほぼ最小手順をまとめておきます。

準備作業としてカレントディレクトリ(CWD)に [ubuntu-18.04.2-server-amd64.iso](http://ubuntutym2.u-toyama.ac.jp/ubuntu-full/18.04/release/ubuntu-18.04.2-server-amd64.iso) ファイルが存在することを前提にしています。

作業ディレクトリとして、~/work/ を使用しています。

```bash:ISOイメージ作成手順
$ mkdir -p ~/work
$ cd ~/work
$ sudo mkdir -p /mnt/iso
$ sudo mount -o ro,loop ubuntu-18.04.2-server-amd64.iso /mnt/iso
$ mkdir iso_root
$ rsync -av /mnt/iso/. iso_root/.
$ sudo chown -R "$(id -un)" iso_root/
$ sudo chmod -R u+rwX iso_root
$ dd if=ubuntu-18.04.2-server-amd64.iso of=iso_root/isolinux/isohdpfx.bin bs=512 count=1

## iso_rootディレクトリ内部の変更

## MBR・UEFI両対応ISOイメージを作成する方法 (両対応)
$ sudo xorriso -as mkisofs -volid "UB1804_%Y%m%d" -output ubuntu-18.04.2-server-amd64-preseed."$(date +%Y%m%d.%H%M%S)".iso -eltorito-boot isolinux/isolinux.bin -eltorito-catalog isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot -isohybrid-gpt-basdat -isohybrid-mbr iso_root/isolinux/isohdpfx.bin iso_root/
```

ここまでで、カレントディレクトリにISOイメージファイルが作成されているはずです。

次からはUEFIに対応した手順をまとめていきますが、基本的にはMBRブートをしたいISOイメージでも編集するファイルが違うだけで、ここでのISOイメージを作成するまでの手順は同じはずです。

# 【UEFI対応】iso_rootディレクトリ内部の変更について

ここから、中心となるpreseed関連の設定を行なっていきます。

これまでRAID1構成の場合は、MBRブートを前提としてきましたが、今回は次のような要素が入ります。

* UEFIブート
* Software RAID1 (/dev/md0) 構成

## iso_root/preseed/preseed.cfg ファイルの作成

```text:preseed.cfg
d-i debian-installer/locale string en_US
d-i debian-installer/keymap string us
d-i keyboard-configuration/xkb-keymap select us
d-i keyboard-configuration/toggle select No toggling
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string localdomain
d-i mirror/http/mirror select jp.archive.ubuntu.com
d-i apt-setup/restricted boolean true
d-i apt-setup/universe boolean true
d-i apt-setup/backports boolean true
d-i apt-setup/services-select multiselect security
d-i apt-setup/security_host string security.ubuntu.com
d-i apt-setup/security_path string /ubuntu
d-i mirror/suite string bionic
d-i passwd/user-fullname string Admin User01
d-i passwd/username string ubuntu
d-i passwd/user-password password temppwd
d-i passwd/user-password-again password temppwd
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false
d-i clock-setup/utc boolean false
d-i time/zone string Asia/Tokyo
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string ntp.nict.jp
d-i partman-auto/disk string /dev/sda /dev/sdb
d-i partman/alignment string cylinder
d-i partman/confirm_write_new_label boolean true
d-i partman-basicfilesystems/choose_label string gpt
d-i partman-basicfilesystems/default_label string gpt
d-i partman-partitioning/choose_label string gpt
d-i partman-partitioning/default_label string gpt
d-i partman/choose_label string gpt
d-i partman/default_label string gpt
d-i partman-auto/method string raid
d-i partman-auto/choose_recipe select gpt-boot-root-swap
d-i partman-auto/expert_recipe string         \
   gpt-boot-root-swap ::                      \
      1 1 1 free                              \
         $bios_boot{ }                        \
         method{ biosgrub } .                 \
      200 200 200 fat32                       \
         $primary{ }                          \
         $bootable{ }                         \
         method{ efi } format{ } .            \
      1000 20000 -1 raid                      \
         $primary{ }                          \
         method{ raid }                       \
	 format{ }                            \
         raidid{ 1 } .
d-i partman-auto-raid/recipe string \
    1 2 0 ext4 /                    \
          raidid=1                  \
    .
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
d-i partman/confirm_nooverwrite boolean true
d-i partman-basicfilesystems/no_swap boolean false
d-i partman-md/device_remove_md boolean true
d-i partman-md/confirm boolean true
d-i partman-md/confirm_nooverwrite boolean true
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-swapfile/percentage string 0
d-i partman-swapfile/size string 0
d-i preseed/early_command string umount /media || true
d-i partman/early_command string /bin/sh -c 'for mdev in /dev/md[0-9]* ; do mdadm --stop $mdev ; done ; mdadm --misc --zero-superblock /dev/sd[a-z][1-9]' || true
d-i base-installer/install-recommends boolean true
d-i base-installer/kernel/image string linux-server
d-i apt-setup/use_mirror boolean false
d-i apt-setup/restricted boolean true
d-i apt-setup/universe boolean true
d-i apt-setup/backports boolean true
d-i apt-setup/services-select multiselect security
d-i apt-setup/security_host string security.ubuntu.com
d-i apt-setup/security_path string /ubuntu
d-i debian-installer/allow_unauthenticated boolean true
tasksel tasksel/first multiselect none
d-i pkgsel/include string openssh-server python2.7-minimal
d-i pkgsel/upgrade select full-upgrade
popularity-contest popularity-contest/participate boolean false
d-i pkgsel/update-policy select none
d-i pkgsel/install-language-support boolean true
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i grub-installer/bootdev  string /dev/sda
d-i finish-install/reboot_in_progress note
d-i preseed/late_command string \
 in-target mkdir -p /home/ubuntu/.ssh ; \
 in-target cp /media/cdrom/preseed/authorized_keys /home/ubuntu/.ssh/authorized_keys ; \
 in-target chmod 750 /home/ubuntu/.ssh ; \
 in-target chown -R ubuntu:ubuntu /home/ubuntu/.ssh ; \
 in-target cp /media/cdrom/preseed/sudoers /etc/sudoers ; \
 in-target chmod 440 /etc/sudoers ; \
 in-target chown root:root /etc/sudoers ; \
 in-target sed -i -e 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config ;
```

## iso_root/boot/grub/grub.cfg ファイルの編集

変更しているのはmenuentryで始まる行から下の部分です。

```text:grub.cfg
if loadfont /boot/grub/font.pf2 ; then
        set gfxmode=auto
        insmod efi_gop
        insmod efi_uga
        insmod gfxterm
        terminal_output gfxterm
fi

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray

set timeout=0
menuentry "Install Ubuntu Server with Preseed" {
        set gfxpayload=keep
        linux   /install/vmlinuz file=/cdrom/preseed/preseed.cfg vga=normal 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 quiet --
        initrd  /install/initrd.gz
}
```

このファイルの中で指定したpreseed.cfgファイルを指定しています。
今回利用いたpreseed.cfgのファイル名は任意ですが、別の名前にする場合は、ここでの指定も変更する必要があります。

## preseed/late_command で設定するファイルの配置

今回利用したpreseed.cfgファイルはansibleで追加の構成を加えるなどの理由で、次の場所にファイルを配置して、インストーラーの中でコピーさせています。

* iso_root/preseed/authorized_keys
* iso_root/preseed/sudoers

# インストール直後の、RAID1としては不十分な構成について

インストールが終って、再起動すると /boot/efi ディレクトリが /dev/sda2 からマウントされている事に気がつきます。

/dev/sdb側の対応するパーティション/dev/sdb2は空のままです。

現状ではHDD1(/dev/sda)が壊れても、システムの内容はHDD2(/dev/sdb)側に格納されていますが、HDD1側にしかないEFIパーティションが失なわれてしまうため、そのままでは起動できません。

## /dev/sda (HDD) が壊れる事を想定した準備作業

Preseedを利用する限り、EFIパーティション(/dev/sdb2:/boot/efi)をRAID1でミラーする設定は難しいようです。
Webで検索するとFedoraではパーテイョンIDを工夫しながらRAID1を構成しつつ、EFI領域を確保しているようです。

2nd HDD側で/boot/efiに対応する/dev/sdb2は、フォーマット済みで確保されているものの、放置されています。

```bash
$ sudo mkdir -p /boot/efi2
$ sudo mount /dev/sdb2 /boot/efi2
$ sudo grub-install --efi-directory /boot/efi2 --bootloader-id ubunut
```

この時にblotloader-idを変更してしまうと、/boot/efi*/EFI/ubuntu/grub.cfgの場所にファイルがないため、起動時にGRUBのプロンプトが表示されてしまいます。


いずれにしても、追加したEFIディレクトリはマウントしておきます。

```bash
$ vi /etc/fstab
...
UUID=yyyy-yyyy /boot/efi  vfat umask=0077 0 1
UUID=xxxx-xxxx /boot/efi2 vfat umask=0077 0 1
```

UEFIに登録されているかどうかは、次のコマンドで確認することができます。

```bash
$ efibootmgr -v
BootCurrent: 0004
Timeout: 1 seconds
BootOrder: 0004,0000,0003,0001
Boot0000* ubuntu        HD(2,GPT,4d76e3cd-78ed-443b-baef-a8471fc78990,0x7c4,0x5f5e2)/File(\EFI\UBUNTU\SHIMX64.EFI)
Boot0001* UEFI: HL-DT-ST DVDROM DUD0N   PciRoot(0x0)/Pci(0x17,0x0)/Sata(5,65535,0)/CDROM(1,0x448,0x1340)..BO
Boot0003* UEFI OS       HD(2,GPT,4d76e3cd-78ed-443b-baef-a8471fc78990,0x7c4,0x5f5e2)/File(\EFI\BOOT\BOOTX64.EFI)..BO
Boot0004* ubuntu        HD(2,GPT,a7866e0e-0516-46f5-9d16-74f2572cb667,0x7c4,0x5f5e2)/File(\EFI\UBUNTU\SHIMX64.EFI)..BO
```

表示された結果から、両方がubuntuの名称で登録されていて、少し分かりにくくなっています。
blkidコマンドの出力からどちらのディスクか確認することができます。

```bash:blkidコマンドの出力
$ sudo blkid
/dev/sda1: PARTUUID="f48c4789-918d-436e-9f05-71e02383408d"
/dev/sda2: UUID="E69E-E3F3" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="a7866e0e-0516-46f5-9d16-74f2572cb667"
/dev/sda3: UUID="c7c438a4-082a-a3d9-7eaf-5e89fc2ffad6" UUID_SUB="1806dac8-ccd3-9ad7-b8f2-d7cb65112d6e" LABEL="ub1804:0" TYPE="linux_raid_member" PARTUUID="d6e3a67b-9de5-4d19-8683-fa22d483b1b8"
/dev/sdb1: PARTUUID="c111eba2-02fa-4962-8df7-5b79158a7ea1"
/dev/sdb2: UUID="E6A1-3D58" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="4d76e3cd-78ed-443b-baef-a8471fc78990"
/dev/sdb3: UUID="c7c438a4-082a-a3d9-7eaf-5e89fc2ffad6" UUID_SUB="d65dac34-dd5c-58e0-e9b8-9e6fb0a315dd" LABEL="ub1804:0" TYPE="linux_raid_member" PARTUUID="e1f9e3aa-fbe2-4c12-a46f-6143f9c9ef1a"
/dev/md0: UUID="e5980168-243c-4482-9a63-078b56c240e2" TYPE="ext4"
```

Boot0004→Boot0000の順に起動するので、*PARTUUID*の場所を探すと、/dev/sda2の次の/boot/sdb2上の\EFI\UBUNTU\SHIMX64.EFIファイルが順番に呼ばれるようになっていることが分かります。

しかし、少なくともVMware Workstaiton 15 Proでは、同一のラベルをもつ要素はブート順にはどちらか一方のみが表示されています。
その場合でもディスクの片方を削除すると、きちんと起動していて、いまのところ致命的な問題には遭遇していませんが、次の問題に遭遇します。

### ディスク1台で起動しようとした時の対応方法

ディスクが1台無くなった状態で再起動をしようとすると、/etc/fstabに記述されている /boot/efi か /boot/efi2 のいずれかの領域がマウントできなくなるので、起動時の処理が途中で停止します。

停止した段階でシェルに落ちるので、手動で/etc/fstabからマウントできないエントリを削除するか、あらかじめディスク障害が分かっているのであれば、該当側のディスクが記述されているエントリを/etc/fstabから削除してから新しいディスクに交換して再起動する必要があります。

1台のディスクのみで動いている場合には、新しいディスクにパーティションを同じように切ってから、mdadmコマンドで追加します。

```bash:mdadmによるディスク交換時の作業例
$ sudo mdadm --add /dev/md0 /dev/sda3
``` 

追加したディスクの/boot/efi or /boot/efi2 領域を、先ほどの要領で追加します。
/etc/fstabで/boot/efiか/boot/efi2の領域をUUIDで指定している場合には、適切に変更する必要があります。

### 考慮点

故障したディスクがHDD1側の場合には、そのまま再起動すると上記の理由でブートできず、手動で/etc/fstabの修正が必要になります。

これが問題になる場合は、/proc/mdstatを監視するなど、ディスク異常が発生したまま再起動が発生しないような注意が必要と思われます。

今回はKubernetesクラスターは最低3台あればサービスが提供できるように構成しています。

### Ansible-Galaxy Roleによる/boot/efi, /boot/efi2領域の管理

/boot/efi2領域のgrubへの登録と/etc/fstabファイルの編集は、台数が多いと面倒なので、Ansible-Galaxyのroleを追加しました。

* https://galaxy.ansible.com/YasuhiroABE/manage_mdraid1

### 【参考】bootloader-idに"ubuntu"以外を利用した場合の対応策

初稿では--bootloader-idに"ubuntu-2nd"を指定していましたが、このままだと、/EFI/ubuntu/grub.cfgを固定的に探そうとしてgrubのプロンプトが表示されてしまいます。(grubx64.efiの中に固定的にパスが埋め込まれているようにみえます)
この場合でもGRUBにgrub.cfgの場所を教えてあげると無事に起動します。

```bash:grubプロンプトへの入力例
grub> configfile (hd1,gpt2)/EFI/ubuntu-2nd/grub.cfg
```

あるいは、/boot/efi2/EFI/ubuntu/grub.cfgのパスにcpコマンド等で準備しても起動しますが、二度手間なのであまりお勧めしません。

```bash:grub.cfgをgrubx64.efiが認識する場所にコピーする例
$ sudo mkdir -p /boot/efi2/EFI/ubuntu/
$ sudo cp -ip /boot/efi2/EFI/ubuntu-2nd/grub.cfg /boot/efi2/EFI/ubuntu/
```


# この他のTX1310 M3に固有と思われる事象

## SATAの動作モード

購入した4台ともデフォルト設定は、RAIDモードになっていました。
このため起動時に表示される(設定後はF2キー)から、BIOS設定画面に移動し、SATAの動作モードを*AHCI*に変更しています。

## update-grubが66%で停止する

結論からいうと、TX1310の問題ではないです。
同じ現象に遭遇した場合は、Control+Alt+F2 などで別のttyに移って、```$ ps | grep dmset```で表示されるdmsetupプロセスを繰り返し2回停止すると、インストールが進み無事にインストールが終了します。

この現象そのものは以前から報告されていて、この中でdmsetupプロセスを停止することがワークアラウンドとして指摘されています。

* https://bugs.launchpad.net/ubuntu/+source/os-prober/+bug/1663645
* https://ubuntuforums.org/showthread.php?t=2283752

使用しているHDDによっては再現性がありますし、別のディスクでは何回繰り返しても再現しません。
Software RAID1にしている構成が問題だったりするのかとも思いますが、とりあえずこれで動かしています。



以上