はじめに

これは ドリコム Advent Calendar 2019の10日目です。
9日目は fukui_takanori さんによる、タスク記録をつけた話 です。

こんにちは、enzaプラットフォーム事業統括部でエンジニアをやっている廣田です。
去年のアドベントカレンダーでもRaspberry Piについての記事を書かせていただいたのですが、今年もまたRaspberry Piで遊びたいと思います。

現在enza開発チームではチャットインターフェースを使った業務効率化、いわゆるChatOpsを進めようとしており、そのスタートとしてSlackクローンであるMattermostを導入してみることになりました。
僕はMattermostのセットアップの調査をすることになったので、以下で構築するオレオレsandbox環境に実際にインストールして軽く動くことが確認できるところまでやってみたいと思います。

ちなみに社内アクセス用のインフラはAWSのEKSを使って管理する予定なので、おそらくオレオレSandboxの知見はほぼなにも活かされないことでしょう…
そもそもRaspberry piのスペックで現実的にチャット捌けないですからね…

技術選定

Raspberry Pi 3 Model B

去年と同じく3 Model Bです!
本当は4が使いたかったのですが技適対応版が流通しだす頃にはもうこの記事の締め切りが迫っていたので…
TwitterでRaspberry Pi 4が届いた! という投稿を横目にこの記事を書いています。
そういう時間軸です。

Ubuntu Server 18.04 LTS (ゲストOS) / Arch Linux (ホストOS)

今回インストールするのはMattermostだけですが、せっかく作るオレオレSandbox環境なら今後もスクラップ & ビルドができる環境にしておきたいものです。
使っているうちに環境が汚れていくのは避けたいので、軽量なArch LinuxをホストOSとして、その上でMattermostをインストールするためのゲストOSとしてUbuntu Serverを建てるという構成にします。
Raspberry Pi 3 Model Bは仮想マシンの高速化ができるKVMに対応しているので無茶な構成ではないはずです。

オレオレSandboxの構築

まずはオレオレSandbox環境 (Ubuntu on Arch Linux on Raspberry Pi) を作るところからです

Arch Linuxのインストールディスクの作成

Raspberry Piはmicro SDからOSを起動するので、自分のPCにmicro SDを繋いでインストールディスクを作っていきます。
インストールディスクの作成はArch Linuxの公式ドキュメントが大変参考になります。
Arch Linux Wikiに日本語版もあります。
基本この通りに進めていけばOKでした。
ドキュメントでは2種類のルートファイルシステムが提示されていますが、Raspberry Pi 3は64bit対応なのでAArch64の方を使っています (RAMは1GBしかないのですが…)。

個人的な注意点は
  • インストールにLinux環境が必要
  • ファイルの展開にbsdtar 3.3+が必要
の2点です。

Linuxが必要になるのはディスクの作成途中にext4のパーティションの作成・マウントが必要になるためです。
ext4とはLinuxで使われるファイルシステムのことです。
今回は個人的に使っているUbuntu 18.04 LTSでいいやと思ったのですが、結論19.10にupgradeしました。
これは落としてきたファイルの展開にbsdtarの3.3以上が必要だったからです (参考)。
Ubuntu 18.04のbsdtarは惜しくも3.2なのですが、19.04以降は3.3になったのでOSのアップグレードをしました (参考)。

Raspberry PiにArch Linuxをインストール

インストールディスクが完成したらmicro SDをRaspberry Piにさして、LANケーブルを繋いだのちに電源に繋げましょう。
Raspberry Piは電源ボタンのようなものはなく、電源に繋ぐと自動的に起動します。
Arch Linuxは起動すると特に初期設定もなくSSH接続できるようになるので、適当なモニタでコンソールが立ち上がったのを確認したら、あとはいつものPCから作業できます。
初期ユーザー・パスワード共にalarmでログイン可能です。
 # ssh alarm@xxx.xxx.xxx.xxx
alarm@192.168.3.6's password: 
以降の作業はしばらくはrootユーザーで行います。
初期パスワードはrootです。 先ほどの英語ドキュメントに書いてあったpacmanの初期化はここで行います。
 pacman-key --init
pacman-key --populate archlinuxarm 
余談ですがpacmanはArch Linuxのパッケージマネージャーです。
macでいうところのhomebrew、Ubuntuでいうところのaptです。
なんだか可愛らしい名前ですね。
パッケージのアップデートをしたのちにsudoを入れました。
Arch Linux、軽量とは聞いていたがsudoも入っていないとは…
 pacman -Syy
pacman -S sudo 
sudoを入れただけではユーザーが使える状態ではないので、visudoでファイルを1行だけ編集します。
 visudo
# %wheel ALL=(ALL) ALL の行をコメントアウト 
これで一旦の作業ができる環境は整いました。

Arch LinuxにQEMUをインストール

QEMUはCUIで使うエミュレーターで、GUIでいうところのVirtualBoxです。
インストールはこれもpacmanでOKです。
 sudo pacman -S qemu 
今回Raspberry Piで仮想環境を作ってみようという思いつきで最初に見つけたブログ記事とその記事で参考にされていた別の記事がよくまとまっていまして、ほぼそのままでUbuntu Serverの起動までできました。
今回Arch Linux上で動かすのに最低限必要な部分だけピックアップします。
 mkdir qemuarm64; cd qemuarm64

# Ubuntu Server 18.04のイメージをダウンロード
wget http://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-arm64.img

# 起動に必要なカーネルを取得するためイメージをマウント
sudo modprobe nbd max_part=63
sudo qemu-nbd -c /dev/nbd0 bionic-server-cloudimg-arm64.img
mkdir mnt
sudo mount /dev/nbd0p1 mnt

# 起動に必要なカーネルを作業ディレクトリにコピー
sudo cp mnt/boot/vmlinuz-4.15.0-70-generic ./
sudo cp mnt/boot/initrd.img-4.15.0-70-generic ./
sudo umount mnt
sudo qemu-nbd -d /dev/nbd0

# 起動に必要なカーネルの所有者を変更
sudo chown alarm:alarm *-generic 

QEMUでUbuntu Serverを起動、ネットワークの設定

以上でQEMUでUbuntu Serverの仮想環境を起動する準備は整ったので、まずは起動してみます。
 qemu-system-aarch64 -m 512 -cpu host -nographic -machine virt \
-kernel vmlinuz-4.15.0-70-generic \
-append 'root=/dev/vda1 rw rootwait mem=512M console=ttyS0 \
console=ttyAMA0,38400n8 init=/usr/lib/cloud-init/uncloud-init \
ds=nocloud ubuntu-pass=ubuntu' \
-drive if=none,id=image,file=bionic-server-cloudimg-arm64.img \
-initrd initrd.img-4.15.0-70-generic \
-device virtio-blk-device,drive=image \
-device virtio-net-device,netdev=user0 \
-netdev user,id=user0 \
-enable-kvm 
オプション多すぎですね…
KVMを有効化するための-enable-kvmオプションを忘れずにつけましょう。
5行目のubuntu-passで指定しているパスワードはUbuntu Serverの初期ユーザーubuntuのログインに必要なパスワードになります。
起動するとそのまま標準出力にUbuntu Serverの起動ログが流れるので、ログインを求められたら入力しましょう。

無事起動! してもまだ外部ネットワークから仮想環境にはアクセスができないので、ホストOSとゲストOSのネットワークを接続するためのブリッジを作成する必要があります。
ブリッジを作成するためのパッケージと、ネットワーク編集のためのパッケージをインストールします。
 sudo pacman -S netctl
sudo pacman -S networkmanager
sudo systemctl start NetworkManager 
ブリッジ追加・削除のスクリプトは先に紹介させていただいたブログのものが、IPアドレスだけ編集してそのまま使えました。

ブリッジ追加スクリプトを流すとネットワーク設定が書きかわりSSHが切れるので、再接続したのち再度qemuで仮想環境を起動します。
作成したブリッジを立ち上げるためのスクリプト/etc/qemu-ifupと、仮想環境を閉じた際にブリッジを落とすスクリプト/etc/qemu-ifdownは多くの環境ではデフォルトで用意されているようですが、軽量なArch Linuxにはもちろんないのでそれぞれ自前で用意します。

/etc/qemu-ifup
 #!/bin/sh

echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /usr/bin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /usr/bin/brctl addif br0 $1 sleep 2 
/etc/qemu-ifdown
 #!/bin/sh

echo "Executing /etc/qemu-ifdown"
sudo /usr/bin/ip link set $1 down
sudo /usr/bin/brctl delif br0 $1
sudo /usr/bin/ip link delete dev $1 
どちらもArch Linux WikiのQEMUのページを参考にしています。
それぞれのファイルのパーミッションを設定するのを忘れずに。
 sudo chown root:kvm /etc/qemu-ifup
sudo chmod 750 /etc/qemu-ifup
sudo chown root:kvm /etc/qemu-ifdown
sudo chmod 750 /etc/qemu-ifdown 
ここまできたら再度qemuコマンドを下記に変更して実行します。
今回はブリッジに接続するためにsudoで実行している点に注意してください。
 sudo qemu-system-aarch64 -m 512 -cpu host -nographic -machine virt \
-kernel vmlinuz-4.15.0-70-generic \
-append 'root=/dev/vda1 rw rootwait mem=512M console=ttyS0 \
console=ttyAMA0,38400n8 init=/usr/lib/cloud-init/uncloud-init \
ds=nocloud ubuntu-pass=ubuntu' \
-drive if=none,id=image,file=bionic-server-cloudimg-arm64.img \
-initrd initrd.img-4.15.0-70-generic \
-device virtio-blk-device,drive=image \
-device virtio-net-device,netdev=tap0 \
-netdev tap,id=tap0,script=/etc/qemu-ifup \
-enable-kvm 
これでゲストOSが起動すれば無事SSHで接続することができます!
 ssh ubuntu@xxx.xxx.xxx.xxx 

Mattermostのインストール

仕事的にはこちらが本編なのですが…
正直アドベントカレンダーの本編はもう終了しました。
公式ドキュメントがしっかりしているので、やることに関して特に迷うところはありません。
唯一にして最大の注意点は、Mattermostの公式はamd64にしか対応していないので、Raspberry Piのarm64環境ではそのままではビルドできないことです。
とはいえarm64もマイナーな環境ではないので、有志の方が既にビルドしてくださっていたものを使いました。
ちなみにここからはもちろんUbuntuでの作業です!
 wget https://github.com/SmartHoneybee/ubiquitous-memory/releases/download/v5.17.1/mattermost-v5.17.1-linux-arm64.tar.gz 
ここに関してはドキュメント通りなので本当に書くことがなくて…
記事的にもいい長さかと思うので記念のスクショを貼って終わりにします。

最後に

個人的なやってみた系の記事でしたがいかがだったでしょうか。
Raspberry Piの小型ながらの性能には驚くばかりで、早く4も欲しくなりますね…
クラウド、コンテナが当たり前の環境になりつつありますが、改めてこうしてサーバー構築をするのも勉強になるのではないかと思います。
と思ったのですが、やはり個人的な趣味とかロマンとかそういうものですかね…業務的にはクラウドのコンソールとか使えるようになったほうが100倍役に立つでしょう…
とはいえ、今回構築してみてやりたいことも出てきました。
  • 長すぎるqemuコマンドどうにかしたい
  • シェルスクリプトでもいいけど、どうせならブラウザコンソール用意したい
  • dockerをインストールしたい
  • 別の仮想環境で別のWebアプリを動かしてみたい
などなど…
引き続き遊んでいきたいと思います。

明日は Smith さんの記事です。
ドリコムでは一緒に働くメンバーを募集しています!
募集一覧はコチラを御覧ください!