Multipass が M1 Mac に対応#

Multipass は、コマンドラインで簡単に Ubuntu の VM を実行可能なソフトウェアです。 先日、Multipass がアップデートされ、M1 Mac に対応しました

これにより、M1 Mac 上でも簡単に Ubuntu の VM を起動できるようになりました。

Docker Desktop が有料になった#

2021年8月31日に、Docker は製品サブスクリプションの更新と拡張を発表しました。

個人開発者や教育、小規模なビジネスでは無料のサブスクリプションで Docker Desktop を使用できますが、大企業は Docker Desktop を使用するために有料のサブスクリプションが必要になりました。

私は、仕事でもプライベートでも Docker を使用しており、M1 Mac 上では Docker Desktop を使用しています。 私が所属する会社は小規模な会社ではありますが、大企業の子会社なので、Docker Desktop を使用しつづけるためには、有料のサブスクリプションが必要です。

元々この発表がされる前から、個人的に有料サブスクリプションを購入しており、また会社としても有料のサブクスリプションを購入することに問題はありません。

なので、Docker Desktop を使用しつづけても良いのですが、Multipass が M1 Mac に対応したというニュースを受け、Docker を Multipass の VM 上で動かしてみようと思いました。

Multipass のインストール#

公式サイトからインストーラーをダウンロードし、インストールします。

また、Homeberw でもインストール可能です。

$ brew install multipass

インスタンスの起動#

launch サブコマンドでインスタンスを起動できます。デフォルトでは、現在の Ubuntu TLS のインスタンスが起動します。

$ multipass launch --name foo

20秒ほどで、インスタンスの起動が完了します。

起動したインスタンス上でコマンドを実行するには、exec サブコマンドを使用します。

$ multipass exec foo -- lsb_release -a

インスタンス起動時に、cloud-init のメタデータファイルを渡すことも可能です。Multipass で cloud-init を使用するための詳細はこちらを確認してください。

$ multipass launch -n bar --cloud-init cloud-config.yaml

shell サブコマンドを使用すると、シェルを起動できます。

$ multipass shell foo

インスタンスの一覧は、list サブコマンドで表示できます。

$ multipass list

stop サブコマンドと start サブコマンドで、インスタンスの停止と開始ができます。

$ multipass stop foo bar
$ multipass start foo

不要なインスタンスをクリーンアップするには、delete サブコマンド、purge サブコマンドを使用します。

$ multipass delete bar
$ multipass purge

Multipass で起動する他のイメージを探すには、find サブコマンドを使用します。

$ multipass find

その他、コマンドの詳細は help サブコマンドを使用できます。

$ multipass help
$ multipass help <command>

Multipass の Ubuntu VM 上で Docker を動かす#

Multipass の Ubuntu VM 上で Docker を動かすには、特別なことは必要ありません。

公式の手順通りにインストールするだけで、Docker を使用可能になります。

私は、以下の cloud-init のメタデータファイルで、Docker 環境を構築しています。

# docker.yaml
users:
  - name: ubuntu
    ssh-authorized-keys:
      - ecdsa-sha2-nistp256 AAAAE....

package_update: true
package_upgrade: true
packages:
  - ca-certificates
  - curl
  - gnupg
  - lsb-release
  - avahi-daemon
runcmd:
  - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
  - apt-get update
  - apt-get install -y docker-ce docker-ce-cli containerd.io
  - gpasswd -a ubuntu docker

ubuntu という名前のユーザーを作成し、ssh の公開鍵を authorized-keys に追加するように設定しています。 avahi-daemon パッケージをインストールすることで、mDNS による名前解決ができるようになり便利です。 ubuntu ユーザーを docker グループに追加して、sudo 無しでも docker コマンドを実行できるようにします。

これを使用して、Ubuntu VM を起動します。

$ multipass launch -c 2 -d 10G -m 2G -n docker --cloud-init docker.yaml

必要に応じて、-c-d-m オプションにて、CPU数、ディスクサイズ、メモリーサイズを指定します。

しばらく待つと、VM の起動と初期化が完了します。

これで、Docker 環境を含む VM が起動できました。 docker コマンドを実行できます。

$ multipass exec docker -- docker version

Mac の docker-cli を使用する#

Mac にインストールされた docker-cli から、multipass の VM で動作する docker-engine を操作することができます。 普段 Mac 上で作業をする場合、そのほうが便利です。

Docker の CLI のみインストールするには、Homebrew で docker formula をインストールすれば良いです。

$ brew install docker

Mac の docker-cli と VM で動作する docker-engine の間は、SSH 経由で接続します。 Mac 上で SSH のキーペアを用意しておき、VM 起動時に cloud-init で SSH の公開鍵を追加しておきます。

あらかじめ、ssh で VM に接続し、ホストの指紋を確認しておきます。

$ ssh ubuntu@docker.local

あとは、DOCKER_HOST 環境変数に SSH 経由でアクセスするための設定を記述します。

$ export DOCKER_HOST="ssh://ubuntu@docker.local"

.bashrc.zshenv 等に記述しておくと良いでしょう。

これで、Mac にインストールされた docker-cli から、multipass VM 内の docker-engine を操作できるようになりました。

SSH を経由するので、Mac で docker コマンドを実行するときに若干のラグを感じますが、そこを気にしなければ普通に使用可能です。 Unix ソケット経由でアクセス可能な方法があれば改善できるかもしれませんが、現状未確認です。

まとめ#

長々と書きましたが、環境構築そのものは簡単に行えます。

Docker Desktop に不満があるわけではありませんし、Docker への有料サブスクリプションは購入を継続しますが、しばらくは Multipass の Docker 環境を使用してみようと思います。