第458回ではUbuntuにおけるDockerのインストール方法を紹介しました。ところでDockerと同じコンテナ技術を利用したソフトウェアとして
LXDの上でDockerを使う
Dockerと同様にカーネルのコンテナ技術を利用したソフトウェアのひとつにLXDが存在します。Dockerがひとつのコンテナでひとつのアプリケーションを動かす
両者の具体的な違いを見ていきましょう。ちなみに個々の環境や運用方針によって成り立たないものもあります。オプションやツールを組み合わせることで変えられるものもあります。あくまで
- Docker
- 単一のコンテナには単一のサービスが動いている
docker run
で構築済みイメージをコンテナインスタンスとして実行する/sbin/
は実行されないinit - 個々のコンテナの設定は
docker run
コマンドの引数として渡す - イメージは
Dockerfile
によって構築する - 永続的なデータは
「データボリューム」 に保存する - ユーザーはコンテナインスタンスの中に入って操作することはない
CMD
で指定したプロセスが終了すればインスタンスは停止する- コンテナのrootはホストのrootと同じUIDが使われる
- マシン間のライブマイグレーションは将来的に対応予定
- コンテナはホストから名前空間の機能によって隔離されている
- Dockerコンテナの中でDockerコンテナを起動できる
- LXD
- 単一のコンテナの中に複数のサービスが動いている
lxc start
で構築済みイメージをコンテナインスタンスとして起動する/sbin/
は実行されるinit - 個々のコンテナの設定は設定コマンドを使ってメタデータファイルに保存する
- イメージはrootfsイメージとして構築する
- 永続的なデータはコンテナの中に保存する
- ユーザーはコンテナインスタンスの中に入って操作する
- コンテナの中で
shutdown
コマンドを実行すればインスタンスは終了する - コンテナのrootはホストのrootと異なるUIDが使われる
- マシン間のライブマイグレーションが実験的ではあるものの実装済み
- コンテナはホストから名前空間の機能によって隔離されている
- LXDコンテナの中でLXDコンテナを起動できる
使う上で一番大きな違いは、docker run
で実行することに なります。
それに対してLXDは、
実際のところLXDが比較されるべきはDockerよりもむしろ、
ところでLXDによって
LXDのインストールと初期設定
LXDはUbuntu公式のリポジトリにパッケージが用意されていますので、lxd
とそれを操作するツールであるlxc
がインストールされます。Dockerと同じような感じでlxc
コマンドを使うにはlxd
グループに所属する必要があります。ただしグループはインストール時に作成されますし、admin
グループとsudoers
グループのユーザーは自動的にlxd
グループに所属することになりますので、sudo
コマンドを使えるユーザーであれば単にインストール後に一度ログインしなおすだけでかまいません。
$ sudo apt install lxd
LXDを使うにはまず初期設定を行う必要があります。これはlxd
コマンドを使います。lxc
コマンドと混同しそうですが、lxd
コマンドを直接使うのはこのタイミングだけです。
$ sudo lxd init Name of the storage backend to use (dir or zfs) [default=zfs]: dir Would you like LXD to be available over the network (yes/no) [default=no]? Do you want to configure the LXD bridge (yes/no) [default=yes]? LXD has been successfully configured.
最初に設定するのがzfsutils-linux
パッケージがインストール済みの環境であれば、
BtrfsやLVMという選択肢もあります。特にBtrfsは機能の面から言えばZFSよりも便利なのですが、/var/
が存在するファイルシステム)
2つ目はLXDのサービスをネットワーク越しに操作できるかどうかの設定です。あとからでも設定変更可能ですので、
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_01.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_02.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_03.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_04.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_05.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_06.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_06.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_07.png)
![画像](/assets/images/admin/serial/01/ubuntu-recipe/0459/thumb/TH800_08.png)
これでLXDを利用できる環境が整いました。
$ lxc info apiextensions: - id_map apistatus: stable apiversion: "1.0" auth: trusted environment: addresses: [] architectures: - x86_64 - i686 certificate: | -----BEGIN CERTIFICATE----- (中略) -----END CERTIFICATE----- certificatefingerprint: e2deb928a0ab2192ab428b66ed6fe7802bf1809043bfcc8f01ef5a8dae77e849 driver: lxc driverversion: 2.0.6 kernel: Linux kernelarchitecture: x86_64 kernelversion: 4.4.0-62-generic server: lxd serverpid: 29207 serverversion: 2.0.8 storage: dir storageversion: "" config: {} public: false
Docker用コンテナの作成
では実際にDockerを動かすためのLXDコンテナを作成し、
LXD上でDockerを動かすためにはコンテナ作成時に
$ lxc init ubuntu:16.04 docker -p default -p docker $ lxc start docker $ lxc list +--------+---------+---------------------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+---------------------+-----------------------------------------------+------------+-----------+ | docker | RUNNING | 10.55.74.241 (eth0) | fdf5:4b0a:8212:503d:216:3eff:fe2e:c662 (eth0) | PERSISTENT | 0 | +--------+---------+---------------------+-----------------------------------------------+------------+-----------+
コンテナが起動したら、
$ lxc exec docker -- sed -i "s/archive.ubuntu.com/jp.archive.ubuntu.com/g" /etc/apt/sources.list $ lxc exec docker apt update $ lxc exec docker -- apt full-upgrade -y $ lxc exec docker -- apt install -y language-pack-ja $ lxc exec docker update-locale LANG=ja_JP.UTF-8 $ lxc exec docker timedatectl set-timezone Asia/Tokyo $ lxc restart docker
上記のようにexec
サブコマンドを使えば、lxc exec
を打つのは面倒ですので、/bin/
をexec
することでもコンテナの中に移動できますが、lxc file push
でホストのファイルをコンテナにコピーしてしまいましょう。
$ lxc file push ~/.ssh/id_rsa.pub docker/home/ubuntu/.ssh/authorized_keys $ lxc exec docker chown ubuntu: /home/ubuntu/.ssh/authorized_keys
もしGitHubにすでに公開鍵を登録済みであれば、ssh-import-id
を使ってGitHubからインストールする方法もあります。
$ lxc exec docker -- ssh-import-id -o /home/ubuntu/.ssh/authorized_keys gh:(GitHubのアカウント名)
さて次にDockerそのものをインストールしましょう。これについては第458回のlxc exec
を実行すると、
$ lxc exec docker -- apt install -y docker.io $ lxc exec docker getent group docker docker:x:116: $ lxc exec docker systemctl is-enabled docker enabled
ちなみにここまでの手順をCloud Initに任せたい場合は、lxc init
のあとlxc start
の前に次のコマンドを実行してください。
$ lxc config set docker user.user-data - < cloud.cfg
さて実際にDockerが動作しているか試してみましょう。
$ lxc exec docker docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 1.12.3 Storage Driver: overlay Backing Filesystem: extfs Logging Driver: json-file (中略) $ lxc exec docker docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 78445dd45222: Pull complete (中略) $ lxc exec docker docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 48b5124b2768 4 weeks ago 1.84 kB
簡単に動きましたね。このようにLXDを使えば、
Docker Composeによるマルチコンテナの管理
Docker Composeを使うと、
Docker ComposeはDocker本体とは別にインストールする必要があります。Ubuntuの公式リポジトリにもdocker-compose
パッケージが存在しますが、
今回はLXDコンテナの中でDockerを動かしているため、lxc exec
コマンド経由でコンテナの中にDocker Composeをインストールしています。ホストに直接インストールするなら、
$ lxc exec docker -- curl -L "https://github.com/docker/compose/releases/download/1.11.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ lxc exec docker -- chmod +x /usr/local/bin/docker-compose $ lxc exec docker -- docker-compose --version docker-compose version 1.11.1, build 7c5d5e4
Docker Composeはdocker-compose.
ファイルを作って、
version: '2' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_PASSWORD: wordpress volumes: db_data:
ホストで作ったdocker-compose.
をLXDコンテナの中にコピーします。LXDはlxd file
」wordpress
ディレクトリも作っています。
$ lxc exec docker -- sudo -u ubuntu mkdir /home/ubuntu/wordpress $ lxc file push docker-compose.yml docker/home/ubuntu/wordpress/
最後にDocker Compose経由でWordPressコンテナとMySQLコンテナを起動しましょう。詳細は省きますが、docker-compose up
」-d
」
$ lxc exec docker -- sh -c "cd /home/ubuntu/wordpress && docker-compose up -d" Creating network "wordpress_default" with the default driver Creating volume "wordpress_db_data" with default driver Pulling db (mysql:5.7)... 5.7: Pulling from library/mysql (中略) Status: Downloaded newer image for wordpress:latest Creating wordpress_db_1 Creating wordpress_wordpress_1 $ lxc exec docker -- sh -c "cd /home/ubuntu/wordpress && docker-compose ps" Name Command State Ports ------------------------------------------------------------------------------------- wordpress_db_1 docker-entrypoint.sh mysqld Up 3306/tcp wordpress_wordpress_1 docker-entrypoint.sh apach ... Up 0.0.0.0:8000->80/tcp
起動中のコンテナの状態はdocker-compose ps
」docker ps
」lxc list
」
$ lxc list docker -c 46 +--------------------------------+-----------------------------------------------+ | IPV4 | IPV6 | +--------------------------------+-----------------------------------------------+ | 172.18.0.1 (br-3b0ff7fa92ef) | fdf5:4b0a:8212:503d:216:3eff:fe2e:c662 (eth0) | | 172.17.0.1 (docker0) | | | 10.55.74.241 (eth0) | | +--------------------------------+-----------------------------------------------+
eth0
に割り当てられているアドレスにアクセスすれば、
- http://
10. 55. 74. 241:8000/ - http://[fdf5:4b0a:8212:503d:216:3eff:fe2e:c662]:8000/
DockerコンテナをLXDごとマイグレーション
LXDには実験的機能ではありますが、
- 停止中のコンテナを他のホストへ移動するマイグレーション機能
- 停止中のコンテナを他のホストへ複製するコピー機能
- 稼働中のコンテナを読み込み専用のコンテナとして保存するスナップショット機能
- スナップショットされたコンテナをリストアする機能
- 稼働中のコンテナを他のホストへ移動するライブマイグレーション機能
ライブマイグレーション機能は実際のところ、
このステートフルなスナップショットとリストアのために、
ただこのライブマイグレーション機能は実験的ということもあって、
そこで今回はライブマイグレーションではなく、
$ sudo apt install criu
ここからはリモート側のホストの名前を$
」serval$
」
まずはリモート側で、lxd init
」Would you like LXD to be available over the network
」no
」
serval$ lxc config set core.https_address [::]:8443 serval$ lxc config set core.trust_password (パスワード)
上記の例では、[::]
」
次にローカル側でもネットワークアドレスの紐付けを行い、[::]
」
$ lxc config set core.https_address [::]:8443 $ lxc remote add serval リモート側のアドレス 証明書のフィンガープリント: (中略) ok (y/n)? y serval の管理者パスワード: (リモート側で設定したパスワード) クライアント証明書がサーバに格納されました: serval
追加されたリモートのリストはlxc remote list
」
$ lxc remote list +-----------------+------------------------------------------+---------------+--------+--------+ | NAME | URL | PROTOCOL | PUBLIC | STATIC | +-----------------+------------------------------------------+---------------+--------+--------+ | images | https://images.linuxcontainers.org | simplestreams | YES | NO | +-----------------+------------------------------------------+---------------+--------+--------+ | local (default) | unix:// | lxd | NO | YES | +-----------------+------------------------------------------+---------------+--------+--------+ | serval | https://(リモートのアドレス):8443 | lxd | NO | NO | +-----------------+------------------------------------------+---------------+--------+--------+ | ubuntu | https://cloud-images.ubuntu.com/releases | simplestreams | YES | YES | +-----------------+------------------------------------------+---------------+--------+--------+ | ubuntu-daily | https://cloud-images.ubuntu.com/daily | simplestreams | YES | YES | +-----------------+------------------------------------------+---------------+--------+--------+
PROTOCOL
がlxd
」PROTOCOL
がsimplestream
」lxc init
」
PUBLIC
は認証なしにリモートに接続するかどうかのフラグです。イメージサーバーは認証なしに接続しますが、
lxc
コマンドはリモート名を明示的に指定することで、
(ローカルのコンテナ情報) $ lxc list +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | docker | RUNNING | 172.18.0.1 (br-3b0ff7fa92ef) | fdf5:4b0a:8212:503d:216:3eff:fe2e:c662 (eth0) | PERSISTENT | 0 | | | | 172.17.0.1 (docker0) | | | | | | | 10.55.74.241 (eth0) | | | | +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ (リモートservalのコンテナ情報) $ lxc list serval: +-------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +-------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | kaban | RUNNING | 172.18.0.1 (br-d2860119fbd1) | fd3b:f724:c6b0:f8f8:216:3eff:fee8:1f37 (eth0) | PERSISTENT | 0 | | | | 172.17.0.1 (docker0) | | | | | | | 10.241.13.124 (eth0) | | | | +-------+---------+--------------------------------+-----------------------------------------------+------------+-----------+
ちなみにkaban
コンテナでは、docker
コンテナと同様にDockerを動かしています。
ここまででマイグレーションの準備は完了です。さっそくリモートにあるkaban
コンテナを一旦停止して、
$ lxc stop serval:kaban $ lxc move serval:kaban kaban $ lxc start kaban
移動後にコンテナのリストを確認すると、
(ローカルのコンテナ情報) $ lxc list +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | docker | RUNNING | 172.18.0.1 (br-3b0ff7fa92ef) | fdf5:4b0a:8212:503d:216:3eff:fe2e:c662 (eth0) | PERSISTENT | 0 | | | | 172.17.0.1 (docker0) | | | | | | | 10.55.74.241 (eth0) | | | | +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ | kaban | RUNNING | 172.18.0.1 (br-d2860119fbd1) | fdf5:4b0a:8212:503d:216:3eff:fee8:1f37 (eth0) | PERSISTENT | 0 | | | | 172.17.0.1 (docker0) | | | | | | | 10.55.74.235 (eth0) | | | | +--------+---------+--------------------------------+-----------------------------------------------+------------+-----------+ (リモートservalのコンテナ情報) $ lxc list serval: +----------+---------+------+------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +----------+---------+------+------+------------+-----------+
今回のような