LXD/LXCの設定方法とコンテナの立ち上げ方を記載します。
Table of Contents
1 LXD向けのパッケージ
LXD向けのパッケージとZFS向けのパッケージをインストールします。
$ sudo apt install -y lxd lxd-client lxd-tools criu $ sudo apt install -y zfsutils-linux $ sudo modprobe zfs
criuはコンテナのマイグレーションで使用されます。
ZFSはコンテナイメージの格納場所に使用されます。ZFSを使用しない場合はディレクトリ配下に格納されます。ZFSは専用のブロックデバイスがある場合に用いると良いでしょう。
2 LXDの初期化
lxdを対話形式で初期化します。lxd-bridgeも対話形式で初期化します。ZFSをブロックデバイスなしで使用した場合はファイルシステム上にzfs.imgが作成されます。
"Address to bind LXD to"はどのNICにlxdデーモンをListenさせるかを示します(0.0.0.0の場合はすべてのインターフェースに対してListenします)。
$ sudo lxd init Name of the storage backend to use (dir or zfs): zfs Create a new ZFS pool (yes/no)? yes Name of the new ZFS pool: tank Would you like to use an existing block device (yes/no)? no Size in GB of the new loop device (1GB minimum): 20 Would you like LXD to be available over the network (yes/no)? yes Address to bind LXD to (not including port): 0.0.0.0 Port to bind LXD to (8443 recommended): 8443 Trust password for new clients: Again: Do you want to configure the LXD bridge (yes/no)? yes Warning: Stopping lxd.service, but it can still be activated by: lxd.socket LXD has been successfully configured.
–autoオプションを用いれば対話不要で初期化できます。
$ sudo lxd init --auto \ --storage-backend zfs \ --storage-pool tank \ --storage-create-loop 20 \ --network-address 0.0.0.0 \ --network-port 8443 \ --trust-password password
ZFSを使わない場合は以下のとおりです。
$sudo lxd init --auto \ --storage-backend dir \ --network-address 0.0.0.0 \ --network-port 8443 \ --trust-password password
lxd-bridgeも対話不要で初期化出来ます。
$ sudo systemctl stop lxd-bridge $ sudo systemctl --system daemon-reload $ sudo su -c 'cat <<EOF > /etc/default/lxd-bridge USE_LXD_BRIDGE="true" LXD_BRIDGE="lxdbr0" UPDATE_PROFILE="true" LXD_CONFILE="" LXD_DOMAIN="lxd" LXD_IPV4_ADDR="10.202.80.1" LXD_IPV4_NETMASK="255.255.255.0" LXD_IPV4_NETWORK="10.202.80.1/24" LXD_IPV4_DHCP_RANGE="10.202.80.2,10.202.80.254" LXD_IPV4_DHCP_MAX="252" LXD_IPV4_NAT="true" LXD_IPV6_ADDR="" LXD_IPV6_MASK="" LXD_IPV6_NETWORK="" LXD_IPV6_NAT="false" LXD_IPV6_PROXY="false" EOF ' $ sudo systemctl enable lxd-bridge $ sudo systemctl start lxd-bridge
3 コンテナの作成
lxc launchでコンテナを作成します。コンテナの名前は.や_を用いることができません。
$ # lxc launch <image> <countainer> $ lxc launch ubuntu:16.04 ubuntu-16-04
イメージのダウンロードはLinux Containersのページのものを使うこともできます。私の環境だとダウンロード速度はLinux Containersのページの方が圧倒的に速いです。
images:<Distribution>/<Release>/<Architecture>
例えば、Debian 8なら以下のとおりです。
images:debian/jessie/amd64
リモートサーバのイメージ一覧は以下のコマンドで取得できます。
$ lxc image list <remote>:
デフォルトでアクセス可能なリモートサーバはimages, ubuntu, ubuntu-dailyです。イメージのサイズは100MByte程度です。
$ lxc image list images: $ lxc image list ubuntu: $ lxc image list ubuntu-daily:
3.1 Fedora 22/23のdnfで'Inappropriate ioctl for device'(回避策あり)
gpgcheckが上手く動作しません。
# dnf install -y <pkg> gpgme.GpgmeError: (7, 32870, 'Inappropriate ioctl for device')
–nogpgcheckオプションを使うことでインストールは完了できます。
# dnf install --nogpgcheck -y <pkg>
RedHatのbugzillaに一度teeを噛ませると直るという情報があります。イメージ作成方法が正しくないのか、dnfが作成方法の情報を記録しているのが悪いのか、今後の改善に期待です。
以下を実行すればlxc stopやUbuntu 16.04の再起動後でも–nogpgcheckオプションを使わなくてもエラーは発生しなくなります。
$ lxc exec images-fedora-23-amd64 -- dnf reinstall -y gzip | tee
あるいはコンテナで以下を実行します。
$ lxc exec images-fedora-23-amd64 -- /bin/bash # dnf reinstall -y gzip | tee
3.2 Debian jessieのpolicykit-1のインストールでフリーズ(回避策なし)
lxcとDebian jessieのsystemdの相性が悪いようです。Debian stretchのsystemdをインストールすれば一時的に問題を回避できますが、依存関係が少し壊れるのでおすすめできません。lxcかDebian jessie側で問題が解消されるまで待つしかないようです。
# apt install -y policykit-1 <snip> Setting up policykit-1 (0.105-8) ... <hung>
4 ネットワークの設定
コンテナのネットワークにはデフォルトでdefaultプロファイルのbridgedが使われます。
$ lxc profile list default docker $ lxc profile show default devices: eth0: name: eth0 nictype: bridged parent: lxdbr0 type: nic
4.1 defaultプロファイル(非推奨)
defaultプロファイルを用いた場合は内部ネットワークを形成します。lxd-bridgeでNATを実現しており、lxd-bridgeはdnsmasqを使用しています。複数の用途が異なるnameserverを用いてる場合は名前解決で問題が発生する場合があります。
4.1.1 複数のnameserverを使い分けてると名前解決できない
以下の/etc/resolv.confは192.168.11.2で内部ネットワークの名前解決をし、192.168.11.1でインターネットの名前解決を実行しています。
$ cat /etc/resolv.conf # Dynamic resolv.conf(5) file for glibc resolver(3) generated by # resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE # OVERWRITTEN nameserver 192.168.11.2 nameserver 192.168.11.1 search hiroom2.com
dnsmasqでも/etc/resolv.confを用いて名前解決を試みますが、一つのnameserverが名前解決ができないというREFUSEを返すと、そこで処理が停止しています。
lxd-bridgeではdnsmasqを–strict-orderで使用しており、一つ目のnameserverがREFUSEを実行すると以降のnameserverに問い合わせません。–strict-orderを用いない場合は複数のnameserverへ同時に問い合わせ、ひとつでもREFUSEを返すと名前解決は失敗します。
この問題を回避する為に、serverディレクティブとresolv-fileディレクティブを使用する必要があります。
serverディレクティブにてhiroom2.comの名前解決は192.168.11.2で実行し、新規に作成したresolv.confを読み込むdnsmasq.confを新規に作成します。
$ cat /var/lib/lxd-bridge/dnsmasq.conf server=/hiroom2.com/192.168.11.2 resolv-file=/var/lib/lxd-bridge/resolv.conf
resolv.confにはインターネット向けのnameserverを記載します。
$ cat /var/lib/lxd-bridge/resolv.conf nameserver 192.168.11.1
このdnsmasq.confをLXD_CONFILEで読み込みます。
$ diff -uprN /etc/default/lxd-bridge{.org,} --- /etc/default/lxd-bridge.org 2016-06-18 09:16:05.533082034 +0900 +++ /etc/default/lxd-bridge 2016-06-18 09:16:18.037062209 +0900 @@ -1,7 +1,7 @@ USE_LXD_BRIDGE="true" LXD_BRIDGE="lxdbr0" UPDATE_PROFILE="true" -LXD_CONFILE="" +LXD_CONFILE="/var/lib/lxd-bridge/dnsmasq.conf" LXD_DOMAIN="lxd" LXD_IPV4_ADDR="10.202.80.1" LXD_IPV4_NETMASK="255.255.255.0"
しかし、DHCPサーバから配布された情報を元に/etc/resolv.confを作成している場合は、DHCPサーバの配布情報が変わる度に上記のファイルを作り直す必要が出てきます。
4.1.2 動的にLXD_CONFILE向けのファイルを作成するパッチを適用
ほぼテストしていませんが、パッチを作成しました。lxd initの後で以下の手順を実行してdebファイルを作成してください。
lxdをビルドするためのパッケージをインストールします。
$ sudo apt install -y devscripts $ sudo apt-get build-dep -y lxd
lxdのソースコードをダウンロードしてパッチを当てます。lxdのソースコードのダウンロードができない場合は/etc/apt/sources.listのdeb-srcのコメントアウトを全て外してください。
$ mkdir lxd.ubuntu-16.04 $ cd lxd.ubuntu-16.04/ $ apt source lxd $ cd lxd-2.0.2
パッチを適用します。
$ GITHUB=https://github.com/hiroom2/lxd-pkg-ubuntu/commit $ wget ${GITHUB}/f9c429c8c7177ad1484cb2f6b3a17e5eeacf2442.patch $ patch -p1 < f9c429c8c7177ad1484cb2f6b3a17e5eeacf2442.patch $ echo "a.patch" | EDITOR=true dpkg-source --commit
lxdをビルドしてインストールします。
$ dpkg-buildpackage -us -uc $ sudo dpkg -i ../*.deb
/etc/default/lxd-bridgeでLXD_CONFILEを設定せずにLXD_GEN_CONFILE="true"を設定することでlxd-bridge起動時に/var/run/lxd-bridge/dnsmasq.confと/var/run/lxd-bridge/resolv.confが生成され、lxd-bridgeで使用されます。
$ sudo sed -i 's/^LXD_CONFILE/#LXD_CONFILE/g' /etc/default/lxd-bridge $ sudo su -c 'echo LXD_GEN_CONFILE="true" >> /etc/default/lxd-bridge' $ sudo systemctl restart lxd-bridge
4.2 macvlan(非推奨)
macvlanを用いることで外からアクセスできるようになります。ただしホストマシンとコンテナはアクセスできません。
$ lxc profile create vlan $ cat <<EOF | lxc profile edit vlan name: vlan config: {} description: VLAN profile devices: eth0: name: eth0 nictype: macvlan parent: ens3 type: nic EOF
ubuntu-16-04というコンテナにこのプロファイルを適用します。
$ lxc profile apply ubuntu-16-04 vlan
MACアドレスはlxc config showで確認できます。
$ lxc config show ubuntu-16-04 | \ grep volatile.eth0.hwaddr: | \ awk '{ print $2 }' 00:16:3e:0e:f6:38
192.168.11.0/24のネットワークで動作するDHCPサーバからMACアドレス00:16:3e:0e:f6:38へIPアドレスを配布できました。
$ lxc exec ubuntu-16-04 -- ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:16:3e:0e:f6:38 inet addr:192.168.11.86 Bcast:192.168.11.255 Mask:255.255.255.0 inet6 addr: fe80::216:3eff:fe0e:f638/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:70 errors:0 dropped:0 overruns:0 frame:0 TX packets:77 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:7192 (7.1 KB) TX bytes:9830 (9.8 KB)
4.3 bridged(推奨)
予めbridgeインターフェースを作成しておきます。これによりホストマシンからも別のマシンからもアクセスできるようになります。
br0を使うプロファイルを作成します。
$ lxc profile create bridge $ cat <<EOF | lxc profile edit bridge name: bridge config: {} description: Bridge profile devices: eth0: name: eth0 nictype: bridged parent: br0 type: nic EOF
5 コンテナをイメージにする
コンテナを停止した後、イメージにすることができます。
$ lxc stop ubuntu-16-04 $ lxc publish ubuntu-16-04 --alias ubuntu-16-04 Container published with fingerprint: fdd934c336bbd506c2f4f068a872ccd7504564b50d27d3a168a4835b6cfe4e96
イメージはexportすることができます。fdd934c336bbd506c2f4f068a872ccd7504564b50d27d3a168a4835b6cfe4e96.tar.gzというファイルが作成されます。
$ lxc image export fdd934c336bbd506c2f4f068a872ccd7504564b50d27d3a168a4835b6cfe4e96
exportしたイメージを他のマシンでimportすることができます。
$ lxc import fdd934c336bbd506c2f4f068a872ccd7504564b50d27d3a168a4835b6cfe4e96.tar.gz
6 リモートサーバの設定
sudo lxc initでLXDデーモンがListenするNICとポートを設定することで、他のマシンからLXDへアクセスできるようになります。以下のコマンドでNICとポートを変更できます。
$ lxc config set core.https_address 0.0.0.0:8443
以下のコマンドでパスワードを変更できます。
$ lxc config set core.trust_password password
他のマシンのLXDから以下のコマンドを実行します。
$ lxc remote add myimages 192.168.11.77:8443 Certificate fingerprint: c2e967e5d788db7fbbd19e1f22b789b74313083094bf5585334fe3d15192ab6a ok (y/n)? y Admin password for myimages: # type password Client certificate stored at server: myimages
6.1 イメージのダウンロード
images, ubuntu, ubuntu-dailyのようにダウンロードでます。
$ lxc image list myimages: <snip> ... b39919dbaf79 ... <snip>
$ lxc launch myimages:b39919dbaf79 container-from-myimages Creating container-from-myimages
6.2 コンテナのマイグレーション
ローカルマシンとリモートサーバにLXDの設定を含め、criuをインストールしておいてください。
$ lxc move images-centos-7-amd64 myimages: $ lxc list myimages: <snip> ... images-centos-7-amd64 ... <snip>