j3iiifn’s blog

ネットワーク、インフラ、プログラミングについての備忘録

Raspberry Piの初期設定をcloud-initで半自動化する

2年くらい稼働させっぱなしにしていたRasPiのSDカードが故障した。 もはやどんな設定を入れていたか忘れたし、次回壊れたときに構築し直すのも面倒くさい。 そこで、今流行りのInfrastructure as Codeってやつを試してみることにした。 細かい設定はAnsibleでやるとして、SSHできるようにまるまでのごく基本的な設定をcloud-initに設定させたい。 今回はcloud-initを使った初期構築方法を説明する。

環境

  • Raspberry Pi 2 Model B
  • ThinkPad X220
    • SDカードにUbuntuイメージを書き込むための作業端末。
    • Ubuntu 16.04.5 Serverがインストールされている。

実現したいこと

  • RasPiにUbuntu 18.04.2をインストールすること
  • 初回起動時にcloud-initによって以下の項目が設定されること

手順

SDカードへの書き込み

https://wiki.ubuntu.com/ARM/RaspberryPi

Ubuntu公式サイトのこのページにRaspi用イメージがある。 Raspberry Pi 2: ubuntu-18.04.2-preinstalled-server-armhf+raspi2.img.xz (4G image, 302MB compressed) をダウンロードした。

同ページのInstallationに書いてあるコマンドをそのまま打って、イメージをSDカードに書き込んだ。4分半かかった。 デバイス/dev/mmcblk0sudo parted -l で調べられる。

x220:~$ time xzcat ubuntu-18.04.2-preinstalled-server-armhf+raspi2.img.xz | sudo dd bs=4M of=/dev/mmcblk0
0+196993 records in
0+196993 records out
2361393152 bytes (2.4 GB, 2.2 GiB) copied, 271.332 s, 8.7 MB/s

real    4m31.348s
user    0m48.944s
sys 0m6.932s

書き込み後のSDカードのパーティションを確認しておく。

x220:~$ sudo parted -l /dev/mmcblk0
Model: SD SA16G (sd/mmc)
Disk /dev/mmcblk0: 15.6GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system  Flags
 1      4194kB  138MB   134MB   primary  fat16        boot, lba
 2      138MB   2360MB  2222MB  primary  ext4

2番目のパーティション(ルートファイルシステム)のサイズが約2GBになっているが、初回起動時にcloud-initが空き領域の末尾までパーティションをリサイズしてくれるので問題ない。

SDカードのマウント

ルートファイルシステム内のファイルを変更するために、作業端末(Ubuntuサーバ / ThinkPad X220)にマウントする。

※このパーティションファイルシステムext4であるため、WindowsMacではマウントできない。こういうときにUbuntuが載ってるPCがあると便利。VMでもいいけど。

x220:~$ sudo mkdir /mnt/raspi
x220:~$ sudo mount /dev/mmcblk0p2 /mnt/raspi/

cloud-initの設定

ここが本題。 /mnt/raspi/etc/cloud/cloud.cfg.d/999_my.cfg を次の内容で作成する。 これがRasPiが起動したときに /etc/cloud/cloud.cfg.d/999_my.cfg になる。

datasource_list: [None]

preserve_hostname: false
hostname: raspi

ntp:
  servers: [ntp.nict.jp]
timezone: Asia/Tokyo

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      dhcp6: no
      addresses: [192.168.0.10/24]
      gateway4: 192.168.0.1
      mtu: 1454
      nameservers:
        addresses: [192.168.0.1, 8.8.8.8, 1.1.1.1]

ssh_pwauth: False
password: ubuntu
chpasswd:
  expire: False

ssh_authorized_keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEA3FSyQwBI6Z+nCSjUU ...
    - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3I7VUf2l5gSn5uavROsc5HRDpZ ...

だいたい見ればわかるが、わかりづらい部分だけ補足しておく。

  • datasource_list: [None] : ssh_pwauth: False を効かせるために必要。ここのトラブルシューティングの様子→ /etc/cloud/cloud.cfg.d/hoge.cfg に書いた ssh_pwauth が効かない - j3iiifn’s blog
  • ssh_pwauth: False : SSHサーバーのパスワード認証を禁止する。
  • chpasswd: {expire: False} : 初回起動時にパスワードを強制的に変更させたかったのでこれをTrueにしてみたら、永遠にパスワードの変更を求められてログインできなくなってしまった。だから今回はFalseにして初回ログイン時に手動で変更する運用にしてみた。

SDカードのアンマウント

SDカードをアンマウントし、カードスロットからSDカードを抜く。

x220:~$ sudo umount /mnt/raspi

起動

Raspberry PiにSDカードを挿入して電源を入れる。 起動中に表示されるログを眺めると、cloud-initでIPアドレスが設定されたり、SSH公開鍵が登録されたりする様子が確認できる。 ログは /var/log/cloud-init.log に保存される。 あとは公開鍵認証でSSHログインできることを確認し、passwd コマンドでパスワードを変更しておく。

参考URL