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/
技術書典6
技術書典6に行ってきました。
後日、何買ったか忘れてしまうので、購入した書籍の備忘録です。
- mixi Tech Note #1
- XFLAG Tech Note #2
- YOMOYAMA Book Vol.1
- Hatena Tech Book
- WANTEDLY TECH BOOK 6
- エムスリーテックブック#1
- showKsではじめるクラウドネイティブ開発
- 動かしながら学ぶSpinnaker入門
- 自作アプリをHelm化して簡単デプロイ
- k3sで始めるkubernetes
- KubernetesとGoで作るgRPC API
- Knativeの歩き方 KubernetesからServerlessを訪ねて
- コンテナ時代の個人Webサービスの作り方
- Pragmatic Terraform on AWS
- pospomeのサーバサイドアーキテクチャ2
- マンガでわかるDocker③ 〜AWS編〜
- 文Go
- Go といろんな技術をつまみ食い
- Goで学ぶGoogle Cloud Functions
- Go がだいすきになる本
結構買ったなぁという感じです。
簡単後払いが便利でした。
YAPC::Tokyo 2019 に行ってきた #yapcjapan
遅くなりましたが、去る 1/26(土) YAPC::Tokyo 2019 に参加してきました。
今回も良い YAPC でした。
以下、セッションの感想などなど。
Perl 6 でのアプリケーション開発と実用
インストールが簡単になっていたり、エコシステムも揃ってきているので、Perl 6 書きたい機運が高まりました。
Perl to Go
GOPATH の呪縛とパッケージ管理で挫折した組ですが、セッション聞いて Go 勉強しようと思いました。
Perl on Rails
「レールに乗せたい」という考え方は分かるなぁーという感じでした。
Perl プロダクトに Rails の便利機能を導入しているのは凄いなぁと思いました。
ログにやさしいDB設計
ログテーブルの設計難しい。
ログテーブル設計は、自分の中でこれといった答えがないので、いろいろ考えさせられるセッションでした。
Keynote
コミュニティへの貢献方法とか、非常に参考になる内容でした。
コミュニティとは「利用するもの」であり、かつまた「貢献するもの」
雑感
Perl 成分多めな YAPC でした。
Perl 利用者は減少傾向だと思うけど、Perl は便利だし、何より好きな言語なので使っていくだろうなぁと思いました。
tokuhirom さんの Keynote にあったように、気負わないでコミュニティに貢献していこうと思いました。
運営スタッフと関係者のみなさん、参加者のみなさん、ありがとうございました。