Ubuntu

userns容器啟動失敗,如何追查原因?

  • June 15, 2015

在 Ubuntu 14.04 上使用以下命令行創建使用者(非特權)LXC 容器時:

lxc-create -n test1 -t download -- -d $(lsb_release -si|tr 'A-Z' 'a-z') -r $(lsb_release -sc) -a $(dpkg --print-architecture)

並且(不接觸創建的配置文件)然後嘗試使用以下命令啟動它:

lxc-start -n test1 -l DEBUG

它失敗。日誌文件向我顯示:

lxc-start 1420149317.700 INFO     lxc_start_ui - using rcfile /home/user/.local/share/lxc/test1/config
lxc-start 1420149317.700 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.701 INFO     lxc_confile - read uid map: type u nsid 0 hostid 100000 range 65536
lxc-start 1420149317.701 INFO     lxc_confile - read uid map: type g nsid 0 hostid 100000 range 65536
lxc-start 1420149317.701 WARN     lxc_log - lxc_log_init called with log already initialized
lxc-start 1420149317.701 INFO     lxc_lsm - LSM security driver AppArmor
lxc-start 1420149317.701 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/2' (5/6)
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/7' (7/8)
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/8' (9/10)
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/10' (11/12)
lxc-start 1420149317.702 INFO     lxc_conf - tty's configured
lxc-start 1420149317.702 DEBUG    lxc_start - sigchild handler set
lxc-start 1420149317.702 DEBUG    lxc_console - opening /dev/tty for console peer
lxc-start 1420149317.702 DEBUG    lxc_console - using '/dev/tty' as console
lxc-start 1420149317.702 DEBUG    lxc_console - 14946 got SIGWINCH fd 17
lxc-start 1420149317.702 DEBUG    lxc_console - set winsz dstfd:14 cols:118 rows:61
lxc-start 1420149317.905 INFO     lxc_start - 'test1' is initialized
lxc-start 1420149317.906 DEBUG    lxc_start - Not dropping cap_sys_boot or watching utmp
lxc-start 1420149317.906 INFO     lxc_start - Cloning a new user namespace
lxc-start 1420149317.906 INFO     lxc_cgroup - cgroup driver cgmanager initing for test1
lxc-start 1420149317.907 ERROR    lxc_cgmanager - call to cgmanager_create_sync failed: invalid request
lxc-start 1420149317.907 ERROR    lxc_cgmanager - Failed to create hugetlb:test1
lxc-start 1420149317.907 ERROR    lxc_cgmanager - Error creating cgroup hugetlb:test1
lxc-start 1420149317.907 INFO     lxc_cgmanager - cgroup removal attempt: hugetlb:test1 did not exist
lxc-start 1420149317.908 INFO     lxc_cgmanager - cgroup removal attempt: perf_event:test1 did not exist
lxc-start 1420149317.908 INFO     lxc_cgmanager - cgroup removal attempt: blkio:test1 did not exist
lxc-start 1420149317.908 INFO     lxc_cgmanager - cgroup removal attempt: freezer:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: devices:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: memory:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: cpuacct:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: cpu:test1 did not exist
lxc-start 1420149317.910 INFO     lxc_cgmanager - cgroup removal attempt: cpuset:test1 did not exist
lxc-start 1420149317.910 INFO     lxc_cgmanager - cgroup removal attempt: name=systemd:test1 did not exist
lxc-start 1420149317.910 ERROR    lxc_start - failed creating cgroups
lxc-start 1420149317.910 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.910 ERROR    lxc_start - failed to spawn 'test1'
lxc-start 1420149317.910 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.910 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.910 ERROR    lxc_start_ui - The container failed to start.
lxc-start 1420149317.910 ERROR    lxc_start_ui - Additional information can be obtained by setting the --logfile and --logpriority options.

現在我在這裡看到兩個錯誤,後者可能是前者的結果,即:

lxc_start - 創建 cgroup 失敗

但是,我看到/sys/fs/cgroup已安裝:

$ mount|grep cgr
none on /sys/fs/cgroup type tmpfs (rw)

cgmanager安裝:

$ dpkg -l|awk '$1 ~ /^ii$/ && /cgmanager/ {print $2 " " $3 " " $4}'
cgmanager 0.24-0ubuntu7 amd64
libcgmanager0:amd64 0.24-0ubuntu7 amd64

注意:我的主機預設仍為upstart.

如果有任何疑問,核心支持cgroups

$ grep CGROUP /boot/config-$(uname -r)
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NET_CLS_CGROUP=m
CONFIG_NETPRIO_CGROUP=m

注意:我的主機預設仍為upstart.

事實證明,令人驚訝的是,這是一個特定於 Ubuntu 的東西。


原因

問題:雖然核心已cgroups啟用(檢查grep CGROUP /boot/config-$(uname -r))並cgmanager正在執行,但沒有特定於我的使用者的 cgroup。您可以通過以下方式檢查:

$ cat /proc/self/cgroup
11:hugetlb:/
10:性能事件:/
9:blkio://
8:冷凍:/
7:設備:/
6:記憶體:/
5:cpuacct:/
4:中央處理器:/
3:名稱=系統:/
2:cpuset:/

如果您的 UID 在每個相關行中都給出,那沒關係,但如果沒有定義 cgroup,則每行的第二個冒號後只會有一個斜杠。

我的問題是特定於啟動非特權容器。我可以很好地啟動特權容器。

原來我的問題與郵件列表中的這個執行緒lxc-users密切相關。

補救

在 Ubuntu 14.04upstart上是預設設置,而不是systemd. systemd因此,預設情況下不會安裝將安裝在基於 - 的發行版上的某些組件。

除了我必須安裝的兩個軟體包之外cgmanager,我還必須安裝兩個軟體包才能超出我的問題中顯示的錯誤:cgroup-binlibpam-systemd. 坦率地說,我不是 100% 肯定前者是嚴格需要的,所以你可以試著把它排除在外並在這裡發表評論。

安裝軟體包並重新啟動後,您應該會id -u在輸出中看到您的 UID(此處為 1000):

$ cat /proc/self/cgroup
11:hugetlb:/user/1000.user/1.session
10:perf_event:/user/1000.user/1.session
9:blkio:/user/1000.user/1.session
8:冷凍機:/user/1000.user/1.session
7:設備:/user/1000.user/1.session
6:記憶體:/user/1000.user/1.session
5:cpuacct:/user/1000.user/1.session
4:cpu:/user/1000.user/1.session
3:name=systemd:/user/1000.user/1.session
2:cpuset:/user/1000.user/1.session

之後,嘗試啟動來賓容器時的錯誤變為(為簡潔起見進行了修剪):

lxc-start 1420160065.383 資訊 lxc_cgroup - cgroup 驅動程序 cgmanager 為 test1 初始化
lxc-start 1420160065.419 錯誤 lxc_start - 未能創建配置的網路
lxc-start 1420160065.446 錯誤 lxc_start - 未能生成“test1”
lxc-start 1420160065.451 錯誤 lxc_start_ui - 容器無法啟動。

所以仍然沒有成功,但我們更近了一步。

上面連結的lxc-users執行緒指向/etc/systemd/logind.conf沒有提到三個控制器net_clsnet_priodebug。對我來說,只有最後一個失去了。但是,更改後您必須重新登錄,因為更改會在創建登錄會話時生效。

LXC 的一位作者的這篇博文給出了下一步:

您的使用者,雖然它可以創建新的使用者命名空間,其中它將是 uid 0 並且將對與該命名空間綁定的資源擁有一些 root 特權,但顯然不會在主機上被授予任何額外特權。

其中之一是在主機上創建新的網路設備或更改網橋配置。為了解決這個問題,我們編寫了一個名為“lxc-user-nic”的工具,它是 LXC 1.0 中唯一的 SETUID 二進制部分,它執行一個簡單的任務。它解析配置文件並根據其內容為使用者創建網路設備並橋接它們。為防止濫用,您可以限制使用者可以請求的設備數量以及可以將它們添加到哪個網橋。

一個例子是我自己的 /etc/lxc/lxc-usernet 文件:

stgraber veth lxcbr0 10

這聲明使用者“stgraber”最多可以創建 10 個 veth 類型的設備並將其添加到名為 lxcbr0 的網橋中。

在核心中的使用者命名空間和 setuid 工具提供的功能之間,我們已經獲得了執行大多數非特權發行版所需的一切。

如果您的使用者有sudo權限並且您正在使用 Bash,請使用以下命令:

echo "$(whoami) veth lxcbr0 10"|sudo tee -a /etc/lxc/lxc-usernet

並確保類型 ( veth) 與容器配置中的類型匹配,並且橋 ( lxcbr0) 已配置並啟動。

現在我們得到另一組錯誤:

lxc-start 1420192192.775 資訊 lxc_start - 複製一個新的使用者命名空間
lxc-start 1420192192.775 資訊 lxc_cgroup - cgroup 驅動程序 cgmanager 為 test1 初始化
lxc-start 1420192192.923 注意 lxc_start - 在新使用者命名空間中切換到 gid/uid 0
lxc-start 1420192192.923 錯誤 lxc_start - 權限被拒絕 - 無法訪問 /home/user。請授予它“x”訪問權限,或為容器根目錄添加 ACL。
lxc-start 1420192192.923 錯誤 lxc_sync - 無效的序列號 1。預期 2
lxc-start 1420192192.954 錯誤 lxc_start - 未能生成“test1”
lxc-start 1420192192.959 錯誤 lxc_start_ui - 容器無法啟動。

厲害,可以修。與第一個執行緒相同的主角的另一個lxc-users執行緒鋪平了道路。

現在必須進行快速測試sudo chmod -R o+X $HOME,但 ACL 在這裡也是一個可行的選擇。YMMV。

引用自:https://unix.stackexchange.com/questions/176973