LXCをOpenStackから使ってみる

devstackを使って、どんな感じで動くのかやってみた。

# devstack

## LXCの有効化

`local.conf`に以下を記述すると、KVMからLXCに変わる。

```bash:local.conf
LIBVIRT_TYPE=lxc
```

novaのコンテナ操作もKVMと同じlibvirt経由となる。

## イメージの登録

自動でLXC用のイメージがダウンロードされ、Glanceに登録される。KVMとは違うイメージが登録されるようだ。

```text
$ glance image-show 3dc521a0-12c5-4241-9e74-b8a26b69dfb0
+------------------+--------------------------------------+
| Property         | Value                                |
+------------------+--------------------------------------+
| checksum         | b3d0a02042b91519b67277a50f63c769     |
| container_format | bare                                 |
| created_at       | 2015-10-05T02:05:25Z                 |
| disk_format      | raw                                  |
| id               | 3dc521a0-12c5-4241-9e74-b8a26b69dfb0 |
| min_disk         | 0                                    |
| min_ram          | 0                                    |
| name             | cirros-0.3.4-x86_64-rootfs           |
| owner            | 96c311fc81344743b970f98ec3cb8b2b     |
| protected        | False                                |
| size             | 25165824                             |
| status           | active                               |
| tags             | []                                   |
| updated_at       | 2015-10-05T02:05:26Z                 |
| virtual_size     | None                                 |
| visibility       | public                               |
+------------------+--------------------------------------+
```

## コンテナの起動

このイメージを使ってコンテナを起動できる。

```text
$ nova show test
+--------------------------------------+-------------------------------------------------------------------+
| Property                             | Value                                                             |
+--------------------------------------+-------------------------------------------------------------------+
| OS-DCF:diskConfig                    | AUTO                                                              |
| OS-EXT-AZ:availability_zone          | nova                                                              |
| OS-EXT-SRV-ATTR:host                 | gnome2                                                            |
| OS-EXT-SRV-ATTR:hostname             | test                                                              |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | gnome2                                                            |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000001                                                 |
| OS-EXT-SRV-ATTR:kernel_id            |                                                                   |
| OS-EXT-SRV-ATTR:launch_index         | 0                                                                 |
| OS-EXT-SRV-ATTR:ramdisk_id           |                                                                   |
| OS-EXT-SRV-ATTR:reservation_id       | r-zq0y58x4                                                        |
| OS-EXT-SRV-ATTR:root_device_name     | -                                                                 |
| OS-EXT-SRV-ATTR:user_data            | -                                                                 |
| OS-EXT-STS:power_state               | 1                                                                 |
| OS-EXT-STS:task_state                | -                                                                 |
| OS-EXT-STS:vm_state                  | active                                                            |
| OS-SRV-USG:launched_at               | 2015-10-05T02:25:38.000000                                        |
| OS-SRV-USG:terminated_at             | -                                                                 |
| accessIPv4                           |                                                                   |
| accessIPv6                           |                                                                   |
| config_drive                         | True                                                              |
| created                              | 2015-10-05T02:25:33Z                                              |
| flavor                               | m1.tiny (1)                                                       |
| hostId                               | 0f5a1966c1ecf8f1dbe349623ad14a2f7820be3194f3a9e09007bae3          |
| id                                   | 072123b6-f342-4944-990b-02e0b9147978                              |
| image                                | cirros-0.3.4-x86_64-rootfs (3dc521a0-12c5-4241-9e74-b8a26b69dfb0) |
| key_name                             | -                                                                 |
| locked                               | False                                                             |
| metadata                             | {}                                                                |
| name                                 | test                                                              |
| os-extended-volumes:volumes_attached | []                                                                |
| private network                      | 10.0.0.3                                                          |
| progress                             | 0                                                                 |
| security_groups                      | default                                                           |
| status                               | ACTIVE                                                            |
| tenant_id                            | 9cd7654cb5454706915d22e48856752b                                  |
| updated                              | 2015-10-06T02:00:32Z                                              |
| user_id                              | aced389ef0bc441197b674add536d1ba                                  |
+--------------------------------------+-------------------------------------------------------------------+
```

この辺はKVMの場合と変わらない。

```text
$ ssh 10.0.0.3 -lcirros
cirros@10.0.0.3's password:
$ ps
PID   USER     COMMAND
    1 root     init
   16 root     /sbin/syslogd -m 0
   18 root     /sbin/klogd
   69 root     udhcpc -p /var/run/udhcpc.eth0.pid -R -n -T 60 -i eth0 -s /sbin/cirros-dhcpc -O mtu -O staticroutes -x hostname test
  152 root     /usr/sbin/dropbear
  191 root     /sbin/getty 115200 tty1
  257 root     /usr/sbin/dropbear
  258 cirros   -sh
  262 cirros   ps
```

ちゃんとSSHもできる。

# ドメイン定義

```
virsh --connect lxc:/// dumpxml instance-00000001
```

virshを打つときには`--connect`でlxcを指定する必要がある。`/etc/libvirt/libvirt.conf`あたりにデフォルトの接続先設定に書いておくと、デフォルトをLXCにできる。

```xml
<domain type='lxc' id='699'>
  <name>instance-00000001</name>
  <uuid>072123b6-f342-4944-990b-02e0b9147978</uuid>
  <metadata>
    <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0">
      <nova:package version="13.0.0"/>
      <nova:name>test</nova:name>
      <nova:creationTime>2015-10-06 02:00:30</nova:creationTime>
      <nova:flavor name="m1.tiny">
        <nova:memory>512</nova:memory>
        <nova:disk>1</nova:disk>
        <nova:swap>0</nova:swap>
        <nova:ephemeral>0</nova:ephemeral>
        <nova:vcpus>1</nova:vcpus>
      </nova:flavor>
      <nova:owner>
        <nova:user uuid="aced389ef0bc441197b674add536d1ba">admin</nova:user>
        <nova:project uuid="9cd7654cb5454706915d22e48856752b">demo</nova:project>
      </nova:owner>
      <nova:root type="image" uuid="3dc521a0-12c5-4241-9e74-b8a26b69dfb0"/>
    </nova:instance>
  </metadata>
<memory unit='KiB'>524288</memory>
  <currentMemory unit='KiB'>524288</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <cputune>
    <shares>1024</shares>
  </cputune>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64'>exe</type>
    <init>/sbin/init</init>
    <cmdline>console=tty0 console=ttyS0</cmdline>
  </os>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/lib/libvirt/libvirt_lxc</emulator>
    <filesystem type='mount' accessmode='passthrough'>
      <source dir='/opt/stack/data/nova/instances/072123b6-f342-4944-990b-02e0b9147978/rootfs'/>
      <target dir='/'/>
    </filesystem>
    <interface type='bridge'>
      <mac address='fa:16:3e:41:10:67'/>
      <source bridge='qbr37347393-fe'/>
      <target dev='tap37347393-fe'/>
    </interface>
    <console type='pty' tty='/dev/pts/26'>
      <source path='/dev/pts/26'/>
      <target type='lxc' port='0'/>
      <alias name='console0'/>
    </console>
  </devices>
  <seclabel type='none'/>
</domain>
```

# ネットワーク

```text
$ sudo ovs-vsctl show
[sudo] password for ubuntu:
f845f7e9-5857-4133-82e2-ae85d7eb9e6a
    Bridge br-int
        fail_mode: secure
        Port "qr-1b5f5ada-9f"
            tag: 1
            Interface "qr-1b5f5ada-9f"
                type: internal
        Port "tapc69cdf38-d1"
            tag: 1
            Interface "tapc69cdf38-d1"
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port br-int
            Interface br-int
                type: internal
        Port "qvo37347393-fe"
            tag: 1
            Interface "qvo37347393-fe"
    Bridge br-ex
        Port br-ex
            Interface br-ex
                type: internal
        Port "br100"
            Interface "br100"
        Port "qg-7c652743-7f"
            Interface "qg-7c652743-7f"
                type: internal
    Bridge br-tun
        fail_mode: secure
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
        Port br-tun
            Interface br-tun
                type: internal
    ovs_version: "2.0.2"
```

neutronがOpen vSwitchにポートを作ってくれるので、そこにアタッチされるみたい。XMLの`interface`にOVSのポートが書かれている。このあたりもKVMと同じっぽい。

ちなみにこのOpen vSwitchの状態では、コンテナは外部と通信できないが、細かいことは気にしない。

# ファイルシステム

ちょっと気になることがあったので、詳細はこちらで別に書いた。
http://qiita.com/makisyu/items/dc88ec85af5d10dead92

コンテナ起動の流れを追うと
1. Novaが`qemu-nbd`を使って、QCOW2ディスクをNBDとして見せる
2. NovaがNBDをコンテナのrootfsにマウント
3. libvirtがコンテナを起動

なので、コンテナ内で`df`すると、

```text
$ sudo virsh --connect lxc:/// lxc-enter-namespace instance-00000001 --noseclabel /bin/df -h
Filesystem                Size      Used Available Use% Mounted on
devfs                    64.0K         0     64.0K   0% /dev
/dev/nbd7                22.2M     17.0M      4.1M  81% /
tmpfs                    64.0K         0     64.0K   0% /sys/fs/cgroup
tmpfs                     7.8G         0      7.8G   0% /dev/shm
tmpfs                   200.0K     64.0K    136.0K  32% /run
```

ホストのNBDが見えている。ホスト側では`qemu-nbd`がNBDを作っている

```text
$ ps -eFH | grep qemu-nbd
ubuntu   20148 20778  0  2615   936   0 08:25 pts/25   00:00:00           grep --color=auto qemu-nbd
root       402     1  0 200128 19432  2 02:00 ?        00:00:00   /usr/bin/qemu-nbd -c /dev/nbd7 /opt/stack/data/nova/instances/072123b6-f342-4944-990b-02e0b9147978/disk
```

このdiskはQCOW2

```text
$ qemu-img info /opt/stack/data/nova/instances/072123b6-f342-4944-990b-02e0b9147978/disk
image: /opt/stack/data/nova/instances/072123b6-f342-4944-990b-02e0b9147978/disk
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 1.7M
cluster_size: 65536
backing file: /opt/stack/data/nova/instances/_base/733137ff1173257fbd2dc691611bc44398018c66
Format specific information:
    compat: 1.1
    lazy refcounts: false
```

Backing fileはRAWなので、Glanceに登録されているのはrawファイルである。

```text
$ qemu-img info  /opt/stack/data/nova/instances/_base/733137ff1173257fbd2dc691611bc44398018c66
image: /opt/stack/data/nova/instances/_base/733137ff1173257fbd2dc691611bc44398018c66
file format: raw
virtual size: 24M (25165824 bytes)
disk size: 24M
```