Docker + KVM 上で Xubuntu を動かす

# 動機

以下のような流れで、docker上のKVMで、Xubuntuを動かそうと試みました。
1. docker上で動く[xfce](http://www.xfce.org/?lang=ja)環境を構築しようとする
2. [gauthierc/dockerspicexfce4](https://hub.docker.com/r/gauthierc/dockerspicexfce4/)などを試すも、恒常的に使うのは辛そう [^1]
3. やっぱりデスクトップは仮想マシンにするか！
4. 失敗してもいいように、docker上でKVMを試そう


# 仮想デバイスを準備する

まず仮想マシンで利用する仮想ディスクを ホストに作成します。サイズは100GBです。

```sh
$ dd if=/dev/zero of=/mnt/vm/xubuntu/primary.raw bs=10M count=10k
$ ll -h /mnt/vm/xubuntu/primary.raw
-rw-rw-r-- 1 foo bar 100G Feb 14 20:16 /mnt/vm/xubuntu/primary.raw
```

次に、[Xubuntuのインストールイメージ](http://xubuntu.org/getxubuntu/)をダウンロードして 仮想ディスクと同じディレクトリに置きます。


```sh
$ wget http://ubuntutym2.u-toyama.ac.jp/xubuntu/14.04/release/xubuntu-14.04.3-desktop-amd64.iso
$ mv xubuntu-14.04.3-desktop-amd64.iso /mnt/vm/xubuntu/
```

# docker-compose.yml を記述する

[Docker Hub](https://hub.docker.com/)にて既存イメージを探したところ、[ianblenke/kvm](https://github.com/ianblenke/docker-kvm) が良さそうでしたのでこれを使わせてもらうことにします。

- コンテナを作成するだけでKVMの実行環境が整い、
- コンテナ作成時にパラメータを渡すと それがKVMのパラメータとして実行され、仮想マシンが作成される

という代物です。ありがたい。
必要なパラメータが多いので、docker run ではなく 最初からdocker-composeを使います。

```yaml:docker-compose.yml
xubuntu:
  image: ianblenke/kvm
  container_name: xubuntu
  tty: true
  privileged: true
  mem_limit: 600000000
  ports:
    - "5900:5900"
  volumes:
    - /mnt/vm/xubuntu:/mnt/vm/xubuntu
  command: "/run.sh  \
    -name xubuntu -smp 2 -m 512  \
    -vnc :0  \
    -k ja \
    -cdrom /mnt/vm/xubuntu/xubuntu-14.04.3-desktop-amd64.iso  \
    /mnt/vm/xubuntu/primary.raw"
```
コンテナが ```/dev/kvm``` と ```/dev/net/tun``` にアクセスするため、特権モード(privileged)を有効にします。また、仮想マシンはVNCを使って操作するため、5900番ポートを開けます。

run.sh のパラメータが そのままqemu-kvm のパラメータとして渡ります。各パラメータの意味は[こちら](http://manual.geeko.cpon.org/ja/cha.qemu.running.html)が参考になります。

# コンテナを作成し、仮想マシンにxubuntuをインストールする

```docker-compose up``` でコンテナ作成し、結果を確認します。

```sh
$ docker-compose up -d xubuntu
Creating xubuntu
$ docker-compose ps xubuntu
      Name             Command             State              Ports
-------------------------------------------------------------------------
xubuntu            /run.sh -name      Up                 3389/tcp, 0.0.0.
                   xubuntu -smp ...                      0:5900->5900/tcp
```

コンテナが作成されました。同時に仮想マシンも立ち上がっているはずなので、別のホストからVNCで繋いでみます。VNCの接続先として指定するのはホストのIPアドレスです。
![Install.png](https://qiita-image-store.s3.amazonaws.com/0/87156/84401be7-d0e0-78af-8bc1-c95ec7b8d11a.png)

Xubuntuのインストールイメージで仮想マシンが起動しています！ このまま仮想ディスクにXubuntuをインストールします。

(インストール作業は 他の環境と同じなので割愛)
![vnc.png](https://qiita-image-store.s3.amazonaws.com/0/87156/f0da6ed0-6922-44bc-0278-2dbeecb41ff4.png)

無事Xubuntuが起動するようになりました。Docker、KVM、Xubuntuのうちどれが寄与しているのかわかりませんが、とにかく起動が早いです。
Xubuntuをシャットダウンするとコンテナも停止します。Xubuntuをリブートしたときはコンテナは動作したままです。

# 仮想マシンの構成を変更する

インストールイメージがマウントされたままなので、これを仮想マシンの構成から外します。また、(個人的に)WAN越しにデスクトップを使うことが多いため、VNCでなく[SPICE](http://www.spice-space.org/)で仮想マシンを操作できるようにします。

```yaml:docker-compose.yml
xubuntu:
  image: ianblenke/kvm
  container_name: xubuntu
  tty: true
  privileged: true
  mem_limit: 600000000
  ports:
    - "5900:5900"
  volumes:
    - /mnt/vm/xubuntu:/mnt/vm/xubuntu
  command: "/run.sh  \
    -name xubuntu -smp 2 -m 512  \
    -spice port=5900,disable-ticketing \
    -vga qxl \
    -k ja \
    /mnt/vm/xubuntu/primary.raw"
```
-vncオプションを-spiceに変更し、-cdromオプションを削除しました。
また、-vgaオプションをデフォルトのstdからqxlに変更しています。[^2]
一旦コンテナを停止し、```docker-compose up -d xubuntu``` で再起動するとSPICEで接続できるようになりました。
![spice.png](https://qiita-image-store.s3.amazonaws.com/0/87156/3f46a4a6-d65d-baf5-eda3-34e8ef38eb53.png)

以上

[^1]: そもそも "恒常的に使う" "デスクトップ"を docker上で動かすのが少しズレてるんだと解釈しています。
[^2]: stdのままだと、WindowsのSPICEクライアント([virt-viewer](https://virt-manager.org/download/))でマウスカーソルが表示されなかったため qxlに変更しました