TenForward

技術ブログ。はてなダイアリーから移転しました

CRIU (3)

(ちょっと雑なのであとで書き直すかも?)

前回,CRIU を試してから丁度 1 年.前回はカーネルは 3.7 ベースで専用のもの,CRIU は 0.2 の頃でした.実はこの時も LXC コンテナで dump/restore するのを試したのですが,やり方が悪かったのか,まだ機能的に無理だったのかわかりませんが,うまくいきませんでした.

今や標準カーネルにも Checkpoint/Restore 用の機能の実装もすすみ,CRIU も 0.8 になっています.だいぶ動くようになっているのが以下からもうかがえますね.

というわけで私も少し試してみました.試した! 動いた! ってだけなのであまり役には立たないエントリです.

準備

準備ができたら

# criu check --ms
(00.002480) Warn  (tun.c:54): Skipping tun support check
Looks good.

とやって Looks good を確認します.

ちなみにこんな環境になっています.

root@enterprise:~# uname -r
3.11.6-plamo64-karma
root@enterprise:~# criu --version
Version: 0.8
root@enterprise:~# lxc-version 
lxc version: 1.0.0.alpha2

iproute2 は 3.8.0 でした.

実行

ほぼ LXC - CRIU に書いてある通りです.私は lxc-create -t plamo で作った Plamo コンテナで実行しています.

  1. まずコンテナを準備しました.しかし /var/lib/lxc/コンテナ名/rootfs 以下のファイルは別の場所に移して,ここは空にします.あとで bind mount します.
    # lxc-create -n plamo02 -t plamo
    # cd /root ; rsync -a /var/lib/lxc/plamo02 . ; rm -rf /var/lib/lxc/plamo02/rootfs/*
  2. コンテナの設定ファイルを編集します.設定は後で示します.編集のポイントは
    • console はなしにする (lxc.console = none)
    • あとで実行時に指定するので veth ペアのホスト側のインターフェース名を固定します (lxc.network.veth.pair = plamo02)
    • コンテナ内で cgroupfs はマウントしません.これは 1.0alpha 以降でないと普通はしないですね.
    • あとは普通に lxc-create で作るテンプレートでいけそうな気がしますが,ここで挙げる例と公式ページの CentOS コンテナの例しか試してませんので他はわかりません
  3. コンテナ内で実行するデーモンは最低限にしました.Plamo の場合
    • NFS関係のデーモンの停止 (rc.inet2)
    • postfix 停止
    • inetd 停止
    • 動くのは dhclient, saslauthd, sshd 程度にしました
  4. コンテナの rootfs を bind mount します.なぜこれが必要なのかはわかりません.
    root@enterprise:~# mount --bind /root/plamo02/ /var/lib/lxc/plamo02/rootfs/
  5. ここでおもむろにコンテナのスタートです.起動してアドレスも割り当たってます.
    root@enterprise:~# lxc-start -n plamo02 -d -o log -l DEBUG
    root@enterprise:~# lxc-info -n plamo02
    state: RUNNING
    pid: 7205
    ip: 10.0.100.173
  6. ip コマンドでネットワーク名前空間を操作するために必要なリンクを張ります.これで別の名前空間内の操作が可能になりますね.
    root@enterprise:~# ln -sf /proc/7205/ns/net /var/run/netns/plamo02
    root@enterprise:~# ip netns exec plamo02 ip a
    1: lo: mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
    valid_lft forever preferred_lft forever
    9: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether d2:17:05:04:10:e2 brd ff:ff:ff:ff:ff:ff
    inet 10.0.100.173/24 brd 10.0.100.255 scope global eth0
    valid_lft forever preferred_lft forever
    inet6 fe80::d017:5ff:fe04:10e2/64 scope link
    valid_lft forever preferred_lft forever
  7. 確認のために ping
    root@enterprise:~# ping 10.0.100.173
    PING 10.0.100.173 (10.0.100.173): 56 octets data
    64 octets from 10.0.100.173: icmp_seq=0 ttl=64 time=0.0 ms
    64 octets from 10.0.100.173: icmp_seq=1 ttl=64 time=0.0 ms
    ^C
    --- 10.0.100.173 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.0/0.0/0.0 ms
  8. ここで dump します.指定した /root/dump 以下には *.img というファイルがたくさんできています.
    root@enterprise:~# criu dump \
    --tcp-established \
    --ext-unix-sk \
    --file-locks \
    -n net -n mnt -n ipc -n pid \
    --action-script "/root/network-script.sh dump 7205 plamo02" \
    -D /root/dump/ \
    -o dump.log \
    -vvvv \
    -t $1
    plamo02<=>eth0
    Detach plamo02 to the bridge lxcbr0
    root@enterprise:~# ls /root/dump
    core-1.img fdinfo-11.img fs-77.img itimers-77.img pages-4.img rlimit-68.img signal-s-111.img
    core-104.img fdinfo-2.img ids-1.img mm-1.img pages-5.img rlimit-77.img signal-s-112.img
    core-109.img fdinfo-3.img ids-104.img mm-104.img pages-6.img route-7.img signal-s-113.img
    core-110.img fdinfo-4.img ids-109.img mm-109.img pages-7.img sigacts-1.img signal-s-142.img
    core-111.img fdinfo-5.img ids-110.img mm-110.img pages-8.img sigacts-104.img signal-s-68.img
    core-112.img fdinfo-6.img ids-111.img mm-111.img pages-9.img sigacts-109.img signal-s-77.img
    core-113.img fdinfo-7.img ids-112.img mm-112.img pipes-data.img sigacts-110.img signalfd.img
    core-142.img fdinfo-8.img ids-113.img mm-113.img pipes.img sigacts-111.img sk-queues.img
    core-68.img fdinfo-9.img ids-142.img mm-142.img posix-timers-1.img sigacts-112.img stats-dump
    core-77.img fifo-data.img ids-68.img mm-68.img posix-timers-104.img sigacts-113.img stats-restore
    core-79.img fifo.img ids-77.img mm-77.img posix-timers-109.img sigacts-142.img tmpfs-49.tar.gz.img
    core-80.img filelocks-1.img ifaddr-7.img mountpoints-10.img posix-timers-110.img sigacts-68.img tmpfs-50.tar.gz.img
    core-81.img filelocks-104.img inetsk.img netdev-7.img posix-timers-111.img sigacts-77.img tty-info.img
    creds-1.img filelocks-109.img inotify-wd.img netlinksk.img posix-timers-112.img signal-p-1.img tty.img
    creds-104.img filelocks-110.img inotify.img ns-files.img posix-timers-113.img signal-p-104.img tunfile.img
    creds-109.img filelocks-111.img inventory.img packetsk.img posix-timers-142.img signal-p-109.img unixsk.img
    creds-110.img filelocks-112.img ipcns-msg-8.img pagemap-1.img posix-timers-68.img signal-p-110.img utsns-9.img
    creds-111.img filelocks-113.img ipcns-sem-8.img pagemap-104.img posix-timers-77.img signal-p-111.img vmas-1.img
    creds-112.img filelocks-142.img ipcns-shm-8.img pagemap-109.img pstree.img signal-p-112.img vmas-104.img
    creds-113.img filelocks-68.img ipcns-var-8.img pagemap-110.img reg-files.img signal-p-113.img vmas-109.img
    creds-142.img filelocks-77.img iptables-7.img pagemap-111.img remap-fpath.img signal-p-142.img vmas-110.img
    creds-68.img fs-1.img itimers-1.img pagemap-112.img restore.log signal-p-68.img vmas-111.img
    creds-77.img fs-104.img itimers-104.img pagemap-113.img rlimit-1.img signal-p-77.img vmas-112.img
    dump.log fs-109.img itimers-109.img pagemap-142.img rlimit-104.img signal-p-79.img vmas-113.img
    eventfd.img fs-110.img itimers-110.img pagemap-68.img rlimit-109.img signal-p-80.img vmas-142.img
    eventpoll-tfd.img fs-111.img itimers-111.img pagemap-77.img rlimit-110.img signal-p-81.img vmas-68.img
    eventpoll.img fs-112.img itimers-112.img pages-1.img rlimit-111.img signal-s-1.img vmas-77.img
    fanotify-mark.img fs-113.img itimers-113.img pages-10.img rlimit-112.img signal-s-104.img
    fanotify.img fs-142.img itimers-142.img pages-2.img rlimit-113.img signal-s-109.img
    fdinfo-10.img fs-68.img itimers-68.img pages-3.img rlimit-142.img signal-s-110.img
  9. ここで ping をしても届きません.lxc-info も STOPPED に.
    root@enterprise:~# ping 10.0.100.173
    PING 10.0.100.173 (10.0.100.173): 56 octets data
    ^C
    --- 10.0.100.173 ping statistics ---
    2 packets transmitted, 0 packets received, 100% packet loss
    root@enterprise:~# lxc-info -n plamo02
    state: STOPPED
  10. restore します.そのまま返ってこないので ^C で終わらせます.
    root@enterprise:~# criu restore \
    --tcp-established \
    --evasive-devices \
    -n net -n mnt -n ipc -n pid \
    --action-script "/root/network-script.sh restore plamo02" \
    --veth-pair eth0=plamo02 \
    --root /var/lib/lxc/plamo02/rootfs \
    -D /root/dump \
    -o restore.log \
    -vvvv
    Attach plamo02 to the bridge lxcbr0
    ^Croot@enterprise:~#
  11. 復帰しているか確認です
    root@enterprise:~# ping 10.0.100.173
    PING 10.0.100.173 (10.0.100.173): 56 octets data
    64 octets from 10.0.100.173: icmp_seq=0 ttl=64 time=0.0 ms
    64 octets from 10.0.100.173: icmp_seq=1 ttl=64 time=0.0 ms
    ^C
    --- 10.0.100.173 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.0/0.0/0.0 ms
    root@enterprise:~# pstree -p
    init(1)-+-Thunar(4186)
    |-agetty(3991)
    : (snip)
    |-init(7415)-+-dhclient(7438)
    | |-rsyslogd(7436)-+-{rsyslogd}(7443)
    | | |-{rsyslogd}(7444)
    | | `-{rsyslogd}(7445)
    | |-saslauthd(7435)-+-saslauthd(7439)
    | | |-saslauthd(7440)
    | | |-saslauthd(7441)
    | | `-saslauthd(7442)
    | `-sshd(7434)

ちゃんと期待するコンテナ内のプロセスが上がっているのが確認できるかと思います.

ちなみに復帰後は lxc-start で起動してないから,lxc ツールのモニタリングに必要な処理がされてないためと思われますが,lxc-info は STOPPED のままです.lxc-stop なんかで止めることはできないので,なんらかの手段でシャットダウンするか,強引に init を kill するかになります.

まだコンテナ側に色々工夫が必要で,普通に起動したコンテナを dump/restore するのは無理ですが,確実に進化していますね :-) 詳しい仕組みは賢い人がきっと説明してくれるでしょう ;-D

(もう少し丁寧に例を挙げて説明するかも?)