Multipass で Ubuntu 仮想環境を構築する
Ubuntu 開発でお馴染みの Canonical 社が開発している仮想環境構築管理ソフトの Multipass を使ってみました。
Multipass
数ステップの簡単なコマンドで、ローカルに Ubuntu VM を構築することができます。
以下のような特徴があります。
- クロスプラットフォーム (Linux/Mac/Windows) 対応
- Apple silicon (M1/M2) でも使える
- ハイパーバイザー型 VM (macOS では HyperKit (Intel) / QEMU (Apple silicon))
- cloud-init 対応
- CLI なインタフェース
環境
今回 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 を使う際のテスト環境にもいいなと思いました。
YAPC::Kyoto 2023 に参加した #yapcjapan
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)
- Virtualization core: support for nested hardware-virtualization on AMD CPUs
Changelog-6.0 – Oracle VM VirtualBox
(VirtualBox 6.1.0)
- Virtualization core: Support for nested hardware-virtualization on Intel CPUs (starting with 5th generation Core i, codename Broadwell), so far tested only with guest running VirtualBox
Changelog-6.1 – Oracle VM VirtualBox
Nested Virtualization とは
Nested Virtualization とは、仮想マシンの中で Hypervisor を実行できる機能のことです。
簡単に言うと、仮想マシンの入れ子です。
以下のレイヤが連携して動きます。
- Level 0 layer (L0) : 実ハードウェア上で動作する Hypervisor
- Level 1 layer (L1) : L0上で仮想マシンとして動作する Hypervisor
- Level 2 layer (L2) : L1上で動作する仮想マシン
試してみる
今回使った環境は、以下の通りです。
VitualBox と Vagrant はインストール済みという前提です。
$ 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
レイヤは以下のような感じです。
- L0 : macOS Catalina + VirtualBox
- L1 : CentOS 7.8.2003 + KVM
- L2 : Debian 10.4
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
(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
(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)
(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 を実行します。
*1:Homebrew は事前にインストールしてください。https://brew.sh/