仮想化機能

# 仮想化機能とは

仮想化機能は、物理的なマシン上で、仮想マシンを動かすためのソフトウェア機能、およびそれを助けるためのハードウェア機能の組み合わせ

# 仮想マシンの用途

* ハードウェアの有効活用 : 1台の物理マシン上で複数のシステムを動かす(IaaSなど)
* サーバの統合 : 複数の物理マシンで構成されているシステムの物理マシンを仮想マシンに置き換えて、より少ない数の物理マシンに集約する
* レガシーシステムの延命 : ハードウェアサポートが終わった古いシステムを仮想システム上で動かす
* あるOS上で別のOSを動かす
* 開発・テスト環境 : 業務システム環境と同じ、または似た環境を物理マシンなしに構築する

# 仮想化ソフトウェア

仮想マシンは、物理マシン上に存在する仮想化ソフトウェアが生成、管理および廃棄をする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/0c8f6a6e-8042-a7da-3eae-be7d3b298cec.png)

仮想化ソフトウェアは、物理マシン上のハードウェア資源を管理し、それを仮想マシンに分配する。物理マシン上のCPUを物理CPU(PCPU)、仮想マシン上のCPUを仮想CPU(VCPU)と呼ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/d7b00f96-c6c4-8796-059c-32d780834a17.png)

# 仮想化ソフトウェアの種類

仮想化ソフトウェアの実現は、物理ハードウェア上に直接ハイパーバイザと呼ばれる仮想化ソフトウェアをインストールするもの、既存OS上のアプリケーションとして動かすものなど色々ある。

* VMware社の各種製品
* Oracle社のVirtualBox
* MicrosoftのHyper-V
* Citrix System社のXen

# 仮想ソフトウェアの一例

ここでは以下3つを組み合わせて仮想マシンを作成、管理する。

* KVM(Kernel-based Virtual Machine) : Linuxカーネルが提供する仮想化機能
* QEMU : CPU,　ハードウェアのエミュレータ。KVMと組み合わせて使う場合は、CPUのエミュレーション部分は使わない
* virt-manager : 仮想マシンの生成、管理、廃棄をする。(生成してから実行するのはQEMUが行う)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/d792ebe1-d198-392f-2b4f-6dfe6bac4cfe.png)

virt-managerとQEMUはLinuxカーネルから見るとただのプロセスに過ぎない。

## 仮想マシンの生成〜削除の流れ

1. virt-managerが新規仮想マシンの雛形を作成(CPU数、メモリ容量、その他搭載ハードウェアなど)
1. virt-managerが上記雛形をもとに仮想マシンを生成してQEMUを起動
1. QEMUがKVMと連携しつつ、仮想マシンを必要な数だけ動かす(途中に電源ON/OFFや再起動を挟む)
1. virt-managerが必要亡くなった仮想マシンを削除

## virt-mangerによる仮想マシンの操作

* 各仮想マシンに用意されたウィンドウから仮想マシンのディスプレイ出力を見る
* 上記ウィンドウ上でキーボード、マウスを用いて入力すると仮想マシンのキーボード、マウスが操作される
* 仮想マシンの電源ON/OFFや再起動をする
* 仮想マシンのデバイスを追加・削除する、isoファイルの仮想DVDドライブへの挿入・取り出し

:::note info
**Nested Virtualization**とは、仮想マシン上で仮想マシンを動かす機能。IaaSの仮想マシン上で、仮想マシンを作って開発やテストをする時に使用する。例えば、GCEの仮想マシン上で複数のマシンから構成される仮想データセンターを構築し、CIなどで使用できるようにする。
:::

## 仮想化を支援するCPUの機能

* ユーザモード : CPUがプロセスを動作させているとき(一部のリソースへのアクセスが制限される)
* カーネルモード : システムコールや割り込みが発生したとき(なんでもできる)

仮想化機能をサポートしているCPUではこれらの考え方を拡張している。

* VMX-root : 物理マシンの処理をしているとき
* VMX-nonroot : 仮想マシンの処理をしているとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/b61b39c1-852a-2076-85be-ed0d022dad00.png)

* VT-x : Intel社のCPUによる仮想化支援機能
* SVM : AMDのプロセッサのCPUによる仮想化支援機能

それぞれ機能はほぼ一緒だが、CPUレベルの命令セットが異なる。この違いをKVMが吸収する(カーネルによるハードウェア機能の抽象化の1つ)

以下コマンドでVT-xやSVMが有効になっているかを調べられる。出力が1以上であれば有効。０なら無効。CPU自身は仮想化機能があるが、BIOSによって無効化されている場合がある。

```sh
egrep -c '^flags.*(vmx|svm)' /proc/cpuinfo
```

## QEMU + KVMの場合

プロセスがシステムコールの発行を介して、あるデバイスのレジスタにアクセスするときを考える。

:::note info
**CPUによる仮想化機能が存在しない場合の仮想化**
仮想マシンを動かすには、仮想マシンからハードウェアにアクセスしたことを物理マシンが検出する必要がある。仮想マシン上で動作するカーネルなどの実行ファイルを書き換えてハードウェアアクセスすると、仮想化ソフトウェアに制御が渡るような方法がある。準仮想化、Para-virtualization。
:::

# 仮想マシンはホストOSからどう見えているか？

## CLIからの仮想マシンの作成

```shell-session:terminal
virt-install --name ubuntu2004 --vcpus 1 --cpuset=0 --memory 8192 --os-variant ubuntu20.04 --graphics none --extra-args 'console=ttyS0 --- console=ttyS0' --location http://us.archive.ubuntu.com/ubuntu/dists/focal/main/installer-amd64/
```

```shell-session:terminal
sudo apt install sysstat fio golang python3-matplotlib python3-pil fonts-takao jq openssh-server
```

`virsh`コマンド : 仮想マシンをCUIで操作するコマンド

`virsh dumpxml ubuntu2004`を叩くとvirt-managerで作成した仮想マシンに関するXMLが出力される。

`virsh edit`でXMLの編集ができる。

## 仮想マシンの起動

virt-managerから起動。もしくは、`virsh start`で起動。

```sh
virsh start ubuntu2004
```

`virsh list`でubuntu2004という仮想マシンが起動していることが和kる

```shell_session
virsh list
ps ax | grep qemu-system
```

## 複数マシンを立ち上げた場合

```shell_session
virt-clone -o ubuntu2004 -n ubuntu2004-clone --auto-clone
virsh start ubuntu2004
virsh start ubuntu2004-clone
ps ax | grep qemu-system
```

すると、qemu-system-x86_64プロセスが2つになっていることがわかる。

## 仮想マシンの削除

以下は`ubuntu2004-clone`を削除する。

```shell_session
virsh destroy ubuntu2004-clone
virsh undefine ubuntu2004-clone --remove-all-strage
```

:::note info
**IaaSにおけるオートスケールの仕組み**
`virsh`コマンドで、仮想マシンの作成、定義の変更、起動の操作は全てできる。`virsh`は内部で`libvirt`というライブラリを使い、操作している。
IaaSでのオートスケール(システムの負荷によって、システムに組み込む仮想マシン数を変更する機能)は、システムの負荷が変動したときにプログラムから仮想マシンを増減させることによって実現している。
:::

# 仮想マシンとストレージデバイス

仮想マシン上のストレージデバイスは、物理マシン上では、ファイル、あるいはストレージデバイスと関連づけらている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/9704b72e-7dea-05e6-8b7d-313b29dd0b5d.png)

以下のようにlibvirtの設定ファイルを見る。

```shell-session
virsh dumpxml ubuntu2004
```

設定ファイルに書かれた、ubuntu2004.qccow2が仮想ディスクを保持するファイルの名前。(ディスクイメージ)

# 参考文献

1. [［試して理解］Linuxのしくみ　―実験と図解で学ぶOS、仮想マシン、コンテナの基礎知識【増補改訂版】 | 武内 覚 |本 | 通販 | Amazon](https://www.amazon.co.jp/%EF%BC%BB%E8%A9%A6%E3%81%97%E3%81%A6%E7%90%86%E8%A7%A3%EF%BC%BDLinux%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF-%E2%80%95%E5%AE%9F%E9%A8%93%E3%81%A8%E5%9B%B3%E8%A7%A3%E3%81%A7%E5%AD%A6%E3%81%B6OS%E3%80%81%E4%BB%AE%E6%83%B3%E3%83%9E%E3%82%B7%E3%83%B3%E3%80%81%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98%E3%80%90%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88%E3%80%91-%E6%AD%A6%E5%86%85-%E8%A6%9A/dp/429713148X)