TenForward

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

Plamo Linux 5.2 での非特権コンテナ

Ubuntu はもうすぐ出そうなので出てから試すとして,Plamo 5.2 で非特権コンテナを試してみました.カーネルだけは自前で make してます (Plamo ユーザならカーネル再構築はインストール後のお決まりの仕事ですよ :-)

$ uname -r
3.14.1-plamo64-karma

プロンプトが "#" は root で実行."$" は一般ユーザ (ここでは "karma") で実行していますよ.

  1. shadow パッケージ,lxc パッケージを最新にします
    $ head -n 1 /var/log/packages/shadow 
    PACKAGE NAME: shadow-git_20130908-x86_64-P1
    karma@enterprise:~$ head -n 1 /var/log/packages/lxc
    PACKAGE NAME: lxc-1.0.3-x86_64-P1
  2. 非特権コンテナを実行したいユーザの subuid, subgid を設定します.ここでは 100000 から 10000 個の uid/gid をユーザ "karma" の subuid/subgid と設定しています.
    # usermod -v 100000-109999 -w 100000-109999 karma
    # cat /etc/subuid
    karma:100000:10000
    # cat /etc/subgid
    karma:100000:10000
  3. veth ペアの片方をホストのブリッジにアタッチするには特権が必要なので,そのために使う lxc-user-nic のための設定ファイルを作ります.lxc-user-nic は setuid されているプログラムです
    # echo "karma veth lxcbr0 2" | tee -a /etc/lxc/lxc-usernet
    karma veth lxcbr0 2
  4. ユーザが書き込める cgroup を作るために以下のようなスクリプトを実行します.私は /etc/rc.d/init.d で start/stop できるようなスクリプトにしています.
    USERNS="karma"

    echo 1 > /sys/fs/cgroup/memory/memory.use_hierarchy
    for c in /sys/fs/cgroup/*
    do
    echo 1 > $c/cgroup.clone_children
    for u in $USERNS
    do
    mkdir $c/$u
    chown -R $USERNS $c/$u
    if [ `basename $c` = "cpuset" ]; then
    echo 0 > $c/$u/cpuset.cpus
    echo 0 > $c/$u/cpuset.mems
    fi
    done
    done
    • これで "karma" ディレクトリができているのが確認できます.
      $ ls -ld /sys/fs/cgroup/*/karma
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/blkio/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/cpu/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/cpuacct/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/cpuset/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/devices/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/freezer/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/hugetlb/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/memory/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/net_cls/karma/
      drwxr-xr-x 2 karma root 0 4月 16日 17:00 /sys/fs/cgroup/perf_event/karma/
  5. lxc-create で使うユーザ用のデフォルトファイルを作成します.こんな感じ
    $ cat ~/.config/lxc/default.conf 
    lxc.id_map = u 0 100000 10000
    lxc.id_map = g 0 100000 10000

    lxc.network.type=veth
    lxc.network.link=lxcbr0
    lxc.network.flags=up
  6. これで準備できたので lxc-create します.ここでは Ubuntu Trusty コンテナを作ってみます.使うテンプレートは非特権ユーザの場合は download テンプレートです.
    $ lxc-create --name trusty01 --template download -- --dist ubuntu --release trusty --arch amd64
    Setting up the GPG keyring
    Downloading the image index
    Downloading the rootfs
    Downloading the metadata
    The image cache is now ready
    Unpacking the rootfs

    ---
    You just created an Ubuntu container (release=trusty, arch=amd64, variant=default)
    The default username/password is: ubuntu / ubuntu
    To gain root privileges, please use sudo.
    • できてますね〜
      $ ls -l ~/.local/share/lxc/
      合計 8,192
      drwxr-xr-x 3 karma users 4,096 4月 16日 20:01 trusty01/
      $ ls -l .local/share/lxc/trusty01/
      合計 8,192
      -rw-r--r-- 1 karma users 654 4月 16日 20:01 config
      drwxr-xr-x 21 100000 100000 4,096 4月 16日 13:09 rootfs/
      $ ls -l .local/share/lxc/trusty01/rootfs/
      合計 77,824
      drwxr-xr-x 2 100000 100000 4,096 4月 16日 13:08 bin/
      drwxr-xr-x 2 100000 100000 4,096 4月 11日 07:12 boot/
      drwxr-xr-x 3 100000 100000 4,096 4月 16日 13:08 dev/
      drwxr-xr-x 64 100000 100000 4,096 4月 16日 20:01 etc/
      drwxr-xr-x 3 100000 100000 4,096 4月 16日 13:09 home/
      drwxr-xr-x 12 100000 100000 4,096 4月 16日 13:08 lib/
      drwxr-xr-x 2 100000 100000 4,096 4月 16日 13:08 lib64/
      drwxr-xr-x 2 100000 100000 4,096 4月 16日 13:08 media/
      drwxr-xr-x 2 100000 100000 4,096 4月 11日 07:12 mnt/
      drwxr-xr-x 2 100000 100000 4,096 4月 16日 13:08 opt/
      drwxr-xr-x 2 100000 100000 4,096 4月 11日 07:12 proc/
      drwx------ 2 100000 100000 4,096 4月 16日 13:08 root/
      drwxr-xr-x 7 100000 100000 4,096 4月 16日 13:08 run/
      drwxr-xr-x 2 100000 100000 4,096 4月 16日 13:09 sbin/
      drwxr-xr-x 2 100000 100000 4,096 4月 16日 13:08 srv/
      drwxr-xr-x 2 100000 100000 4,096 3月 13日 10:41 sys/
      drwxrwxrwt 2 100000 100000 4,096 4月 16日 13:09 tmp/
      drwxr-xr-x 10 100000 100000 4,096 4月 16日 13:08 usr/
      drwxr-xr-x 11 100000 100000 4,096 4月 16日 13:08 var/
  7. 現在実行中のシェルの PID を自身の cgroup の tasks に登録します.この辺りは cgmanager を入れたら勝手にやってくれるのかな? (よく知らない)
    $ for c in /sys/fs/cgroup/*
    > do
    > echo $$ > $c/karma/tasks
    > done
  8. コンテナスタート!!
    $ lxc-start --name trusty01 --daemon
    $ lxc-ls --fancy
    NAME STATE IPV4 IPV6 AUTOSTART
    ------------------------------------------------
    trusty01 RUNNING 10.0.100.111 - NO
  9. lxc-console で繋ぐなり ssh で繋ぐなり
    $ lxc-console --name trusty01
    • こんな感じで
      Ubuntu 14.04 LTS trusty01 tty1

      trusty01 login: ubuntu
      Password:
      Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.14.1-plamo64-karma x86_64)

      * Documentation: https://help.ubuntu.com/

      The programs included with the Ubuntu system are free software;
      the exact distribution terms for each program are described in the
      individual files in /usr/share/doc/*/copyright.

      Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
      applicable law.

      ubuntu@trusty01:~$ ip addr show
      1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default
      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 group default qlen 1000
      link/ether ba:06:40:f6:a6:bc brd ff:ff:ff:ff:ff:ff
      inet 10.0.100.111/24 brd 10.0.100.255 scope global eth0
      valid_lft forever preferred_lft forever
      inet6 fe80::b806:40ff:fef6:a6bc/64 scope link
      valid_lft forever preferred_lft forever
      ubuntu@trusty01:~$ sudo shutdown -h now
      [sudo] password for ubuntu:
      ubuntu@trusty01:~$
      Broadcast message from ubuntu@trusty01
      (/dev/tty1) at 11:24 ...

      The system is going down for halt NOW!
      lxc_container: Input/output error - failed to read
      $

はい! Plamo なら最新のコンテナ環境もバッチリですよ :-) (Ubuntu はもっと簡単になってるはず)