[仮想化]Multipassで気軽にUbuntuサーバーを作ったり壊したりする

今回はCanonical社が開発しているVM管理ソフトのMultipassを紹介します。 個人的には数ステップの簡単なコマンドだけでVMを作ることができお手軽だと思います。 またハイパーバイザ型のVMのため、Dockerなどと異なりコンテナ用でないイメージが使えるという特徴もあります。
2021.06.11

今回はUbuntuなどの開発で有名なCanonical社が開発しているVM管理ソフトのMultipassを紹介したいと思います。 近いソフトではVagrantが挙げられます。

Multipassの特徴

個人的にはMultipassの特徴は次のような感じだと思います

  • クロスプラットフォーム
  • ハイパーバイザ型のVM
  • CLIのみのインターフェイス
  • cloud-initに対応
  • マシンイメージの一覧がカタログになっている

Linux、Windows、Macの3つのプラットフォームで動作します。 同じコマンドで複数のOS上で使えるのはありがたいです。

LinuxならKVM、WindowsならHyper-V、MacならHyperKitをバックエンドに使用して動きます。 ハイパーバイザを用いて仮想化を行っているためDockerなどとは異なり、コンテナ用ではないマシンイメージが使えるのがいいと思います。 systemdなどの設定を行いたい時などはDockerだと少し手間がかかってしまいます。

Amazon EC2などのサーバーでの作業をローカルで実験できるようにするというのが、大きな使用用途の一つらしく、CLIでのみ使用可能です。 なのでGUIが必要なアプリケーションを使用するのにはあまり向いてないと思います。

先述のように主にクラウド上のサーバーでの作業を意識しているため、cloud-initの使用が簡単です。 cloud-initはファイルによってサーバーの設定を行うためのツールです。

使用できるマシンイメージの一覧がコマンドで簡単に取得でき、ダウンロードも容易です。 最新のOSを楽に使えるのはいいですね。 ただ、現状Ubuntu系以外のイメージは提供されてないみたいです。

実際につかってみた

今回は以下の環境で実行しています。

  • multipass 1.6.2+mac
  • macOS Catalina 10.15.7

インストール

Linuxならsnapでインストールできるみたいです。

snap

sudo snap install multipass

Macならbrewもしくは公式ホームページから配布されているpkgファイルから。

brew

brew install --cask multipass

Windowsなら公式ホームページから.exeファイルをダウンロードしてください。

Ubuntu20.04 LTSを使ってみる

まずはVMインスタンスの立ち上げをしてみます。使用するイメージはUbuntu20.04です。

launchの際に何も指定しないとCPU Core 1, Memory 1G, Disk 5Gのインスタンスが出来上がります。 これらは引数で変更可能です。

Ubuntu 20.04のインスタンスを起動

$ multipass find # 使用できるイメージを検索
Image                       Aliases           Version          Description
snapcraft:core18                              20201111         Snapcraft builder for Core 18
snapcraft:core20                              20201111         Snapcraft builder for Core 20
snapcraft:core                                20210430         Snapcraft builder for Core 16
18.04                       bionic            20210604         Ubuntu 18.04 LTS
20.04                       focal,lts         20210603         Ubuntu 20.04 LTS
20.10                       groovy            20210604         Ubuntu 20.10
$ multipass launch 20.04 --name ubuntu20 # Ubuntu20.04をubutu20という名前のインスタンスで立ち上げる
Launched: ubuntu20
$ multipass ls
Name                    State             IPv4             Image
ubuntu20                Running           XXX.XXX.XXX.XXX     Ubuntu 20.04 LTS

無事立ち上げができたみたいなので、シェルに接続をしてディストリビューションの情報を確認してみましょう。

インスタンスのシェルに接続

$ multipass shell ubuntu20 # インスタンスのシェルに接続
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-74-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Thu Jun 10 10:34:44 JST 2021

  System load:             0.18
  Usage of /:              26.9% of 4.67GB
  Memory usage:            18%
  Swap usage:              0%
  Processes:               112
  Users logged in:         0
  IPv4 address for enp0s2: XXX.XXX.XXX.XXX
  IPv6 address for enp0s2: XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX


1 update can be applied immediately.
To see these additional updates run: apt list --upgradable


To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@ubuntu20:~$ lsb_release -a # ディストリビューションの情報を表示
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.2 LTS
Release:	20.04
Codename:	focal
ubuntu@ubuntu20:~$ exit
logout

シェルに接続し、Ubuntu 20.04が起動したことがわかったので作成したインスタンスを削除しましょう。 削除するにはstopdeletepurgeの順でコマンドを実行する必要があります。 delete状態ならrecoverで復旧可能です。

インスタンスを削除する

$ multipass stop ubuntu20 # インスタンスの停止
Stopping ubuntu20 |[2021-06-10T10:35:23.421] [error] [ubuntu20] process error occurred Crashed
$ multipass ls
Name                    State             IPv4             Image
ubuntu20                Stopped           --               Ubuntu 20.04 LTS
$ multipass delete ubuntu20 # インスタンスを削除可能状態に
$ multipass ls
Name                    State             IPv4             Image
ubuntu20                Deleted           --               Not Available
$ multipass purge # 完全に削除
$ multipass ls
No instances found.

個人的に便利だと思った機能

cloud-initでセットアップ

launchの際に--cloud-initでyamlファイルのパスを指定すればそれを用いて初期化してくれます。 以下ではNginxをセットアップしています。

cloud-init

$ multipass launch --name nginx --cloud-init cloud-init.yml  20.04
$ multipass ls
Name                    State             IPv4             Image
nginx                   Running           XXX.XXX.XXX.XXX     Ubuntu 20.04 LTS
$ curl XXX.XXX.XXX.XXX
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

cloud-initを使用すればSSHの公開鍵も設置できるので別ツールによるセットアップやVSCodeなどを利用した開発もしやすくなります。 以下はNginxをインストールし、公開鍵を設置するcloud-initファイルの例です。

cloud-init.yml

#cloud-config
repo_update: true
repo_upgrade: all

packages:
  - nginx

runcmd:
  - systemctl start nginx.service
  - systemctl enable nginx.service

ssh_authorized_keys:
  - your ssh public key

ホストマシンのファイルをマウントする

mountコマンドを使えばホストのディレクトリやファイルを起動中のインスタンスにマウントすることができます。 マウントの情報はinfoコマンドで確認できます。 マウントした際、UIDとGIDが自動で変換されるので便利です。 これが行われないとファイルを操作するときに権限周りで問題が起きることがおおいです。

mount

$ multipass mount /my/target/abs/path nginx
$ multipass info nginx
Name:           nginx
State:          Running
IPv4:           XXX.XXX.XXX.XXX
Release:        Ubuntu 20.04.2 LTS
Image hash:     XXXXXXXXXX (Ubuntu 20.04 LTS)
Load:           0.17 0.06 0.02
Disk usage:     1.4G out of 4.7G
Memory usage:   152.9M out of 981.3M
Mounts:         /my/target/abs/path => /my/target/abs/path
                    UID map: XXXX:default
                    GID map: XXXX:default

何も指定しないと、マウント対象の絶対パスでインスタンス上にマウントされます。 任意の場所にマウントしたい場合は下のように<インスタンス名>:<パス>の形式で指定しましょう。

特定の場所にマウント

$ multipass mount /my/target/abs/path nginx:/home/ubuntu/target

自分の環境(macOS)では以下のようなエラーが発生しましたが、次の画像のmultipassdにアクセス権を与えることで解決しました。

マウントエラー

$ multipass mount /my/target/abs/path nginx
mount failed: source "/my/target/abs/path" is not readable

他のコマンド

この記事では割愛しますが他にも便利なコマンドがあります。 詳しくはドキュメントを読んでください。 一応ここにhelpの実行結果に出てくる使用可能なコマンド一覧書いておきます。

help

$ multipass help
# 中略
Available commands:
  delete    Delete instances
  exec      Run a command on an instance
  find      Display available images to create instances from
  get       Get a configuration setting
  help      Display help about a command
  info      Display information about instances
  launch    Create and start an Ubuntu instance
  list      List all available instances
  mount     Mount a local directory in the instance
  networks  List available network interfaces
  purge     Purge all deleted instances permanently
  recover   Recover deleted instances
  restart   Restart instances
  set       Set a configuration setting
  shell     Open a shell on a running instance
  start     Start instances
  stop      Stop running instances
  suspend   Suspend running instances
  transfer  Transfer files between the host and instances
  umount    Unmount a directory from an instance
  version   Show version details

感想

気軽にUbuntu環境を使えるのはいいと思いました。cloud-initも使いやすく、クラウド環境でのセットアップをローカルで練習するのにはいいと思います。 あとはマウント周りの使い心地がいいです。UID、GIDの自動マッピングはありがたいです。

ただ、このインスタンスに外部からアクセスしようとするとルーティングなどを自分で行う必要があるらしくいです。 なので、これを使ってサーバーを公開するのには工夫が必要です。 あとはUbuntu以外のディストリビューションもカタログにあると嬉しいと思いました。

ただ、まだ新しめのプロダクトなのでこれからも便利になっていくと思います。 最新の情報やコントリビューションは以下のGithubリポジトリからどうぞ。

関連しそうな記事

参考文献