Previous Post | Top | Next Post |
TOC
Linux Namespaces の雰囲気が分かったところで、非特権ユーザー権限から立ち 上げられたLXC仮想環境を作ってみます。
NOTE: (2023-12-25/2024-03-14) LXD/Incusを使い出したら、カスタマイズした環境管理が便利なので以下のシェル操作ベースのコンテナ管理手法は休眠です。
非特権LXC実行環境整備
LXC (1:4.0.6-1) をBulleseye環境で/usr/share/doc/lxc/README.Debian
の
“Unprivileged containers"に従って設定していきます。(2021/02)
まずKERNELがunprivileged user namespacesを有効にしていることを確認します。
$ sudo uname -a
Linux **** 5.10.0-3-amd64 #1 SMP Debian 5.10.13-1 (2021-02-06) x86_64 GNU/Linux
$ sudo sysctl kernel.unprivileged_userns_clone
kernel.unprivileged_userns_clone = 1
ユーザーアカウント設定の/etc/subuid
と/etc/subgid
はすでに設定されていました。
これらは親システムのUIDやGIDからLXCコンテナ内から見えるUIDやGIDへの対応関係定義
しています。
ネットワーク設定は以下を実行:
$ NAME=$(id -un)
$ sudo sh -c "echo $NAME veth lxcbr0 10 >> /etc/lxc/lxc-usernet
さらに、~/.config/lxc/default.conf
のユーザー設定を/etc/subuid
と
/etc/subgid
に合わせて以下でします。
$ mkdir -p ~/.config/lxc
$ cat >~/.config/lxc/default.conf << EOF
lxc.include = /etc/lxc/default.conf
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
lxc.apparmor.profile = unconfined
EOF
download
templateだけが使えるので、これを使って実行します。
$ lxc-create -t download -n bullseye-user -- -d debian -r bullseye -a 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 a Debian bullseye amd64 (20210203_05:24) container.
To enable SSH, run: apt install openssh-server
No default root or user password are set by LXC.
$ cd ~/.local/share/lxc
$ tree -L 2 .
.
└── bullseye-user
├── config
└── rootfs
$ cd bullseye-user
$ ls -la rootfs
total 84
drwxr-xr-x 21 100000 100000 4096 Feb 3 14:29 .
drwxrwx--- 3 100000 osamu 4096 Feb 13 18:20 ..
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:27 bin
drwxr-xr-x 2 100000 100000 4096 Jul 9 2019 boot
drwxr-xr-x 3 100000 100000 4096 Feb 13 07:44 dev
drwxr-xr-x 41 100000 100000 4096 Feb 13 23:55 etc
drwxr-xr-x 2 100000 100000 4096 Jul 9 2019 home
drwxr-xr-x 10 100000 100000 4096 Feb 3 14:26 lib
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:26 lib64
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:26 media
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:26 mnt
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:26 opt
drwxr-xr-x 2 100000 100000 4096 Jul 9 2019 proc
drwx------ 2 100000 100000 4096 Feb 3 14:26 root
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:27 run
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:27 sbin
drwxr-xr-x 2 100000 100000 4096 Feb 3 14:26 srv
drwxr-xr-x 2 100000 100000 4096 Jul 9 2019 sys
drwxrwxrwt 7 100000 100000 4096 Feb 13 23:59 tmp
drwxr-xr-x 11 100000 100000 4096 Feb 3 14:26 usr
drwxr-xr-x 11 100000 100000 4096 Feb 3 14:26 var
なるほど0(root)であるUIDやGIDが、LXCの外から見ると100000にマップされています。
ここで単純にsudoを使った特権ユーザーのようにlxc-start
してコンテナ環境を
立ち上げようとしてもこけます。ここ、要注意です!
ここは以下の様にlxcパッケージのREADME.Debian
の指示どおりsystemd-run を
–property=Delegate=yes 等とともに用いて実行すればうまく立ち上がります。
$ systemd-run --scope --quiet --user --property=Delegate=yes lxc-start -n bullseye-user
$ lxc-ls -f
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
bullseye-user RUNNING 0 - 10.0.3.224 - true
$ lxc-attach -n bullseye-user
root@bullseye-user:/#
私はGNOME terminal からの実行なので、lxc-attach
等の他のコマンドは
systemd-run ...
をつけなくても特権ユーザーによるLXCを使っての仮想環境
操作同様に動きました。
ちなみにこれをキーボードで毎回叩くのは大変なので、Bashの初期化ファイルで 以下を定義して使うことにしました。
alias cgdo="systemd-run --scope --quiet --user --property=Delegate=yes"
また、非特権LXC仮想環境でも、仮想環境の設定ファイルconfig
を前記の特権LXC
仮想環境と同様にlxc.mount.entry
の設定を追加設定することでデーター共有がで
きました。
確かに、lxc-attach
をしてファイルを操作すればコンテナ内のUIDやGIDと整合した
ファイルが生成され問題ないのですが、コンテナ内でコマンド自身が提供されない
場合は意外と面倒です。そんな時に便利なのは、ホスト側に居るままで
User Namespacesだけを非特権LXCコンテナ内に切り替えられるlxc-usernsexec
(1)
コマンドです。
例えば、上記のbullseye-userコンテナの例の続きで、
~/.local/share/lxc/bullseye-user
にいながらコンテナ内のUIDやGIDの
特権ユーザー(UID=0, GID=0)となりファイルリスティングするには単純に
以下とします。
$ lxc-usernsexec -- bash
$ ls -la rootfs
total 84
drwxr-xr-x 21 root root 4096 Feb 3 14:29 .
drwxrwx--- 3 root nogroup 4096 Feb 13 18:20 ..
drwxr-xr-x 2 root root 4096 Feb 3 14:27 bin
drwxr-xr-x 2 root root 4096 Jul 9 2019 boot
drwxr-xr-x 3 root root 4096 Feb 13 07:44 dev
drwxr-xr-x 41 root root 4096 Feb 13 23:55 etc
drwxr-xr-x 2 root root 4096 Jul 9 2019 home
drwxr-xr-x 10 root root 4096 Feb 3 14:26 lib
drwxr-xr-x 2 root root 4096 Feb 3 14:26 lib64
drwxr-xr-x 2 root root 4096 Feb 3 14:26 media
drwxr-xr-x 2 root root 4096 Feb 3 14:26 mnt
drwxr-xr-x 2 root root 4096 Feb 3 14:26 opt
drwxr-xr-x 2 root root 4096 Jul 9 2019 proc
drwx------ 2 root root 4096 Feb 3 14:26 root
drwxr-xr-x 2 root root 4096 Feb 3 14:27 run
drwxr-xr-x 2 root root 4096 Feb 3 14:27 sbin
drwxr-xr-x 2 root root 4096 Feb 3 14:26 srv
drwxr-xr-x 2 root root 4096 Jul 9 2019 sys
drwxrwxrwt 7 root root 4096 Feb 13 23:59 tmp
drwxr-xr-x 11 root root 4096 Feb 3 14:26 usr
drwxr-xr-x 11 root root 4096 Feb 3 14:26 var
コンテナ内の0(root)であるUIDやGIDが、LXCの外から見ると100000にマップ
されていたのが、lxc-usernsexec
を用いて立ち上げたコンテナ外のbash
シェル環境からもコンテナ内のUIDやGIDになっています。
ちなみに非特権LXCのファイルの場所は以下です。
~/.config/lxc/default.conf
– 初期設定~/.cache/lxc/download/debian/...
, … – 最初にダウンロードしたデーター~/.local/share/lxc/[container_name]/rootfs/
– 各コンテナのファイルシステム~/.local/share/lxc/[container_name]/config
– 各コンテナの初期化設定~/.local/share/lxc/[container_name]/[ephemerical_conatiner_name]
–lxc-copy
でephemericalコンテナーを作成すると作成される模様。ephemericalコンテナーが正常に終了消去されないとと、これが残ってしまう模様。/run/user/1000/lxc/lock/home/osamu/.local/share/lxc
– Lock files
また、システムのCgroupの内容状況は、systemd-cgls
コマンドでリストできます。
LXC仮想環境利用のTips
カーネルのLXCサポートの確認
現在のカーネルが lxc に必要な機能をサポートしているか確認は
lxc-checkconfig
(1)を実行します。
$ lxc-checkconfig
LXC version 4.0.6
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-5.10.0-3-amd64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
--- Control groups ---
Cgroups: enabled
Cgroup v1 mount points:
Cgroup v2 mount points:
/sys/fs/cgroup
Cgroup v1 systemd controller: missing
Cgroup v1 freezer controller: missing
Cgroup namespace: required
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled, loaded
Macvlan: enabled, not loaded
Vlan: enabled, not loaded
Bridges: enabled, loaded
Advanced netfilter: enabled, loaded
CONFIG_NF_NAT_IPV4: missing
CONFIG_NF_NAT_IPV6: missing
CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, loaded
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
FUSE (for use with lxcfs): enabled, loaded
--- Checkpoint/Restore ---
checkpoint restore: enabled
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: enabled
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: enabled
CONFIG_NETLINK_DIAG: enabled
File capabilities:
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
Debianパッケージ作成
Debianパッケージ作成に必要なパッケージは正確にはDebian Policyで規定されています。ただ実務的には、 LXCを以下の手順で使うと、ホストシステムをsid環境にして不安定にすることなく作業がはかどります。
まず、ベースとなるsidで作成されたLXC仮想環境に以下のパッケージを導入します。 (前述の手順です)
build-essential
devscripts
debhelper
さらに、lxc-copy
を使い、毎回使い捨てのLXC仮想環境を準備し、その中でホストシステムと
共有されたディレクトリー内に置かれたDebianソースのdebian/control
に基づき、パッケージビルドに
必要なパッケージを追加導入します。devscripts
パッケージに含まれるmk-build-deps
コマンドが、
この追加導入操作に便利です。特に-i
オプションを使うと便利です。この際、mk-build-deps
実行前に、最新システム環境を確保するapt update; apt full-upgrade
を実行する
のが好ましいでしょう。
これなら、pbuilder
等の複雑なコマンドを覚えなくとも作業がはかどります。
Debianパッケージのデバグ
Debianパッケージのデバグの際には、毎回パッケージ依存関係確認のためにインストールするのは
無駄なので、使い捨てではなく必要な全パッケージがインストールされたLXC仮想環境を準備し、
それをベースにlxc-copy
を使い、毎回使い捨てのLXC仮想環境を準備した方が効率的です。
PDFファイル作成にtexlive-full
等の巨大パッケージが利用される際には、この配慮は重要です。
SSH接続
ホスト側から普通のリモートサーバー同様に操作するには、LXC仮想環境には以下のパッケージを 最低限導入するのがいい。
- コンテナ上の
openssh-server
: 公開鍵認証でパスワード無しで接続用に導入・設定します。 - コンテナ上の
sudo
: rootにsshで入れない際にsudoerにユーザーをいれ対応するために導入・設定します。 - ホスト上の
/etc/hosts
: 各LXCのIPにホスト名を定義し、アクセス操作をしやすくする。
Python2 プログラムの実行
Debian bullseye 11 以降はPython3のみのサポートとなるので、古いPython2 プログラムを 実行しその動作を確認するには、buster環境で作成されたLXC仮想環境を準備すると便利です。
参考情報
- Upstream: https://linuxcontainers.org/
- Debian:
/usr/share/doc/lxc/README.Debian
(最新、重要) - Debian: https://wiki.debian.org/LXC (slightly outdated docs)
- Ubuntu: https://ubuntu.com/server/docs/containers-lxc (semi-upstream, recent LXC 4.0)
- SUSE: https://documentation.suse.com/sles/15-SP1/html/SLES-all/part-virt-lxc.html (16 July 2018)
Previous Post | Top | Next Post |