lxc勉強のため、Gentooホスト上にArchLinuxのコンテナを作成した。lxc-1.1.0-r3 使用、最低限のスタートアップとシャットダウンができる状態にする(20153)

不明点/宿題

今回の内容には以下の項目が欠けていて、私自身の宿題になっている。

  • ネットワークの使用 (コンテナ間ブリッジとmasquerateで、さくらVPS上でも動かしてみたい。)
  • 自動起動(lxc-auto-start)。 Gentooのlxc-1.1.0-r3のebuildに付属のinitスクリプトは、あんまりいけてない。多分lxc-auto-startやスナップショットを使っていない。
  • デバイスのアクセス権設定。
  • aufsなど使用して、低いコストで複数コンテナを走らせて見る。
  • 出来ればグラフィックスなどを使用できるか試してみる。 GentooでGUIの味見はつらいので。/dev/tty0を明け渡せばいけるかも
  • /etc/hostnameは作成すべきか。/etc/fstabを作成すべきかどうかなど、コンテナ内のシステム設定
  • VirtualBox上のArchテスト環境を、コンテナへ移動。実はホストもVirtualBox上のGentoo。

Docker? いつか試します

busyboxコンテナであたりをつける

busybox環境の超軽量コンテナを作成し、何がどうなるのか見てみた。 テンプレート /usr/share/lxc/templates/lxc-busybox を使用。

テンプレートによるコンテナ作成

コンテナ名を bbとする。 この名前とテンプレートのみ指定すると・・・

# lxc-create -n bb -t busybox
setting root password to "root"
Password for 'root' changed

# find /var/lib/lxc -maxdepth 2
/var/lib/lxc
/var/lib/lxc/bb
/var/lib/lxc/bb/config
/var/lib/lxc/bb/rootfs
/var/lib/lxc/rootfs
/var/lib/lxc/rootfs/.keep_app-emulation_lxc-0
/var/lib/lxc/rootfs/README

/var/lib/lxcに、コンテナ用ディレクトリ bb、および コンフィグファイル bb/config、そしてファイルシステムルート bb/rootfsが作成された。

busyboxコンテナを実行してみる

フォアグラウンドで実行(-F)

# lxc-start -F -n bb  --logfile=~/bb.log -l INFO
/etc/init.d/rcS: line 2: /bin/syslogd: not found
mount: can't read '/etc/fstab': No such file or directory
udhcpc: SIOCGIFINDEX: No such device

Please press Enter to activate this console.

コンテナ内で # haltで終了する。 ネットワークデバイスなし、/etc/fstabなし、syslogdなし、などのためエラーが幾つか、今は無視。

ログの内容はそのうちチェックしよう(宿題)。いまは、致命的なものはなさそう(いやdev/shmは大丈夫か??)。

# cat bb.log
lxc-start(略) WARN lxc_log - log.c:lxc_log_init:316 - lxc_log_init called with log already initialized
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup cpuset unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup cpu unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup cpuacct unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup memory unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup devices unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup freezer unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup net_cls unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup blkio unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_cgfs - cgfs.c:lxc_cgroup_get_container_info:1100 - Not attaching to cgroup perf_event unknown to /var/lib/lxc bb
lxc-start(略) WARN lxc_conf - conf.c:mount_entry_on_absolute_rootfs:1874 - ignoring mount point '/dev/shm'
lxc-start(略) WARN lxc_start - start.c:signal_handler:307 - invalid pid for SIGCHLD

Archコンテナに挑戦

ArchWikiこれに従い、ブートストラップイメージを用いたディレクトリへのインストールを行う。 Archコンテナ on Archホストなら、テンプレートが使えるのかもしれない。

  • コンテナ名 : sake

  • 使用したArchブートストラップイメージ : archlinux-bootstrap-2015.02.01-x86_64.tar.gz

.

  1. コンテナ用のディレクトリを作る

    # cd /var/lib/lxc
    # mkdir sake
    
  2. 先ほどの、busyboxコンテナのconfigファイルをコピーして編集

    # cp bb/config sake/
    # vi sake/config
    lxc.network.type = empty
    lxc.rootfs = /var/lib/lxc/sake/rootfs   #修正
    lxc.haltsignal = SIGRTMIN+4 # 修正。systemdシャットダウン開始
    lxc.stopsignal = SIGRTMIN+14 #追加。systemd直ちにhalt
    lxc.utsname = sake          #修正
    lxc.tty = 1
    lxc.pts = 1
    lxc.cap.drop = sys_module mac_admin mac_override sys_time
    
    # When using LXC with apparmor, uncomment the next line to run unconfined:
    #lxc.aa_profile = unconfined
    
    lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
    #lxc.mount.entry = shm /dev/shm tmpfs defaults 0 0       #とりあえずコメントアウト:警告が出てマウントできていないようなので
    #lxc.mount.entry = /lib lib none ro,bind 0 0             #修正 busyboxではホストの/libを流用, Archでは不要
    #lxc.mount.entry = /usr/lib usr/lib none ro,bind 0 0     #修正 同上
    #lxc.mount.entry = /lib64 lib64 none ro,bind 0 0         #修正 同上
    #lxc.mount.entry = /usr/lib64 usr/lib64 none ro,bind 0 0 #修正 同上
    lxc.mount.entry = /sys/kernel/security sys/kernel/security none ro,bind,optional 0 0 # そんなの無いよとログにでるがINFOなので放置
    

    この後しばらくは、ArchWikiにほぼ従った手順。

  3. ArchLinuxのブートストラップイメージを、適当な場所に展開する。

    # mkdir /var/tmp/arch_bootstrap
    # cd /var/tmp/arch_bootstrap
    # tar xpf .../archlinux-bootstrap-2015.02.01-x86_64.tar.gz
    # ls
    root.x86_64
    
  4. ArchLinux のブートストラップイメージにchrootし、chroot環境に ディレクトリ/mnt/rootfs を作成しそこでブートストラップを行う。

    # pwd
    /var/tmp/arch_bootstrap
    # root.x86_64/usr/bin/arch-chroot root.x86_64/
    (ここからchroot環境)
    # PS1="## " # 見分けやすいようにプロンプトを変更
    ##
    

    /etc/resolv.confのコピーや、/proc等のマウントなど基本的なことは自動で行われるらしい。

  5. pacmanのキーリングを初期化する。

    ## pacmna-key --init
    ## pacman-key --populate archlinux
    

    遅いときは、待つかhavegdを使う。今回はホスト側でdd if=/dev/sda of=/dev/nullしてみたけど効果は不明。

  6. pacmanのミラーリストを編集。Japanの2つほどのエントリをコメント解除するなど。

    ## vi root.x86_64/etc/pacman.d/mirrorlist
    ## /etc/pacman.d/mirrorlist
    
  7. pacstrapでベースシステムをインストールする

    ## mkdir /mnt/rootfs
    ## pacstrap -d /mnt/rootfs base  # マウントポイントでないので -d が必要
    
  8. インストールイメージにchrootする。

    ## arch-chroot /mnt/rootfs
    ## PS1="### "  #見やすいようにプロンプト変更
    ### 
    

    /etc/pacman.d/mirrorlistはpacstrapがコピーしてくれるらしい。

  9. Archのインストール手順に従い、いろいろ初期化してゆく。

    ### ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
    ### vi /etc/locale.gen
    ja_JP.UTF-8 UTF-8
    ### locale-gen
    Generating locales...
     ja_JP.UTF-8... done
    Generation complete.
    ### echo KEYMAP=jp106 > /etc/vconsole.conf
    ### echo LANG=C > /etc/locale.conf
    ### passwd
    
    • ホスト名設定済みで起動するので、/etc/hostnameは置かなかった。
    • /etc/fstabを空のまま放置。これでいいか不明。
  10. ブートストラップ 終わり。作成したイメージrootfsを、lxcのディレクトリへ移動する。

    ### exit # インストールイメージからexit
    ## exit # ブートストラップ環境からexit
    mv root.x86_64/mnt/rootfs /var/lib/lxc/sake/
    

これで最低限、起動する状態になった。デバイスのアクセス制限や、ホストの vgaを独占させられるかなどは宿題。

起動

ログは/var/log/lxc/<コンテナ名>.log。 以下便宜上、コンテナ内のやり取りは、行頭に(sake) を置いて区別する。

フォアグラウンド(-F)で起動

コンテナ内haltで終了

# lxc-start -F -n sake
  :
 (systemdの起動関連メッセージ多数)
  :
(sake) login: root
(sake) password:
(sake) # halt # or shutdown -h now
  :
 (systemdのたち下げ関連メッセージ多数)
  :
# 

バックグラウンドで起動

# lxc-start -n sake
  • rootのbashでconsoleにアタッチ(ログインなし)、exitで戻ってくる

    # lxc-attach -n sake
    (sake)# exit
    # 
    

    lxc-attachにコマンドを指定しないと、現ユーザーのデフォルトシェルをコンテナ内で実行する。とmanにある。

  • ptsに接続。コンテナ内のログインプロンプトが待っている。 exitするとログインプロンプトに戻る。いつでも、ctl-a qで切断できる。

    # lxc-console -n sake
    Connected to tty 1
    Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself
    (sake) login: <非root>
    (sake) password:
    (sake) $ exit
    (sake) login: (^a-q)
    #
    

    再度lxc-consoleすると、前回切断した状況の続きになる。コンテナ内の設定により、rootでもログインできるようになると思うが今後の宿題。 (多分/etc/security/access.conf)

  • フォアグラウンド(-F)+コマンド指定なしで実行するのと、バックグラウンド+lxc-consoleとで異なる点:

    • フォアグラウンドだと、コンソールにアクセスする。 rootログイン可。systemdの起動中メッセージを見ることが出来る。 haltやshutdown -hでシャットダウンの様子を確認できる。

      4402 pts/1    Ss+    0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt102 #フォアグラウンドはこっち。
      
    • バックグラウンドで実行してからlxc-consoleで接続だと、pts 接続。rootログインは、Archの初期状態では禁止されているようだ。

      4403 pts/0    Ss+    0:00 /sbin/agetty --noclear --keep-baud pts/0 115200 38400 9600 vt102 #バックグラウンドはこっちにつながる。
      

起動は所要1.5秒,シャットダウンは0.2秒くらい。ちょっと楽しい。楽しいので最後に画面の様子をお送りします。

# lxc-start -n sake -F

systemd 218 running in system mode. (+PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD +IDN)
Detected virtualization 'lxc'.
Detected architecture 'x86-64'.

Welcome to Arch Linux!

Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.
[  OK  ] Created slice Root Slice.
[  OK  ] Listening on Device-mapper event daemon FIFOs.
[  OK  ] Listening on /dev/initctl Compatibility Named Pipe.
[  OK  ] Listening on Journal Socket (/dev/log).
[  OK  ] Listening on Journal Audit Socket.
[  OK  ] Listening on Delayed Shutdown Socket.
[  OK  ] Created slice System Slice.
[  OK  ] Created slice system-container\x2dgetty.slice.
[  OK  ] Reached target Swap.
[  OK  ] Reached target Encrypted Volumes.
[  OK  ] Created slice system-getty.slice.
[  OK  ] Listening on LVM2 metadata daemon socket.
[  OK  ] Listening on Journal Socket.
         Starting Journal Service...
         Starting Remount Root and Kernel File Systems...
         Mounting Temporary Directory...
[  OK  ] Reached target Remote File Systems.
[  OK  ] Created slice User and Session Slice.
[  OK  ] Reached target Slices.
         Mounting Configuration File System...
         Mounting FUSE Control File System...
         Mounting POSIX Message Queue File System...
[  OK  ] Reached target Paths.
[  OK  ] Mounted FUSE Control File System.
[  OK  ] Mounted Temporary Directory.
[  OK  ] Mounted POSIX Message Queue File System.
[  OK  ] Mounted Configuration File System.
[  OK  ] Started Remount Root and Kernel File Systems.
[  OK  ] Reached target Local File Systems (Pre).
         Starting Load/Save Random Seed...
[  OK  ] Reached target Local File Systems.
[  OK  ] Started Load/Save Random Seed.
[  OK  ] Started Journal Service.
         Starting Flush Journal to Persistent Storage...
[  OK  ] Started Flush Journal to Persistent Storage.
         Starting Create Volatile Files and Directories...
[  OK  ] Started Create Volatile Files and Directories.
         Starting Update UTMP about System Boot/Shutdown...
[  OK  ] Started Update UTMP about System Boot/Shutdown.
[  OK  ] Reached target System Initialization.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Reached target Basic System.
         Starting D-Bus System Message Bus...
[  OK  ] Started D-Bus System Message Bus.
         Starting Permit User Sessions...
         Starting Login Service...
[  OK  ] Reached target Timers.
[  OK  ] Started Permit User Sessions.
         Starting Cleanup of Temporary Directories...
         Starting Console Getty...
[  OK  ] Started Console Getty.
         Starting Container Getty on /dev/pts/0...
[  OK  ] Started Container Getty on /dev/pts/0.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started Cleanup of Temporary Directories.
[  OK  ] Started Login Service.
[  OK  ] Reached target Multi-User System.
[  OK  ] Reached target Graphical Interface.

Arch Linux 3.18.7-gentooOhi64_1 (console)

sake login: root
Password:

ログインできた。プロセス一覧は・・・

[root@sake ~]#
[root@sake ~]# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 /sbin/init
   14 ?        Ss     0:00 /usr/lib/systemd/systemd-journald
   24 ?        Ss     0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
   26 ?        Ss     0:00 /usr/lib/systemd/systemd-logind
   28 ?        Ss     0:00 login -- root
   29 pts/0    Ss+    0:00 /sbin/agetty --noclear --keep-baud pts/0 115200 38400 9600 vt102
   32 ?        Ss     0:00 /usr/lib/systemd/systemd --user
   33 ?        S      0:00 (sd-pam)
   35 console  Ss     0:00 -bash
   37 console  R+     0:00 ps ax

とてもシンプルな世界。シャットダウンしてみる。

[root@sake ~]# shutdown -h now
         Stopping User Manager for UID 0...
[  OK  ] Stopped target Timers.
[  OK  ] Stopped target Graphical Interface.
[  OK  ] Stopped target Multi-User System.
         Stopping D-Bus System Message Bus...
[  OK  ] Stopped target Login Prompts.
         Stopping Container Getty on /dev/pts/0...
         Stopping Console Getty...
         Stopping Login Service...
[  OK  ] Removed slice system-getty.slice.
         Starting Generate shutdown-ramfs...
[  OK  ] Stopped D-Bus System Message Bus.
[  OK  ] Stopped Login Service.
[  OK  ] Stopped Console Getty.
[  OK  ] Stopped Container Getty on /dev/pts/0.
[  OK  ] Removed slice system-container\x2dgetty.slice.
[  OK  ] Stopped User Manager for UID 0.
         Stopping Permit User Sessions...
[  OK  ] Removed slice user-0.slice.
[  OK  ] Stopped Permit User Sessions.
[  OK  ] Stopped target Remote File Systems.
[  OK  ] Stopped target Basic System.
[  OK  ] Stopped target Paths.
[  OK  ] Stopped target Sockets.
[  OK  ] Closed D-Bus System Message Bus Socket.
[  OK  ] Stopped target Slices.
[  OK  ] Removed slice User and Session Slice.
[  OK  ] Stopped target System Initialization.
[  OK  ] Stopped target Swap.
[  OK  ] Stopped target Encrypted Volumes.
         Stopping Update UTMP about System Boot/Shutdown...
         Stopping Load/Save Random Seed...
[  OK  ] Stopped Load/Save Random Seed.
[  OK  ] Stopped Update UTMP about System Boot/Shutdown.
         Stopping Create Volatile Files and Directories...
[  OK  ] Stopped Create Volatile Files and Directories.
[  OK  ] Stopped target Local File Systems.
         Unmounting /sys/devices/virtual/net...
         Unmounting Temporary Directory...
         Unmounting /run/user/0...
         Unmounting /proc/sysrq-trigger...
         Unmounting /dev/tty1...
[  OK  ] Started Generate shutdown-ramfs.
[  OK  ] Unmounted /sys/devices/virtual/net.
[  OK  ] Unmounted Temporary Directory.
[  OK  ] Unmounted /dev/tty1.
[  OK  ] Unmounted /run/user/0.
[  OK  ] Unmounted /proc/sysrq-trigger.
[  OK  ] Reached target Unmount All Filesystems.
[  OK  ] Stopped target Local File Systems (Pre).
         Stopping Remount Root and Kernel File Systems...
[  OK  ] Stopped Remount Root and Kernel File Systems.
[  OK  ] Reached target Shutdown.
Sending SIGTERM to remaining processes...
Sending SIGKILL to remaining processes...
Halting system.

ひとまず、以上。