0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LXC

Last updated at Posted at 2022-11-10

LXC というコンテナ技術について調べている。LXC というのは Docker のように Linux 上で他の Linux を動かすしくみだ。色々調べたが正直 Docker との違いはよく分からなかった。端的には、LXC が init を動かすのに対して

$ sudo lxc-create -t download -n u1 -- -d ubuntu -r bionic -a amd64 --keyserver hkp://keyserver.ubuntu.com:80
$ sudo lxc-execute -n u1 -- ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   1312     4 ?        Ss   07:08   0:00 init
root        22  0.0  0.0  36704  3060 ?        Rs+  07:08   0:00 ps -aux

docker では init が無いのが違う。(--init を付加すれば init も動く)

$ docker run -it --rm ubuntu ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  1.0  0.0   7060  1584 pts/0    Rs+  07:09   0:00 ps -aux

ここでは、たまたま手元にあった Ubuntu-18 を利用して動作を確認する。

インストール

sudo apt install -y lxc

LXC には2つの動作モードがある。

  • privileged: root ユーザで lxc を動かす
  • unprivileged: 一般ユーザで lxc を動かす
    • コンテナ内の root UID は non-root UID に割り当てられるため安全。

privileged モード (root ユーザ) でコンテナの作成

privileged でインタラクティブにコンテナ作成。

sudo lxc-create --template download --name u1 --  --keyserver hkp://keyserver.ubuntu.com:80

またはノンインタラクティブに作成

sudo lxc-create -t download -n u1 -- -d ubuntu -r bionic -a amd64 --keyserver hkp://keyserver.ubuntu.com:80
  • --template, -t: でテンプレートというコンテナの作り方を指定する。
    • テンプレートの実態は /usr/share/lxc/templates/ にあるシェルスクリプト。
  • --name, -n: コンテナにつける名前。
  • --: テンプレートに渡すオプション。
    • lxc-create -t TEMPLATE -h でヘルプが出る。
    • --keyserver: -t download に渡す GPG keyserver。事情がありデフォルト値が使えないので hkp://keyserver.ubuntu.com:80 と指定する。

busybox のコンテナを作ってみる。ls -l /bin すれば分かるが busybox しか無い素晴らしく小さなコンテナができる。

sudo lxc-create --template busybox --name bbox

参考: Linux Containers - LXC - Man ページ - lxc-create.1

様々なコマンド

コンテナのリスト

sudo lxc-ls --fancy

コンテナを起動

sudo lxc-start --name u1

起動したコンテナに入る

sudo lxc-attach --name u1

コンテナを停止

sudo lxc-stop --name u1

コンテナを起動してコマンドを実行して停止

sudo lxc-execute --name u1 -- bash

コンテナを破棄

sudo lxc-destroy --name u1

コンテナの静的構造

/var/lib/lxc/名前/ 以下にコンテナの実態が作られる。

  • rootfs: コンテナから見えるファイル
  • config: 設定ファイル
    • lxc.mount.entry: rootfs にあるファイルの他、ここで指定したディレクトリをマウントできる。

例えば、先程作った busybox コンテナ bbox に pstree コマンドを入れたい時は /var/lib/lxc/bbox/rootfs/ にコピーすれば良い。

sudo cp /usr/bin/pstree /var/lib/lxc/bbox/rootfs/usr/bin/

コンテナの動的構造

lxc-attach で起動中のコンテナに入れる。先程コピーした pstree で見ると、init/bin/sh の親プロセス ID が 0 である事がわかる。(引数なしで実行すると init(1) を指定した事になるので、sh や pstreeが表示されないため、明示的に 0 を指定する)

# pstree -p 0
?()─┬─init(1)─┬─getty(10)
    │         ├─init(11)
    │         ├─syslogd(4)
    │         └─udhcpc(9)
    └─sh(28)───pstree(75)

一方でコンテナの外に出て観察すると、init の親が lxc-start/bin/sh の親が lxc-attach である事がわかる。

Subordinate UID / GID

Unprivileged モードを利用する前に、Linux の仮想環境でユーザを仮想化する方法を確認する。ユーザ仮想化の確認には unshare --user コマンドを使う。

$ unshare --user
$ id
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
$ echo $$
11839

この時点では uid=65534(nobody) にみえる。$$ は現在の PID なので、この番号 11839 を覚えておく。

別のシェルを開けて、このプロセスの UID を変更する。

$ echo '0 1000 1' > /proc/11839/uid_map
$ echo '0 1000 1' | sudo tee /proc/11839/gid_map

ここで、'0 1000 1' の意味は

  • 0: 名前空間内の最初の ID
  • 1000: 名前空間外の最初のID つまり自分の ID
  • 1: 範囲

となる。ここで unshare --user を実行したシェルに戻る。

$ id
uid=0(root) gid=0(root) groups=0(root)

このように自分が root になったように見える。他にも色々あるが省略。

Unprivileged モード (一般ユーザ) で動かす。

(注意: Ubuntu 18 では X ターミナルから実行しないと動きませんでした。詳細は https://github.com/lxc/lxc/issues/3002)

まず、自分が使える UID と GID の範囲を確認する。

$ grep $USER /etc/subuid
tyamamiya:100000:65536
$ grep $USER /etc/subgid
tyamamiya:100000:65536

これで、uid / gid ともに 100000 から 65536 個使えるとわかる。この値を使って LXC を設定する。

cat <<EOT > ~/.config/lxc/default.conf
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
EOT
echo "$USER veth lxcbr0 2" | sudo tee -a /etc/lxc/lxc-usernet

Unprivileged モードでコンテナを作成する。

lxc-create -t download -n u1 -- -d ubuntu -r bionic -a amd64 --  --keyserver hkp://keyserver.ubuntu.com

あとは Privileged モードと同じ。

lxc-start --name u1
lxc-attach --name u1
touch hello.txt

作ったファイルは .local/share/lxc/u1/rootfs にできている。

ls -l .local/share/lxc/u1/rootfs/hello.txt
-rw-rw-r-- 1 100000 100000 0 Nov  9 21:24 .local/share/lxc/u1/rootfs/hello.txt

非常に面白い。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?