Linux 使いになりたい人のための Vagrant と VirtualBox の設定(Ubuntu 22.04 編)
はじめに
Vagrant は、HashiCorp が開発している OSS(オープンソースソフトウェア)で、これを使うと仮想マシンの作成および管理を簡単にすることができます。
本記事では、Ubuntu 22.04 に Vagrant をインストールして使う方法について説明します。仮想マシンソフトウェアとしては VirtualBox を使用します。
Vagrant と VirtualBox をインストールするだけなら簡単にできます。そのため、筆者は Ubuntu 22.04 の apt パッケージで Vagrant と VirtualBox をインストールすれば、すぐに使えるだろうと思っていました。ところが、手元にあった Ubuntu 22.04 に VirtualBox 7.0 をインストール済みのマシンで、vagrant パッケージを追加インストールして使おうとしたところ、エラーが発生してしまい、動作しませんでした。ということで、同じように困っている人がいると思うので記事にすることにしました。
この問題を解決するには、次の2つの対応が必要でした。
- VirtualBox 7.0 に対応している Vagrant を使うこと
- Secure Boot への対応
これらのうち、2. の Secure Boot については、これを無効にして使えば、エラーは起こらなくなるのですが、セキュリティ的に安全性が低くなります。そのため、Secure Boot を有効にしたまま、対応することにします。
ここでは、Secure Boot を有効にしたまま、Vagrant と VirtualBox が使えるように Ubuntu 22.04 の設定をする方法について説明します。Vagrant と VirtualBox については、記事執筆時点で最新のものを使用します。
Vagrant とは
Vagrant は、HashiCorp が開発している OSS(オープンソースソフトウェア)で、これを使うと仮想マシンの作成および管理を簡単にすることができます。Vagrant を使うことで、開発環境の構築を自動化することができます。その結果、プロジェクトに参加する開発者が各自のパソコンに同じ環境を簡単に用意することができるようになります。このように、同じ開発環境での作業を前提とするプロジェクトでは、開発プロセスを円滑に進めることができるようになります。
Vagrant の主な特徴は次のとおりです。
- 仮想環境のプロビジョニング
- 高いポータビリティ
- 仮想環境の高い再現性
- 構成管理ツールのサポート
- 仮想環境用ネットワークの構成をサポート
Vagrant を使用すると仮想環境のプロビジョニングが簡単にできます。プロビジョニングとは仮想マシンの初期設定や設定管理をすることです。利用可能な仮想環境としては、Docker、VirtualBox、VMware などがあります。
Vagrant は高いポータビリティがあります。これは、Vagrantfile と呼ばれる設定ファイルを使用して仮想環境を定義するため、異なる開発者やマシン間で簡単に環境構築に必要な情報を共有できます。
Vagrant を使うと、仮想環境の高い再現性も手に入ります。同じ Vagrantfile を使用することで、環境構築に必要な情報を共有することができ、それを使って各自が同じ環境を手元に構築することができます。プロジェクトに参加する開発者全員が同じ環境で作業できるため、「自分の環境では動いているのに、他の環境では動かない」といった問題を回避できます。
ここで、Vagrant でのプロビジョニングにあたっては、構成管理ツールである Ansible、Chef、Puppet などが利用可能です。これらを使って、仮想マシンの設定を自動化できます。
また、Vagrant では仮想環境用のネットワークを構成する機能もあるため、仮想マシンのネットワーク設定を簡単に構成でき、ポートフォワーディングやプライベートネットワークなどの設定が可能です。
VirtualBox と Vagrant のインストール
それでは、ここで使用する VirtualBox と Vagrant をインストールしましょう。
VirtualBox のインストール
Linux での VirtualBox のインストールは Linux_Downloads – Oracle VM VirtualBox を参考にして行います。
最初に apt-get
コマンドがパッケージをダウンロードするときのリポジトリーの情報を登録するために、/etc/apt/sources.list.d/virtualbox.list
ファイルを作成します。スクリプトにしておいて、実行するのが確実でしょう。
GPG=oracle-virtualbox-2016.gpg
URL=https://download.virtualbox.org/virtualbox/debian
TARGET=$(lsb_release -cs)
cat << EOS | sudo tee /etc/apt/sources.list.d/virtualbox.list
deb [arch=amd64 signed-by=/usr/share/keyrings/${GPG}] ${URL} ${TARGET} main
EOS
これを実行します。内部で sudo
コマンドを実行しているので、実行時にアカウントのパスワードが要求されます。
sh ./install_apt_source_vbox.sh
次に、パッケージをダウンロードするときの検証に使う Oracle の公開鍵を登録します。正しい公開鍵を登録する必要があるので、きちんとチェックすることにします。
ここで、参考にした Oracle のダウンロードページに記載されている oracle_vbox_2016.asc
のフィンガープリントの値は次のとおりです。この値が更新されている場合は、この後に紹介するスクリプトは、その値を使うように修正してください。
B9F8 D658 297A F3EF C18D 5CDF A2F6 83C5 2980 AECF
Oracle Corporation (VirtualBox archive signing key) <info@virtualbox.org>
目視チェックは大変なので、check_fingerprint_vbox.sh.sh
スクリプトを用意して確認します。
wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc
x=$(LANG=C gpg --show-keys --with-fingerprint --keyid-format=short oracle_vbox_2016.asc | grep -e "Key" | awk -F '=' '{print $2}')
y=$(LANG=C gpg --show-keys --with-fingerprint --keyid-format=short oracle_vbox_2016.asc | grep -e "uid" | awk -F 'uid' '{print $2}')
echo $x > fingerprint_download.txt
echo $y >> fingerprint_download.txt
# <https://www.virtualbox.org/wiki/Linux_Downloads> に記載されているものを使用。
# ただし、`gpg` コマンドの出力に合わせて、`C18D 5CDF` は `C18D 5CDF` 修正。
cat << EOS > fingerprint.txt
B9F8 D658 297A F3EF C18D 5CDF A2F6 83C5 2980 AECF
Oracle Corporation (VirtualBox archive signing key) <info@virtualbox.org>
EOS
diff fingerprint.txt fingerprint_download.txt
if [ $? -ne 0 ]; then
echo "error"
fi
参考にする Oracle のダウンロードページ https://www.virtualbox.org/wiki/Linux_Downloads に記載されているものを使用しますが、gpg
コマンドの出力に合わせて、C18D 5CDF
は C18D 5CDF
と、空白を減らす修正をしてあります。
スクリプトを用意したら実行します。
sh check_fingerprint_vbox.sh.sh
フィンガープリントに差がない場合は、次のようになります。
$ sh check_fingerprint_vbox.sh.sh
← 何も表示されない
ちなみに、gpg
コマンドの出力に合わせた修正をしなかった場合は、次のように最後に error
という出力が出ます。とはいえ、上下に比較しやすく文字列が並ぶので、正しいものかどうかを確認するのは容易でしょう。
$ sh check_fingerprint_vbox.sh.sh
1c1
< B9F8 D658 297A F3EF C18D 5CDF A2F6 83C5 2980 AECF
---
> B9F8 D658 297A F3EF C18D 5CDF A2F6 83C5 2980 AECF
error
Oracle の公開鍵のフィンガープリントについて正しいことが確認できたら、gpg
コマンドでシステムへ登録します。ダウンロードしたファイルを使うなら下記のコマンドを実行します。
sudo gpg --yes --output /usr/share/keyrings/oracle-virtualbox-2016.gpg \
--dearmor ./oracle_vbox_2016.asc
ダウンロードと登録を同時にするなら下記のコマンドを実行します。
wget -O- https://www.virtualbox.org/download/oracle_vbox_2016.asc \
| sudo gpg --yes --output /usr/share/keyrings/oracle-virtualbox-2016.gpg --dearmor
以上で apt-get
コマンド用のリポジトリー登録が済んだので、apt-get
コマンドを次のように実行して VirtualBox 7.0 をインストールします。
sudo apt-get update
sudo apt-get install -y virtualbox-7.0
vagrant のインストール
Ubuntu 22.04 の apt-get
コマンドでインストールできる vagrant
コマンドは VirtualBox 7.0 に対応していないので、最新版をインストールします。インストール方法は、次の URL で説明されています。
このページを参考にして、ここでは VirtualBox のときと同じ順番で作業することにします。
まず、/etc/apt/sources.list.d/hashicorp.list
を作成するスクリプト install_apt_source_vagrant.sh
を用意します。
GPG=hashicorp-archive-keyring.gpg
URL=https://apt.releases.hashicorp.com
TARGET=$(lsb_release -cs)
cat << EOS | sudo tee /etc/apt/sources.list.d/hashicorp.list
deb [signed-by=/usr/share/keyrings/${GPG}] ${URL} ${TARGET} main
EOS
これを実行します。内部で sudo
コマンドを実行しているので、実行時にアカウントのパスワードが要求されます。
sh ./install_apt_source_vagrant.sh
次に HashiCorp の公開鍵を登録します。公式のインストール方法の説明ページで紹介されているスクリプトでは、HashiCorp の公開鍵については値が提示されていないので、正しい物が配布されていると信じて使うことにします。
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
リポジトリーの準備ができたら vagrant
パッケージをインストールします。
sudo apt-get update
sudo apt-get -y install vagrant
Secure Boot 対応
次に VirtualBox 7 について、Secure Boot 対応します。この対策をしないと、failed: modprobe vboxdrv failed. Please use 'dmesg' to find out why
といったエラーが表示されて vagrant
コマンドを使った仮想マシンの作成ができません。
対応について、参考にした URL は Ask Ubuntu にある次のページです。
Machine Owner Key (MOK) 機能を利用するにあたっては、openssl
や mokutils
といったコマンドを使います。
まずは、MOK 用のキーペアを作成します。スクリプトを用意して実行しましょう。
mkdir /root/module-signing
openssl req -new -x509 -newkey rsa:2048 \
-keyout /root/module-signing/MOK.priv \
-outform DER \
-out /root/module-signing/MOK.der \
-nodes -days 36500 -subj "/CN=n100.example.jp/"
chmod 600 /root/module-signing/MOK.priv
管理者権限が必要なので sudo
コマンドを使って実行します。
sudo sh ./generate_mok_keys.sh
ここで、openssl
コマンドの実行にあたり、Common Name (コモンネーム) の値に何を指定するか決めておく必要があります。通常はマシン名かマシンの FQDN を指定すれば良いです。Common Name は、/CN=n100.example.jp/
で指定していて、ここでは n100.example.jp
としてあります。
次に mokutil
コマンドで /root/module-signing/MOK.der
をインポート。このとき、直後の再起動時の認証に使うパスワード入力があります。ここで入力したパスワードは再起動後に必要なので覚えておきます。このパスワードは次回の再起動時のときだけ必要な一時的に使用するものなので、複雑なものにする必要はありません。
$ sudo mokutil --import /root/module-signing/MOK.der
[sudo] user001 のパスワード: ← sudo コマンドを実行したユーザー(ここでは user001)のパスワードを入力
input password: ← MOK 用パスワードを入力。入力しても表示されません
input password again: ← 直前に入力したパスワードを再入力。入力しても表示されません
次に、VirtualBox 関連のファイルを署名するスクリプト /root/module-signing/sign-vbox-modules.sh
を用意しておきます。
#!/usr/bin/env bash
SCRIPT_DIR=$(cd $(dirname $0); pwd)
cd ${SCRIPT_DIR}
for modfile in $(dirname $(modinfo -n vboxdrv))/*.ko; do
echo "Signing $modfile"
/usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
/root/module-signing/MOK.priv \
/root/module-signing/MOK.der "$modfile"
done
スクリプトを用意したら、実行可能にしておきます。
sudo chmod 700 /root/module-signing/sign-vbox-modules.sh
以上の準備ができたら、パソコンを再起動します。
すると、MOK manager EFI utility が実行されてセキュアブートの画面になります。画面内で、「Enroll MOK」を選択します。それから、インポートしたキーの確認をし、パスワード入力をしたら「continue」を選択します。すると、マシンの起動処理が進みます。
Ubuntu が再起動したら、用意してあった署名用のスクリプトを実行します。なお、この署名作業は、カーネルアップデート時に毎回必要となります。
sudo bash /root/module-signing/sign-vbox-modules.sh
これで、vboxdrv などに署名がされたので、これらがロードできることを確認します。確認するには modprobe
コマンドを使います。
sudo modprobe vboxdrv
問題がないようなら、Ubuntu を再起動します。これで、Vagrant から VirtualBox 7.0 が使えるようになりました。
Vagrant の使用
環境を用意したら、Vagrant を使ってみましょう。
Vagrant で仮想マシンを作成
作成する仮想マシンについては、Vagrant の box を使います。これは https://vagrantcloud.com/ で提供されていて https://vagrantcloud.com/search で検索することができます。
ここでは、generic/ubuntu2204
の box を使ってみます。
最初に Vagrantfile
を作成するために、vagrant init
コマンドを使います。vagrant 用のディレクトリー ${HOME}/vagrant
を作成してから Vagrantfile
を作成します。
mkdir -p ${HOME}/workspace/vagrant
cd ${HOME}/workspace/vagrant
vagrant init generic/ubuntu2204
これで、Vagrantfile
が作成されます。内容については、コメントを省略すると、次のような Ruby のプログラムになっています。
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu2204"
end
ここでは vagrant init
時に指定した generic/ubuntu2204
が config.vm.box
の値になっています。このことからわかるように、Vagrantfile
の config.vm.box
には使用する box を指定します。
Vagrant の仮想マシンを起動と SSH 接続
初期設定の Vagrantfile
の内容のままで良いので、仮想マシンを起動してみます。仮想マシンを起動するには vagrant up
コマンドを使います。これで、コマンド実行時のカレントディレクトリーにある Vagrantfile
を使って起動した仮想マシンが起動できます。
vagrant up --provider=virtualbox
起動した Ubuntu の仮想マシンには SSH 接続することができます。そのためには、vagrant ssh
コマンドを使います。これで、コマンド実行時のカレントディレクトリーにある Vagrantfile
を使って起動した仮想マシンに SSH 接続できます。
vagrant ssh
通常の ssh
コマンドを使うこともできます。その場合は、ポート番号 2222、仮想マシンのアカウントは vagrant を指定します。
ssh -p 2222 vagrant@localhost
パスワード認証のプロンプトが表示されるので、初期パスワードの vagrant
を入力します。すると、ログインできます。ログアウトするには exit
コマンドを使います。
vagrant$ exit
パスワード認証ではなく、公開鍵認証を使いたい場合は ssh-id-copy
コマンドを使って自分の公開鍵を登録します。
ssh-copy-id -i ~/.ssh/id_ed25519 -p 2222 vagrant@localhost
ここで、vagrant ssh
コマンドが使っている公開鍵認証用の秘密鍵は、Vagrantfile
のあるディレクトリーを ${VAGRANT_DIR}
とすると、${VAGRANT_DIR}/.vagrant/machines/default/virtualbox/private_key
にあります。この秘密鍵はパスフレーズがないので、これを使うと認証なしで ssh
コマンドで仮想マシンへ接続できます。
次のようなスクリプトを用意しておくと、役に立つことがあるでしょう。
#!/bin/sh
VAGRANT_DIR=$(cd $(dirname $0)/..; pwd)
OPT_KEY=${VAGRANT_DIR}/.vagrant/machines/default/virtualbox/private_key
ssh -i ${OPT_KEY} -p 2222 vagrant@localhost $@
ちなみに、ssh
コマンドは引数にリモートで実行するコマンドを指定できます。次の例では echo "hello vagrant"
のコマンドを実行しています。
$ ssh -p 2222 vagrant@localhost echo "hello vagrant"
hello vagrant
また、ファイルコピーにあたっては scp
コマンドが使えます。ポート番号は -P
オプションで指定します。実行例は次のようになります。
scp -P 2222 -r ../script/ vagrant@localhost:
仮想マシンの停止と削除
仮想マシンを停止するには vagrant halt
コマンドを使います。これで、コマンド実行時のカレントディレクトリーにある Vagrantfile
を使って起動した仮想マシンが停止されます。
vagrant halt
仮想マシンの状態を確認するには vagrant global-status
コマンドを使います。このコマンドを実行すると、仮想マシンの一覧表示ができます。実行例は次のようになります。
$ vagrant global-status
id name provider state directory
---------------------------------------------------
87c911d default virtualbox poweroff (略)/vagrant
仮想マシンを削除するには vagrant destroy
コマンドを使います。これで、コマンド実行時のカレントディレクトリーにある Vagrantfile
を使って起動した仮想マシンが削除されます。
vagrant destroy
削除する仮想マシンの id
を指定して、それを削除することもできます。この id
の値は、仮想マシンの一覧表示からわかります。
vagrant destroy 87c911d
Discussion