この記事は GRIPHONE Advent Calendar 2022 4日目の記事です。
サーバーサイドエンジニアをしております皆田です。
この記事では、仮想環境を気軽に試せてしまうMultipassについて、設定から使い方までを書いていこうと思います。
今、Multipassを触ってみる理由
現状、開発にはDockerが欠かせない状態です。
弊社でもWin/macでDocker Desktopを用いて開発している状態です。
お手軽にDockerを利用できるDocker Desktopは本当に便利なツールだと思います。
ただ、たまに同期にラグがあったりしてストレスをかかえることがありました。
私はこれまでWindowsで作業していたのですが、リモート業務になるに伴い、macにリプレイスして以降、WSLでubuntu上にdocker-ceを置いたときの速度が忘れられなくて、この状況から離脱し、OSによらない環境を作れたら理想的だなと考えるようになりました。
そんな中、技術記事を読んでいたときに『MultipassでDocker Desktopを抜け出した』という記事を見かけ、OSに依存せずLinux-vmの開発環境を確立できたら便利だろうなと思ってしまったのがキッカケです。
Multipassとは
公式そのままの説明を行うなら、『Linux, mac OS, WindowsでクラウドスタイルのUbuntu仮想マシンを生成するためのツールです』の一言につきます。
2020年に出てきた比較的新しいツールで、Docker Desktop有料化時に結構騒がれていたものです。
GUIを使わない人にとっては使いやすそうなツールです。
Multipassで利用可能なイメージたち
Ubuntuベースで現状使えるものは multipass find で確認可能です。
- Ubuntu 18.04 LTS / 20.04 LTS / 22.04 LTS
- Anbox Cloud Appliance
- charm-dev
- docker
- jellyfin
- minikube
本記事では Ubuntu 20.04 を用います。
基本的なコマンド
コマンド | 説明 |
multipass launch | 仮想マシンをローンチする |
multipass list | インスタンスをリスト表示する |
multipass shell [vm名] | vmのシェルに入る vmを抜けるにはexitと打ちます |
multipass exec [vm名] — [コマンド] | ワンライナーでのコマンド実行 |
multipass start [vm名] | インスタンスを開始する |
multipass suspend [vm名] | インスタンスを一時停止する |
multipass stop [vm名] | インスタンスを停止する |
multipass mount A B | マウントします ローンチコマンド実行時にオブションで –mount A:B としても同じ結果を得られます |
multipass delete [vm名] | インスタンスを削除する –all オプションで全てのインスタンスを削除可能です |
multipass recover [vm名] | deleteで削除したインスタンスを復元できます |
multipass purge | deleteしたインスタンスを完全に削除します 復元できなくなります |
※start/suspend/stopはVM名をスペースでつないで指定した複数のインスタンスを指定可能です。–allですべてのインスタンスを同時に操作することも可能です。
実際にMultipassでDockerを動かしてみる
目標
Docker for mac を離脱し、開発環境を整えるため、以下3点ができること
- 仮想環境でdockerを起動し、macからストレスなくdockerを起動できること
- ファイル配置さえ守っていればメンバーが同じことをすればVMアクセスに対する公開鍵設定も簡単である
- VMを壊しても何度でも簡単に現状復帰できる
もっと言うと検証用のローカルマシンの細かい設定やプロファイラが動くようにするなどあるのですが、記事の公開を考えると作業が間に合わず、載せることができませんでした。師走ですね・・・
インストール〜Docker起動まで
コマンド一覧は作ったので、実際の設定ファイルと起動までを列挙していきます。マシンの設定を行うためのファイル(cloud-config.yaml)を用意してあげればやりたいことはできるはず!ってことで。
1. インストール
dockerが既に入っているとうまく動作しないということがあったので、docker desktopを削除したりします。mac自体にdockerを入れている場合、以下コマンド実行していきます。
# Homebrew が入っている前提ですが、強制削除します
brew uninstall --force docker docker-machine docker-compose
# 新たにインストールしなおします
brew install multipass docker docker-compose
# インストールできたことを確認しておく
docker version
docker-compose version
multipass version
# ssh用の鍵を作っておく(メールアドレスは任意)
ssh-keygen -t rsa -b 4096 -C user_name@mail.co.jp -f ~/.ssh/multipass_docker
# 鍵のパーミッションを変更しておく
chmod 600 ~/.ssh/multipass_docker
chmod 600 ~/.ssh/multipass_docker.pub
2. multipassの仮想マシン用設定ファイルを作る
こちらはcloud-config.yamlに相当するファイルを作るためのスクリプトです。
#!/bin/sh
# このファイルはhomeディレクトリに作成して利用ください。
# 作成した.pubファイルを変数に読み込む(各自、パスを設定)
AUTHORIZED_KEYS=$(cat ~/.ssh/multipass_docker.pub)
# ヒアドキュメントでファイルを作成する
cat > ./multipass_docker.yaml << _EOF_
#cloud-config
locale: en_US.UTF8
timezone: Asia/Tokyo
package_upgrade: true
users:
- name: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
ssh-authorized-keys:
- ${AUTHORIZED_KEYS}
packages:
- docker
- avahi-daemon
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
runcmd:
- sudo curl -fsSL https://get.docker.com | sudo bash
- sudo systemctl enable docker
- sudo systemctl enable -s HUP ssh
- sudo groupadd docker
- sudo usermod -aG docker ubuntu
_EOF_
このスクリプトに実行権限をつけて、./make-multipass-docker-yaml.shなどとして実行しちゃいましょう。
SSHファイルがスクリプト内のファイル名で配置してあれば公開鍵を読み込んで設定してくれるようにできます。
3. ローンチ
スクリプトで作ったyamlファイルを指定してこのようなコマンドでローンチします。
multipass launch -c 4 -m 8G -d 20G -n ubuntu-docker 20.04 --cloud-init ~/multipass_docker.yaml
cpu数を4、メモリは8G、ストレージを20G、VM名をubuntu-dockerとし、ubuntu 20.04ベースで実行します。
ubuntu-docker内部のdocker設定はyaml内のruncmdで実行済みなので、ローンチはコレだけ。
ちょっと時間がかかります。
# ローンチの成否確認
multipass exec ubuntu-docker -- tail -1 /var/log/cloud-init.log
modules-final: SUCCESSと出ていれば成功しています。
※ローンチの成否に関わらずVMは出来てしまうということなので、multipass listのみの確認では不十分ぽいです
もし、ローンチしたマシンを消したい場合は以下コマンドで乱暴に全部消す!ってこともできます。
※deleteでゴミ箱に入れて、purgeで完全削除。allオプションでmultipassインスタンス全部という指定です
multipass delete --all --purge
4. SSH設定
ubuntu-dockerにSSH接続してみます。
ssh -i ~/.ssh/multipass_docker ubuntu@ubuntu-docker.local
# 接続できたらexitしましょう
~/.ssh/configを以下のように記述し、アクセスできるようにします。
※存在しないファイルの場合は同名でファイルを作ってください
Host ubuntu-docker.local
HostName ubuntu-docker.local
IdentityFile ~/.ssh/multipass_docker
User ubuntu
Port 22
鍵を利用してSSHアクセスできるか試してみます
# 念の為接続履歴を削除しておく
ssh-keygen -R ubuntu-docker.local
ssh ubuntu@ubuntu-docker.local
# 入れたらexitで抜けておきます
5. ホストOSのディレクトリをマウントする
macとVMをストレスフリーで操作したいのでマウントしておきます。
この操作は任意です。パスマッピングが楽になるのでマウントすることをおすすめされていました。
multipass mount /Users ubuntu-docker:/Users
multipass mount /private/tmp ubuntu-docker:/tmp
# マウント状況を確認する
multipass info ubuntu-docker
※macのtmpディレクトリはprivate内にあるため、このような記述になるとのこと
6. Dockerを準備する
Clientは別途インストールしてあげる必要があるらしいということで手順に従います。
ARCH=$(if [ "$(uname -m)" = "amd64" ]; then echo "amd64"; else echo "aarch64"; fi)
DOCKER_VERSION="20.10.21"
curl -sL https://download.docker.com/mac/static/stable/$ARCH/docker-$DOCKER_VERSION.tgz | tar xzv -C $HOME
# 上記curlを実行すると以下表示がされます。
x docker/
x docker/docker
x docker/cli-plugins/
x docker/cli-plugins/docker-buildx
※上記、実行して確認したところ、macのclientは20.10.18になってしまいましたが、ubuntu側は20.10.21でしたので20.10.18が正解かもしれないです
.zshrcにパス設定しておきます
echo '\nexport PATH=$PATH:$HOME/docker' >> $HOME/.zshrc
source ~/.zshrc
7. Docker Contextの切り替え
Docker Context を利用することで複数の Docker node を切り替えて利用できます。
コンテキストは任意の名前で、後から書き換えることもできるのでやってみましょう。jqコマンドをインストールしていないかたはbrewなどで予めインストールしておきましょう。
docker context create ubuntu-docker --docker "host=tcp://$(multipass info ubuntu-docker --format json | jq -r '.info["ubuntu-docker"].ipv4[0]'):2375"
docker context use ubuntu-docker
# 確認してみる
docker context list
これで準備完了です。
今までdocker desktopでやっていたことを試してみましょう。
docker-compose buildなど普通にできました。
※まだ開発環境としては正しく動く状況ではありませんが、今回はdockerを動かすことが目標だったのでここまで。
まとめ
うまくいった感はまだないのですが、いかがでしたでしょうか?
Docker Desktopの動作の重さに悩む人はまだまだ多いかと思います。
mutagenでの解決もアリですし、今回のように新しいVMツールを試してやろうとすることは時代の流れに乗り遅れないようにするためにも、どんどん遊んでみるべき!と思っています。
アドベントカレンダー2022はまだまだ序盤です。
明日の記事もお楽しみに!
参考にさせていただいたサイト
https://qiita.com/kozayupapa/items/ab686a2cfd0022411f64
https://zenn.dev/ww24/articles/7e576d6f01a366