Multipass で Ubuntu 仮想環境を構築する

Ubuntu 開発でお馴染みの Canonical 社が開発している仮想環境構築管理ソフトの Multipass を使ってみました。

https://multipass.run/

Multipass

数ステップの簡単なコマンドで、ローカルに Ubuntu VM を構築することができます。
以下のような特徴があります。

環境

今回 Multipass を使ってみた環境は以下の通りです。
Homebrew はインストール済みの前提です。

インストール

% brew install --cask multipass

最新版 Ubuntu LTS を使ってみる

インスタンス起動

multipass launch コマンドで VM インスタンスを起動します。
--name オプションでインスタンス名を設定します。

% multipass launch --name ubuntu-latest
Launched: ubuntu-latest

multipass list コマンドでインスタンスの状態を確認します。

% multipass list  
Name                    State             IPv4             Image
ubuntu-latest           Running           192.168.XXX.XXX     Ubuntu 22.04 LTS

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

multipass shell コマンドで起動したインスタンスのシェルへ接続します。

% multipass shell ubuntu-latest
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-78-generic aarch64)
(省略)
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.2 LTS
Release:        22.04
Codename:       jammy
$ uname -a
Linux ubuntu-latest 5.15.0-78-generic #85-Ubuntu SMP Fri Jul 7 15:29:30 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
$ exit
logout

インスタンス停止/起動

multipass stop コマンドでインスタンスを停止します。

% multipass stop ubuntu-latest
% multipass list
Name                    State             IPv4             Image
ubuntu-latest           Stopped           --               Ubuntu 22.04 LTS

multipass start コマンドでインスタンスを起動します。

% multipass start ubuntu-latest
% multipass list
Name                    State             IPv4             Image
ubuntu-latest           Running           192.168.XXX.XXX     Ubuntu 22.04 LTS

インスタンス削除

インスタンスの削除は、multipass delete -> multipass purge コマンドで行います。
multipass delete コマンドでインスタンスを削除可能な状況 (Deleted) にして、multipass purge コマンドで完全削除します。
Deleted な状態であれば、multipass recover コマンドで復旧することが可能です。

% multipass stop ubuntu-latest
% multipass list
Name                    State             IPv4             Image
ubuntu-latest           Stopped           --               Ubuntu 22.04 LTS

% multipass delete ubuntu-latest    #State が 「Deleted」 (削除可能状態)になる
% multipass list                
Name                    State             IPv4             Image
ubuntu-latest           Deleted           --               Not Available

% multipass recover ubuntu-latest     #State が 「Deleted」 から 「Stopped」 に戻る(削除可能状態から復旧)
% multipass list                 
Name                    State             IPv4             Image
ubuntu-latest           Stopped           --               Ubuntu 22.04 LTS

% multipass delete ubuntu-latest
% multipass purge     #完全削除
% multipass list
No instances found.

cloud-init の使用

multipass launch 時に --cloud-init オプションで cloud-init で初期化することが可能です。
以下では、Timezone と Lacale の設定、sl パッケージをインストールする cloud-init 設定です。

cloud-init.yaml

#cloud-config
repo_update: true
repo_upgrade: all

timezone: Asia/Tokyo
locale: ja_JP.UTF-8

packages:
  - sl

上記の YAML ファイルを指定して、インスタンスを起動します。

% multipass launch --name ubuntu-latest --cloud-init /path/to/cloud-init.yaml
% multipass shell ubuntu-latest
$ timedatectl
(省略)
                Time zone: Asia/Tokyo (JST, +0900)
$ localectl
   System Locale: LANG=ja_JP.UTF-8
(省略)
$ which sl
/usr/games/sl

最新版 LTS 以外のインスタンス起動

multipass find コマンドで使用できるイメージが表示されます。
multipass launch 時にイメージ名を指定すれば、最新版 LTS 以外の Ubuntu を起動することもできます。

% multipass find
Image                       Aliases           Version          Description
20.04                       focal             20230731         Ubuntu 20.04 LTS
22.04                       jammy,lts         20230729         Ubuntu 22.04 LTS
23.04                       lunar             20230729         Ubuntu 23.04

Blueprint                   Aliases           Version          Description
anbox-cloud-appliance                         latest           Anbox Cloud Appliance
charm-dev                                     latest           A development and testing environment for charmers
docker                                        0.4              A Docker environment with Portainer and related tools
jellyfin                                      latest           Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media.
minikube                                      latest           minikube is local Kubernetes
ros-noetic                                    0.1              A development and testing environment for ROS Noetic.
ros2-humble                                   0.1              A development and testing environment for ROS 2 Humble.

Ubuntu 23.04 を起動します。
multipass exec は、インスタンスでコマンドを実行するコマンドです。

% multipass launch 23.04 --name ubuntu2304
Launched: ubuntu2304
% multipass list
Name                    State             IPv4             Image
ubuntu2304              Running           192.168.XXX.XXX    Ubuntu 23.04
% multipass exec ubuntu2304 -- lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 23.04
Release:        23.04
Codename:       lunar

Ubuntu 23.04 が起動しました。

感想

手軽に Ubuntu 環境が準備できるのはいいなぁと思いました。
cloud-init も使えるので、ある程度のプロビジョニングなら簡単にできるし、クラウド環境で cloud-init を使う際のテスト環境にもいいなと思いました。

https://multipass.run/multipass.run github.com

YAPC::Kyoto 2023 に参加した #yapcjapan

yapcjapan.org

2023/03/19 に開催された YAPC::Kyoto 2023 に参加してきました。
久しぶりにオフラインイベントに参加しました。
会場は、はてな創業の地*1京都リサーチパークでした。

キーノート

素晴らしいキーノートでした。
はてな創業時からの話とてもよかったです。
「モブ」と自虐的に話していましたが、一人のエンジニアがつよつよエンジニアになっていく物語は感動したし、 いろいろ悩んだりするけど自分なりに覚悟を決めてやっていくしかないなと再確認できました。

印象に残ったセッション

小さく始め、長く続けるOSS開発と貢献.

OSS へ貢献するというとすごくハードルが高い気がしていましたが、このセッションを聞いて気楽な気持ちで始めて大丈夫そうという気持ちになりました。
OSS 貢献したい気運が高まりました。

あの日ハッカーに憧れた自分が、「ハッカーの呪縛」から解き放たれるまで

事業の向かう先と自分の役割に、自分の will を重ね合わせるように行動する重要さを再認識しました。
テックリードスペシャリスト、エンジニアリングマネージャの役割が言語化できていて素晴らしかった。

権威DNSサービスへのDDoSとハイパフォーマンスなベンチマーカ

DNS の動作としては正常なので、いつ「水責め攻撃」されてもおかしくないので、非常に勉強になりました。
dnsdist 知りませんでした。

感想

YAPC 最高でした。
オフライン開催で大変だったと思いますが、運営の方々、スポンサーの方々ありがとうございました。
参加された皆さん、お疲れ様でした。

*1:建物は違うらしい

Run KVM in nested virtual environment of VitualBox

いまさら感はありますが、VitualBox で サポートされた Nested Virtualization を試してみました。
VirtualBox 6.0 で AMD CPU、VirtualBox 6.1 で Intel CPU での Nested Virtualization がサポートされました。

(VirtualBox 6.0.0)

(VirtualBox 6.1.0)

Nested Virtualization とは

Nested Virtualization とは、仮想マシンの中で Hypervisor を実行できる機能のことです。
簡単に言うと、仮想マシン入れ子です。
以下のレイヤが連携して動きます。

  • Level 0 layer (L0) : 実ハードウェア上で動作する Hypervisor
  • Level 1 layer (L1) : L0上で仮想マシンとして動作する Hypervisor
  • Level 2 layer (L2) : L1上で動作する仮想マシン

試してみる

今回使った環境は、以下の通りです。
VitualBoxVagrant はインストール済みという前提です。

$ sw_vers  
ProductName:    Mac OS X  
ProductVersion: 10.15.5  
BuildVersion:   19F101  
$ sysctl -a | grep brand_string  
machdep.cpu.brand_string: Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz  
$ vboxmanage | head -n 1  
Oracle VM VirtualBox Command Line Management Interface Version 6.1.10  
$ vagrant version | head -n 1  
Installed Version: 2.2.9  

レイヤは以下のような感じです。

L1 仮想マシン

Vagrant + VirtualBox を使用して、L1 仮想マシンとなる CentOS 7.8.2003 (centos/7) をインストールします。

(L0)$ vagrant box add centos/7
(L0)$ vagrant init centos/7

Vagrantfile を編集して、L1 仮想マシンで CPU 仮想化支援機能が有効になるように設定します。
また、Nested Virtualization はオーバーヘッドが大きいので、普段 VirtualBox仮想マシンを動かすよりもマシンリソースを多めにします。

config.vm.provider "virtualbox" do |vb|
  vb.cpus = "2"
  vb.memory = "2048"
  vb.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
end

仮想マシンを起動して、ssh ログインします。

(L0)$ vagrant up
(L0)$ vagrant ssh

CPU 仮想化支援機能フラグ (Intel CPU : vmx / AMD CPU : svm) が立っていることを確認します。

(L1)$ cat /etc/centos-release
CentOS Linux release 7.8.2003 (Core)
(L1)$ egrep '(vmx|svm)' /proc/cpuinfo 
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single tpr_shadow flexpriority fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single tpr_shadow flexpriority fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d

L2 仮想マシン

L1 仮想マシンKVM 環境を構築して、L2 仮想マシンを起動します。
今回は、Vagrant + Libvirt を使用して、L2 仮想マシンとなる Debian 10.4 (debian/buster64) をインストールします。

まず、L1 仮想マシンに、KVM 関連パッケージと Vagrant をインストールします。

(L1)$ sudo yum install -y qemu-kvm libguestfs libvirt libvirt-client libvirt-devel virt-manager virt-top virt-viewer virt-who virt-install bridge-utils nfs-utils
(L1)$ sudo yum install -y https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.rpm

libvirt グループに現在のユーザを追加します。

(L1)$ sudo gpasswd -a vagrant libvirt

Vagrant の provider として libvirt が使用できるように、vagrant-libvirt プラグインをインストールします。

(L1)$ vagrant plugin install vagrant-libvirt

L1 仮想マシンを再起動して、ssh ログインします。

(L0)$ vagrant reload
(L0)$ vagrant ssh

KVM に必要なカーネルモジュールが有効になっているか確認します。

(L1)$ lsmod | grep 'kvm'
kvm_intel             188688  0 
kvm                   636965  1 kvm_intel
irqbypass              13503  1 kvm

libvirt 用の box をダウンロードします。

(L1)$ vagrant box add --provider libvirt debian/buster64
(L1)$ vagrant box list
debian/buster64 (libvirt, 10.4.0)

L2 仮想マシンを起動して、ssh ログインします。

(L1)$ vagrant init debian/buster64
(L1)$ vagrant up --provider libvirt
(L1)$ vagrant ssh

L2 仮想マシンを確認します。

(L2)$ cat /etc/debian_version 
10.4
(L2)$ uname -a
Linux buster 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux

まとめ

VirtualBox の Nested Virtualization 機能を使用して、macOS -> CentOS 7.8.2003 -> Debian 10.4 という仮想マシン入れ子環境が構築できました。
L2 仮想マシンのパフォーマンスは確認していませんが、検証環境が簡単に準備できるようになって良いかもと感じました。

Vagrant assumes that this means the command failed! (Virtualbox 6.0.6 + Vagrant 2.2.4 + vagrant-vbguest 環境でのエラー)

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

 setup

Stdout from the command:



Stderr from the command:

bash: 行 4: setup: コマンドが見つかりません

vagrant up 時に上記のエラーが出た場合は、次の設定で VirtualBox Guest Addition の自動更新を無効にする。

Vagrant.configure("2") do |config|
  config.vbguest.auto_update = false
end

vagrant-vbguest doesn't work with vagrant-reload · Issue #333 · dotless-de/vagrant-vbguest · GitHub

Docker 入門(1) ~ Docker インストールから apache サービスが稼働しているコンテナの生成まで ~

とりあえず Docker 動かしてみる的な手順のまとめです。

環境

Docker for Mac を使います。
コンテナ側の OS は CentOS 7.6 です。

  • ホスト OS: macOS Mojava
  • Docker バージョン
    • docker: 18.09.2
    • docker-compose: 1.23.2
    • docker-machine: 0.16.1

Docker インストール

Homebrew*1 でインストールします。

$ brew install docker  
$ brew cask install docker  

Docker.app 初回起動時に Docker ID でのログインを求められます。

コンテナの生成

$ docker container run -it --name centos-base centos:7.6.1810 /bin/bash   

コンテナが起動すると、プロンプトが root@xxxxxxxxxxxx(container id) になります。

@コンテナ
# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

status が up なコンテナが起動しています。

@ホスト
$ docker container ls -a  
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
xxxxxxxxxxxx        centos:7.6.1810     "/bin/bash"         About a minute ago   Up About a minute                       centos-base

コンテナに httpd パッケージをインストール

OS を最新版にして、httpd をインストールします。

@コンテナ  
# yum check-update     
# yum update -y   
# yum install -y httpd   
# systemctl enable httpd.service   

Docker イメージの作成

httpd をインストールしたコンテナを Docker イメージ化します。
exit を実行して、コンテナを停止します。

@コンテナ
# exit

次のコマンドで Docker イメージ(centos:7.6.1810-httpd)を作成します。

@ホスト
$ docker container commit centos-base centos:7.6.1810-httpd   
$ docker images  
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              7.6.1810-httpd      xxxxxxxxxxxx        2 minutes ago       422MB

systemd に対応したコンテナの生成

これまではコンテナ生成時に /bin/bash を起動していましたが、systemd で httpd を起動するようにコンテナを生成します。
CentOS 7 では、/sbin/init が /lib/systemd/systemd へのシンボリックリンクになっているので、コンテナ生成時に /sbin/init を起動します。

@ホスト
$ docker container run -itd --tmpfs /tmp --tmpfs /run \   
-v /sys/fs/cgroup:/sys/fs/cgroup:ro --stop-signal SIGRTMIN+3 \   
--name centos-httpd -p 8080:80 centos:7.6.1810-httpd /sbin/init   
$ docker container ls -a   
CONTAINER ID        IMAGE                   COMMAND             CREATED              STATUS                   PORTS                  NAMES
xxxxxxxxxxxx        centos:7.6.1810-httpd   "/sbin/init"        About a minute ago   Up About a minute        0.0.0.0:8080->80/tcp   centos-httpd

今回はホストの 8080 ポートをコンテナの 80 ポートへマッピングしているので、ホスト (localhost) の 8080 へアクセスして、apache のデフォルトページが取得できることを確認します。

@ホスト
$ curl http://localhost:8080/   

systemd で起動したコンテナへのログインとコンテナ停止

コンテナ生成時に /sbin/init を起動しているので、最初に起動したコンテナのようにコンテナ側プロンプトが表示されません。
コンテナへログインしたい場合は、次のコマンドを実行します。

$ docker container exec -it centos-httpd /bin/bash

コンテナのプロンプト root@xxxxxxxxxxxx(container id) が表示されます。
コンテナからログアウトする場合は、[ control + p ] -> [ control + q] を押します。
コンテナを停止する場合は、コンテナへログインした状態で exit を実行します。

www.docker.com

*1:Homebrew は事前にインストールしてください。https://brew.sh/