Ubuntu20.04で簡単にAutoInstall を行う方法

##はじめに
はじめまして、インフラエンジニアのJTです。
インフラエンジニアとしての職務はサーバーの構築とメンテナンスというのが一般でしょうか。私のコード開発経験も大学生の時に留まってますが、仕事でデベロッパーと共にWEBプロジェクトを進めるにデバッグも不可欠の一環なので、アプリケーションの不具合の原因がサーバーか、コードにあるかを解明するにはインフラエンジニアでもプログラミングの知識が欠かせないと思います。

このブログに、サーバーの構築に関する記事はもちろん、AWSデベロッパーアソシエイト資格の自習記録も書く予定です。基本は日本語と英語で書きますが、日本語の記事を先に掲載し、英語版はそのあとで掲載したいと思います。

ちなみに、私のIT知識は乏しくて日本語も英語もすごく下手なので、記事に間違えるところがあれば、ぜひともお教えください。

##AutoInstall とは
AutoInstall はUbuntu 20.04 から導入された自動的にOSインストールを行うツールです。最初に自動的にOSをインストールするという概念を触れたのは、Solaris 10 Jumpstartを学んだ時でした。

その後の仕事に使ったCentOS/RedHatもディスクでゼロからインストールを行ったので、自動インストールは一度もしませんでした。そらに、Vsphere/Esxi を使い始めると、OSとその他のパッケージを一度だけにインストールしておき、それを「ゴールデンイメージ」に転換してから、何体のVMもそれで作成できます。必要な時にバーチャルディスクを追加し、VMのストレージを拡大すれば十分でしょう（LVM必須）。AWSのEC2のAMIもそれに似てると思います。

では、VMやEC2を多く使われている時代に、Autoinstallの出番はないではないかと思う方もいらっしゃるでしょうか。元会社で取り扱ったプロジェクトでは、物理サーバーにOSのインストールとアプリケーションのデプロイ（ソフトウェア）がこちらの役割であり、サーバーホスティングとデータセンターの管理（ハードウェア）がクライアントの責任となりました。このケースでは、与えられた複数の同型のサーバーに同じOSとPHP環境を構築するにはCentOS/RHELのKickstart/UbuntuのAutoInstallで行うのが最適です。

残念なことですが、CentOS8は今年をもって終了し、その代わる物のCentOS Streamの場合は本番環境に導入すべきかどうか私が疑問を持っているので、Ubuntuを今後の学習対象に選びました。

##実行環境
このテストはApple MacBookPro 2015 13インチモデルと[VirtualBox](https://www.virtualbox.org)で構成されています。

MacbookProの仕様は以下のように
CPU:　　　デュアルコアi5 2.7GHz
SSD:　　　128GB
メモリ：　 8GB

AutoInstall の詳しい使い方は[Ubuntu](https://ubuntu.com/server/docs/install/autoinstall)に記載されています。[Dusktinさん](https://dustinspecker.com/posts/ubuntu-autoinstallation-virtualbox/) にもすぐに使えるテンプレートが書いてありますが、気になるのはディスクのパーティション分割について明言していません。

Ubuntuの場合はパーティションに関する設定がこれだけ

```text:
    storage:
      layout:
        name: lvm
```

この設定だとディスクのレイアウトをLVMに設定し、

（参考として以下はデフォルトのパーティション分割のスクリーンショット）
![Screen Shot 2021-09-25 at 11.52.23 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2057805/11759b47-ad34-37a5-0898-0745ba26172c.png)

Grub　に１MBを、
/boot をext4として設定し、1GBを、
/ をLVMのロジカルボリュームとして設定し、残ったディスクの空間を全部振り分ける

というデフォルトの分割になります。

もし、デフォルト以外のボリュームを設定したければ、どうする？
コツはまずUbuntuインストーラーを通じてOSをインストールして、あとは完了まで待機します。

再起動してから、SSHでログインし、下記のファイルを開きます。

```text:
cd /var/log/installer
sudo vi autoinstall-user-data
```

すると、このようなものが表示されます。

```text:

#cloud-config
autoinstall:
  apt:
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://us.archive.ubuntu.com/ubuntu
    - arches: [default]
      uri: http://ports.ubuntu.com/ubuntu-ports
  identity: {hostname: ithost, password: $6$NPLmJFVMoi8QGjQr$7MWX45ajTNTpE3Ar33mquKzFUd62AZwkMjOxaNPwSuId41JSoeRGiN9/HKryS/RbR.UBDc.KBCYHDawWETJ320,
    username: ub20}
  kernel:
    kernel: {package: linux-generic}
  keyboard: {layout: us, toggle: null, variant: ''}
  locale: en_US.UTF-8
  network:
    ethernets:
      enp0s3: {dhcp4: true}
    version: 2
  ssh:
    allow-pw: true
    authorized-keys: []
    install-server: true
  storage:
    config:
    - {ptable: gpt, serial: VBOX_HARDDISK_VB8f97059d-a7457df4, path: /dev/sda, wipe: superblock,
      preserve: false, name: '', grub_device: true, type: disk, id: disk-sda}
    - {device: disk-sda, size: 1048576, flag: bios_grub, number: 1, preserve: false,
      grub_device: false, type: partition, id: partition-0}
    - {device: disk-sda, size: 1073741824, wipe: superblock, flag: '', number: 2,
      preserve: false, grub_device: false, type: partition, id: partition-1}
    - {fstype: ext4, volume: partition-1, preserve: false, type: format, id: format-0}
    - {device: disk-sda, size: 15029239808, wipe: superblock, flag: '', number: 3,
      preserve: false, grub_device: false, type: partition, id: partition-2}
    - name: ubuntu-vg
      devices: [partition-2]
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - {name: ubuntu-lv, volgroup: lvm_volgroup-0, size: 15028191232B, wipe: superblock,
      preserve: false, type: lvm_partition, id: lvm_partition-0}
    - {fstype: ext4, volume: lvm_partition-0, preserve: false, type: format, id: format-1}
    - {path: /, device: format-1, type: mount, id: mount-1}
    - {path: /boot, device: format-0, type: mount, id: mount-0}
  updates: security
  version: 1

```

はい、これはUbuntu AutoInstallに用いられるuser-data (テンプレート）です。下のように少し修正を加えれば、再利用できます。

まずは`apt:` から `uri: http://ports.ubuntu.com/ubuntu-ports` までの行を削除します。
次は`kernel:` で始まる行を削除します。 
そして`storage:`から下の二行目に見てみましょう

```text:
- {ptable: gpt, serial: VBOX_HARDDISK_VB8f97059d-a7457df4, path: /dev/sda, wipe: superblock,
      preserve: false, name: '', grub_device: true, type: disk, id: disk-sda}
```

`serial: VBOX_HARDDISK_VB8f97059d-a7457df4,`　が不要になりますので、
削除しておきます。

`storage: `からの行にこういうふうに理解できるでしょうか：

１：　Ubuntu がこのVirtualBoxのVMにつけられる容量15GBのディスクを/dev/sda だと認識しました。　`path: /dev/sda`に注目。
2:   このディスクは３つのパーティションに分けられている。　
`id: partition-[0-2]`に注目。
3：　Partition-0 がGrubとして1048576バイト(1MB)を振り分けられている。
`grub_device: true`に注目。
4:  Partition-1 がext4 としてフォーマットされ、1073741824（1GB）を振り分けられている。 `id: format-0`に注目。
５： Partition-2が残った空間（15029239808バイト＝14GB）を振り分けられている。

続いては `name: ubuntu-vg`の行に移動します。
この行からubuntu-vgと呼ばれるボリュームグループを定義してPartition-2 がその対象パーティションとなります。　`devices: [partition-2]`に注目。

`name: ubuntu-lv`の行からロジカルボリュームを定義され、サイズは
15028191232Bで (Bはバイト、約13.9GB）、Partition-2の14GBよりも少し小さく設定されています。おそらく、Partition-2と同じサイズを設定するとエラーが発生するかもしれません。

次の行からこのロジカルボリュームもext4としてフォーマットされることが伝わる。　`id: format-1`に注目。

最後の`path: /` と `path: /boot`から始まる行から, format-1のデバイスは　/　、 format-0のデバイスは　/boot　にマウントされる情報が伝わる。

基本的には`id: `エレメントがその対応するパーティションかデバイスの用法を教えてくれるというポイントを押さえておけば十分でしょう。

さて、ここから私はこのテンプレートに、新しくロジカルボリュームを追加し、それを/JTにマウントするように修正してみます。

まずは`ubuntu-lv`を10GBに縮みます。

```text:
- {name: ubuntu-lv, volgroup: lvm_volgroup-0, size: 10737418240B, wipe: superblock,
      preserve: false, type: lvm_partition, id: lvm_partition-0}
```

それから、新しいボリュームを定義します。

```text:
- {name: u-lv2, volgroup: lvm_volgroup-0, size: 4187593216B, wipe: superblock,
      preserve: false, type: lvm_partition, id: lvm_partition-1}
    - {fstype: ext4, volume: lvm_partition-1, preserve: false, type: format, id: format-2}
- {path: /JT, device: format-2, type: mount, id: mount-2}
```

修正後のautoinstall-user-dataはこのようになります。

```text:

#cloud-config
autoinstall:
  apt:
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://us.archive.ubuntu.com/ubuntu
    - arches: [default]
      uri: http://ports.ubuntu.com/ubuntu-ports
  identity: {hostname: ithost, password: $6$NPLmJFVMoi8QGjQr$7MWX45ajTNTpE3Ar33mquKzFUd62AZwkMjOxaNPwSuId41JSoeRGiN9/HKryS/RbR.UBDc.KBCYHDawWETJ320,
    realname: ub, username: ub20}
  kernel:
    kernel: {package: linux-generic}
  keyboard: {layout: us, toggle: null, variant: ''}
  locale: en_US.UTF-8
  network:
    ethernets:
      enp0s3: {dhcp4: true}
    version: 2
  ssh:
    allow-pw: true
    authorized-keys: []
    install-server: true
  storage:
    config:
    - {ptable: gpt, serial: VBOX_HARDDISK_VB8f97059d-a7457df4, path: /dev/sda, wipe: superblock,
      preserve: false, name: '', grub_device: true, type: disk, id: disk-sda}
    - {device: disk-sda, size: 1048576, flag: bios_grub, number: 1, preserve: false,
      grub_device: false, type: partition, id: partition-0}
    - {device: disk-sda, size: 1073741824, wipe: superblock, flag: '', number: 2,
      preserve: false, grub_device: false, type: partition, id: partition-1}
    - {fstype: ext4, volume: partition-1, preserve: false, type: format, id: format-0}
    - {device: disk-sda, size: 15029239808, wipe: superblock, flag: '', number: 3,
      preserve: false, grub_device: false, type: partition, id: partition-2}
    - name: ubuntu-vg
      devices: [partition-2]
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - {name: ubuntu-lv, volgroup: lvm_volgroup-0, size: 10737418240B, wipe: superblock,
      preserve: false, type: lvm_partition, id: lvm_partition-0}
    - {fstype: ext4, volume: lvm_partition-0, preserve: false, type: format, id: format-1}
    - {name: u-lv2, volgroup: lvm_volgroup-0, size: 4187593216B, wipe: superblock,
      preserve: false, type: lvm_partition, id: lvm_partition-1}
    - {fstype: ext4, volume: lvm_partition-1, preserve: false, type: format, id: format-2}
    - {path: /, device: format-1, type: mount, id: mount-1}
    - {path: /boot, device: format-0, type: mount, id: mount-0}
    - {path: /JT, device: format-2, type: mount, id: mount-2}
  updates: security
  version: 1
```
ここに少し注意してほしいところは

 1 . `identity: { }`のpasswordの値は、openssl のコマンドで生成できます。

```text:
openssl passwd -6 -salt xX9 12345678
```
この例で12345678の暗号化されたパスワードが生成された。

2 . 新しいボリュームのサイズに512で割り切れる値を設定するのがおすすめです。
そうしないと、実行時にエラーが出て、AutoInstall が中止してしまいます。



続いてはインストール用のseed.iso ファイルを作成します。

```text:

sudo apt-get install -y cloud-image-utils
mkdir ~/seed
sudo cp /var/log/installer/autoinstall-user-data ~/seed/user-data
mkdir ~/seed/meta-data
sudo cloud-locales ~/seed.iso ~/seed/user-data ~/seed/meta-data

```

作成されたseed.iso をMacBook Pro のローカルディレクトリにダウンロードしてから、VirtualBoxに新しいVMを作成し、seed.iso を第2のCDディクスにマウントします。

![VB1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2057805/8e152fac-49ca-569a-d11c-9996b5453057.png)

![VB2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2057805/69effeaa-c639-e01a-4a7a-48185e3e9508.png)

VirtualBox を起動します。コンソールにこのメッセージが表示されます。

```text:
Continue with autoinstall (yes|no)? 
```

うまくいったら、インストールが終了し、Ubuntu が再起動してから、SSHでログインします。

dh コマンドでパーティションを確認してみます。

```text:
df -lh  | egrep -v "tmpfs|loop[0-9]|udev"

/dev/mapper/ubuntu--vg-ubuntu--lv  9.8G  4.1G  5.3G  44% /
/dev/mapper/ubuntu--vg-u--lv2      3.8G   16M  3.6G   1% /JT
/dev/sda2                          976M  107M  803M  12% /boot
```

期待した結果がでてきました。

##要約
今回ご紹介した方法は、AutoInstallを使って、物理サーバーで自動的に
Ubuntuをインストールする方法でした。

本番環境ではディクスのレイアウトをカスタマイズすることがよくあるし、
ゼロからAutoInstallのuser-dataファイルの作成、デバッグは少し面倒だし、
個人的見解でとにかく「使えるテンプレート」を獲得し、アプリケーション環境に応じて修正を加えてから、確実に実行できる物を作成するのが最優先です。
あとは微調整するのはもう十分だと思います。

蛇足ですが、この記事に掲載したテンプレートを使われる場合、是非そのハードウェアに応じて修正をなさってください。例えば、テンプレートに使われた`/dev/sda`と`enp0s3`はVirtualBox が認識したデバイス名で、実際の場合｀/dev/xvda`と`enp0s8`になる可能性があるので、ぜひお使いのハードウェアを確認された上で
ごりようください。

##後記
Ubuntu と言ったら、それは私がまだLinux 初心者であった時の（今も素人。。。）練習用のOSでした。もともと私はkickstart を書こうと思ったが、突然にUbuntu はこれからどうなるかなという考えが頭に浮かんできたので、ついにUbuntu を選びました。

それに、皆さん、もしuser-dataファイルを再起動いらずにテストできる方法が
ご存知でしたら、ぜひお教えくださいね。

この記事の英語版はそのうちに公開するので、ご興味を持たれる方は少々お待ち下さい。

では、また次回に。