前回までで、lxc-start-ephemeralコマンドを紹介しましょう。
lxc-start-ephemeralコマンドは、lxc-start-ephemeralコマンドを実例にしてあわせて簡単に紹介したいと思います。
今回の例はUbuntu 14.
lxc-start-ephemeralコマンドの概要
lxc-start-ephemeralコマンドは、
既存のコンテナをベースにいろいろな作業を行うには、lxc-cloneコマンドによるクローンが便利です。
一方、lxc-start-ephemeralコマンドが便利な場面もあるでしょう。
また、lxc-start-ephemeralコマンドはoverlayfsもしくはaufsを使用しますので、
まずは使ってみましょう
まずは簡単にlxc-start-ephemeralコマンドの動きを見てみましょう。
lxc-start-ephemeralコマンドを一番シンプルに使用するには、
$ sudo lxc-ls ct01 $ sudo lxc-start-ephemeral -o ct01
以上のように実行するとフォアグラウンドでの起動になりますので、
あらかじめ-oで指定したコピー元のコンテナにアクセスできるユーザが設定されていればそのまま使えますが、lxc-stopで終了させるか、lxc-attachコマンドで必要な設定や操作を行いましょう。
なおlxc-startコマンドで起動したコンテナがデフォルトでバックグラウンド起動になるLXC 1.lxc-ephemeralコマンドは特に指定しなければフォアグラウンドでの起動になります。
lxc-startと同様に、lxc-start-ephemeralでも-dオプションを使ってバックグラウンドで起動できます。ここから後はバックグラウンドで起動していろいろな機能を紹介していきます。
それではバックグラウンドでコンテナを起動してみましょう。
$ sudo lxc-start-ephemeral -o ct01 -d The ephemeral container is now started. You can enter it from the command line with: lxc-console -n ct01-zvsn8pmn The following IP addresses have be found in the container: - 10.0.3.130
バックグラウンドで起動すると、
もし、
lxc-consoleコマンドを使ってログインする- ssh経由でログインする
lxc-attachコマンドでコンテナ上でコマンドを実行する
一時的とは言え、lxc-lsで確認できます。
$ sudo lxc-ls -f NAME STATE IPV4 IPV6 AUTOSTART --------------------------------------------------- ct01 STOPPED - - NO ct01-zvsn8pmn RUNNING 10.0.3.130 - NO
起動を確認したあとコンテナを停止させてみます。
$ sudo lxc-stop -n ct01-zvsn8pmn $ sudo lxc-ls ct01
以上のように停止後はコンテナは消えています。
lxc-start-ephemeralコマンドのオプション
lxc-start-ephemeralコマンドを詳しく見ていく前に、
| オプション | オプションの説明 |
|---|---|
| -o,--orig | コピー元のコンテナ名 |
| -n,--name | 一時的に起動するコンテナの名前 |
| -d,--daemon | コンテナをバックグラウンドで実行 |
| -b,--bdir | コンテナ内にバインドマウントするディレクトリ |
| -u,--user | コンテナに接続するためのユーザ |
| -S,--key | コンテナ内にコピーする SSH 公開鍵 |
| -U,--union-type | 使用する union filesystem |
| -k,--keep-data | コマンド終了後にコンテナイメージを残す |
| -s,--storage-type | 使用するストレージバックエンド |
以上のオプションのうち、-oのみです。--storage-typeは現時点でマニュアルに記載がありません。筆者がパッチを送ってありますので、
lxc-start-ephemeralコマンドの仕組みとフック
lxc-start-ephemeralコマンドがどのように一時的なコンテナを実現しているのかを少し詳しく見ていきましょう。あらためてバックグラウンドでコンテナを起動してみます。
$ sudo lxc-start-ephemeral -o ct01 -d The ephemeral container is now started. You can enter it from the command line with: lxc-console -n ct01-7iv1faqo The following IP addresses have be found in the container: - 10.0.3.240
まずはコンテナ用のディレクトリを見てみましょう。
$ sudo ls -F /var/lib/lxc/ct01-7iv1faqo/ config configured delta0/ post-stop* pre-mount* rootfs/
見慣れたファイルの他にいくつか初めて見るファイルが存在しますね。
まずは設定ファイルであるconfigを見てみましょう。lxc-createコマンドを使ってコンテナを作成した時にも設定される項目は除いて、lxc-start-ephemeral特徴的な設定だけ挙げてみます。
$ sudo cat /var/lib/lxc/ct01-7iv1faqo/config :(略) lxc.utsname = ct01-7iv1faqo :(略) lxc.hook.pre-mount = /var/lib/lxc/ct01-7iv1faqo/pre-mount lxc.hook.post-stop = /var/lib/lxc/ct01-7iv1faqo/post-stop lxc.rootfs = /var/lib/lxc/ct01-7iv1faqo/rootfs
lxc.とlxc.はlxc-start-ephemeralコマンドがランダムで付与したコンテナ名で設定されています。この2つの設定以外が初めて目にする設定ではないでしょうか。
LXCはコンテナを起動させようとした時からコンテナが停止するまでのいろいろな場面と、lxc-start-ephemeralコマンドはこのフックを使って必要な処理を行っています。
第11回、
まずはこの2つのフックについて説明しましょう。
lxc-start-ephemeralコマンドのコンテナ起動前の処理
lxc-start-ephemeralコマンドは起動するコンテナのルートファイルシステムをunion filesystemを使って準備します。この準備をフックを使って行っています。
lxc.は、
lxc.で指定されているpre-mountスクリプトは、
1: #!/bin/sh
2: LXC_DIR="/var/lib/lxc/ct01-7iv1faqo"
3: LXC_BASE="ct01"
4: LXC_NAME="ct01-7iv1faqo"
5: mkdir -p /var/lib/lxc/ct01-7iv1faqo/delta0 /var/lib/lxc/ct01-7iv1faqo/rootfs/
6: mount -n -t tmpfs -o mode=0755 none /var/lib/lxc/ct01-7iv1faqo/delta0
7: mount -n -t overlayfs -oupperdir=/var/lib/lxc/ct01-7iv1faqo/delta0,lowerdir=/var/lib/lxc/ct01/rootfs none /var/lib/lxc/ct01-7iv1faqo/rootfs/
8:
9: [ -e $LXC_DIR/configured ] && exit 0
10: for file in $LXC_DIR/rootfs/etc/hostname \
11: $LXC_DIR/rootfs/etc/hosts \
12: $LXC_DIR/rootfs/etc/sysconfig/network \
13: $LXC_DIR/rootfs/etc/sysconfig/network-scripts/ifcfg-eth0; do
14: [ -f "$file" ] && sed -i -e "s/$LXC_BASE/$LXC_NAME/" $file
15: done
16: touch $LXC_DIR/configured
順に見ていきましょう。
- 2~4行目:変数の定義です。
- 5行目:
delta0ディレクトリとrootfsディレクトリを作成します。 - 6行目:
rootfsをtmpfsとしてマウントします。 - 7行目:上層側ディレクトリとして
delta0を、下層側ディレクトリとしてコピー元であるコンテナのイメージを指定して rootfsをoverlayfsとしてマウントします。 - 9行目:既に
configuredファイルが存在する場合は10行目以下の処理を行いません。 - 10行目~15行目:コンテナのルートファイルシステム以下に存在しているファイルに記載されているホスト名を、
これから起動するコンテナ名で書き換えます。 - 16行目:
configuredファイルを作成する。
という処理を行っています。
つまりoverlayfsが変化を記録するために使う上層側ディレクトリとしてtmpfsを使い、
overlayfsを使っているので、
lxc-start-ephemeralコマンドのコンテナ終了後の処理
lxc-start-ephmeralコマンドを使って作成されたコンテナでは、
コンテナ終了後に後始末をするため、lxc.という設定がされていました。これはコンテナがシャットダウンされた後にホストの名前空間上で実行されるフックです。
lxc.hook.post-stop = /var/lib/lxc/ct01-7iv1faqo/post-stop
ここで指定されているファイルの中を見てみましょう。
#!/bin/sh
[ -d "/var/lib/lxc/ct01-7iv1faqo" ] && rm -Rf "/var/lib/lxc/ct01-7iv1faqo"
一時的なコンテナ用に作成されたディレクトリを消去しています。このようにlxc.を使って、
lxc-start-ephemeralのその他の使い方
コンテナ名の指定
デフォルトではlxc-start-ephemeralコマンドは、-nオプションで名前を付けられます。
コマンドの実行
lxc-start-ephemeralコマンドはシステムコンテナだけでなく、
$ sudo lxc-start-ephemeral -o ct01 -- /bin/hostname ct01-d6cz_82i $ sudo lxc-ls ct01
以上の例は/bin/コマンドを実行しました。hostnameコマンドが実行されるとコンテナは終了しますので、lxc-lsコマンドで確認してもコンテナは存在しません。
$ sudo lxc-start-ephemeral -o ct01 -- /bin/bash
root@ct01-lk_clba7:~# (必要な処理を行う)
root@ct01-lk_clba7:~# exit
exit
$ sudo lxc-ls
ct01
以上の例はbashを実行しています。lxc-startで作成したコンテナの内部を、exitするとコンテナは消去されています。
コマンドを指定した場合、lxc-attachコマンドが実行できる環境である場合はlxc-attachで実行した場合と同等の処理でコマンドを実行します。
lxc-attachコマンドが動かなような古いカーネルを使っているような場合は、
現時点でのマニュアルでは、
ユーザの指定
lxc-start-ephemeralでコマンドを実行する際に、
もちろん、
LXCのubuntuテンプレートやdownloadテンプレートでubuntuコンテナを作成した場合は、ubuntuユーザが作成されていますので、ubuntuユーザを指定してコマンドを実行してみましょう。ユーザを指定する場合は--userオプションを使います。
$ sudo lxc-start-ephemeral -o ct01 --user=ubuntu -- /bin/bash ubuntu@ct01-0d5di0mf:~$ id uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),27(sudo) ubuntu@ct01-0d5di0mf:~$ exit exit $
以上のように指定したubuntuユーザでbashが実行されていますね。存在しないユーザで実行すると、
sshでアクセスする時は、--keyオプションを使ってユーザの公開鍵をコンテナ内にコピーできます。
ストレージタイプの指定
lxc-start-ephemeralコマンドは、pre-mountスクリプトでは、
この上層側ディレクトリをtmpfsで作成する代わりに、--storage-typeオプションでdirを指定して普通のディレクトリにできます。
もちろんコンテナの実行が終了した時点でコンテナ自体が消去される場合には、dirを指定してもtmpfsを指定してもあまり変わりはないように思えます。dirが選択肢にある理由は、--keep-dataオプションで使うためです。
使用するUnion filesystemのタイプの指定
一時的なコンテナを作成する際に使用するUnion filesystemのタイプを--union-typeで指定できます。overlayfsかaufsを指定できます。もちろん、
永続的なコンテナにする
--keep-dataオプションを付けてlxc-start-ephemeralコマンドを実行すると、tmpfsを使うわけにはいきませんので普通にディレクトリを使います。
--keep-dataを使うと、lxc-cloneコマンドでoverlayfsもしくはaufsを使ったスナップショットクローンを指定した場合と同じような状態になりますね。
コンテナ内にホストのディレクトリをマウントする
ホスト上のディレクトリをコンテナ内にバインドマウントできます。これは--bdirオプションを使います。指定したパスと同じコンテナ内のパスにバインドマウントされます。
$ touch on_host $ sudo lxc-start-ephemeral -o ct01 --user=ubuntu --bdir=/home/ubuntu -- /bin/bash ubuntu@ct01-212j96rq:~$ pwd /home/ubuntu ubuntu@ct01-212j96rq:~$ ls on_host
上記の例では、/home/というファイルを作成して、/home/をバインドマウントする指定でコンテナを起動しています。コンテナ内の/home/には確かにon_ファイルがあります。
これは先に説明したlxc.を使ってマウントしています。
$ sudo cat /var/lib/lxc/ct01-212j96rq/pre-mount | grep bind mount -n --bind /home/ubuntu /var/lib/lxc/ct01-212j96rq/rootfs//home/ubuntu
pre-mountスクリプトを確認してみると、
まとめ
今回は既に存在するコンテナの一時的なコピーを作成し、lxc-start-ephemeralコマンドを紹介しました。また、lxc-start-ephemeralコマンドが処理中に使用しているLXCのフック機能を簡単に紹介しました。
次回は今回説明していないフック機能を紹介する予定です。
