上一篇使用runc與oci-image-tool運行容器中雖然成功使用
runc
運行起來了容器,但遇到了不少問題。本文再次講述使用runc運行alpine linux容器,並解決上一次出現的相關問題。
注: 本文命令均在Ubuntu 18.04x64下運行通過
下載 解壓鏡像
skopeo與oci-image-tool分別用來下載與解壓鏡像,Ubuntu上兩個工具需要從源碼編譯安裝,而且需要提前配置好Go語言環境。
- 使用
skopeo copy docker://alpine:latest oci:alpine
下載鏡像,skopeo的安裝與使用參考Skopeo-Github,運行結果eric@ubuntu:~/images_tmp$ skopeo copy docker://alpine:latest oci:alpine Getting image source signatures Copying blob 89d9c30c1d48 done Copying config 759e71f0d3 done Writing manifest to image destination Storing signatures
- 使用
oci-image-tool create --ref platform.os=linux alpine alpine-bundle
製作符合OCI規範的鏡像,oci-image-tool的安裝與使用參考image-tools Github
rootfs爲根文件系統,eric@ubuntu:~/images_tmp$ ls -l alpine-bundle/ total 8 -rw-rw-r-- 1 eric eric 217 Nov 9 11:51 config.json drwxr-x--- 19 eric eric 4096 Nov 9 11:51 rootfs
config.json
爲符合runtime-spec
的配置文件
配置 運行
注: 此處要運行的是具有root權限的容器,因此不創建新的User Namespace
已知信息
-
capabilities權限信息: 容器必須具有權限去執行操作,config.json文件中可以現在容器內部權限
-
mount掛載信息: 系統級容器需要掛載必備的文件系統,如
proc sys cgroup
等 -
文件系統中目錄、文件的可讀可執行權限: 從根目錄到容器文件系統內的所有文件夾,以及文件系統內的所有文件/文件夾(
/home/.../alpine-bundle/rootfs/*
)需要至少具有rwxrwxr-x(775)權限,否則可能會遇到各種各樣的permission denied
,可以參考Can’t change to home directory, unable-to-su-with-root-bin-bash-permission-denied的第二個回答
具體過程
-
刪除image-tool生成的
config.json
,該json文件缺少必要的mount、capabilities等信息 -
使用
runc spec
命令生成一個新的config.json
文件,關於runc的使用,參考runc-Github -
修改
config.json
文件,如下爲修改完後的文件,參考rumtime-spec:{ "ociVersion": "1.0.1-dev", "process": { "terminal": true, "user": { "uid": 0, "gid": 0 }, "args": [ "/bin/ash" ], "env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "cwd": "/", "capabilities": { "bounding": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE", "CAP_SETUID", "CAP_SETGID", "CAP_CHOWN", "CAP_SYS_ADMIN", "CAP_SETFCAP", "CAP_SETPCAP", "CAP_FOWNER" ], "effective": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE", "CAP_SETUID", "CAP_SETGID", "CAP_CHOWN", "CAP_SYS_ADMIN", "CAP_SETFCAP", "CAP_SETPCAP", "CAP_FOWNER" ], "inheritable": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE", "CAP_SETUID", "CAP_SETGID", "CAP_CHOWN", "CAP_SYS_ADMIN", "CAP_SETFCAP", "CAP_SETPCAP", "CAP_FOWNER" ], "permitted": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE", "CAP_SETUID", "CAP_SETGID", "CAP_CHOWN", "CAP_SYS_ADMIN", "CAP_SETFCAP", "CAP_SETPCAP", "CAP_FOWNER" ], "ambient": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE", "CAP_SETUID", "CAP_SETGID", "CAP_CHOWN", "CAP_SYS_ADMIN", "CAP_SETFCAP", "CAP_SETPCAP", "CAP_FOWNER" ] } }, "root": { "path": "rootfs", "readonly": false }, "mounts": [ { "destination": "/proc", "type": "proc", "source": "proc" }, { "destination": "/dev", "type": "tmpfs", "source": "tmpfs", "options": [ "nosuid", "strictatime", "mode=755", "size=65536k" ] }, { "destination": "/dev/pts", "type": "devpts", "source": "devpts", "options": [ "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5" ] }, { "destination": "/dev/shm", "type": "tmpfs", "source": "shm", "options": [ "nosuid", "noexec", "nodev", "mode=1777", "size=65536k" ] }, { "destination": "/dev/mqueue", "type": "mqueue", "source": "mqueue", "options": [ "nosuid", "noexec", "nodev" ] }, { "destination": "/sys", "type": "sysfs", "source": "sysfs", "options": [ "nosuid", "noexec", "nodev", "ro" ] }, { "destination": "/sys/fs/cgroup", "type": "cgroup", "source": "cgroup", "options": [ "nosuid", "noexec", "nodev", "relatime", "ro" ] } ], "linux": { "namespaces": [ { "type": "pid" }, { "type": "network" }, { "type": "ipc" }, { "type": "uts" }, { "type": "mount" } ] } }
主要在於修改capabilities中的一些
CAP_SETUID CAP_SETGID CAP_FOWNER
權限以及mount中的信息 -
確保路徑
/.../alpine-bundle
的文件夾都有執行權限,沒有的話可以使用chmod +x file_dir_name
命令添加 -
確保
alpine-bundle/
下的所有文件都有必須的執行權限,這裏我們直接chmod 775 -R alpine-bundle/
-
由於runc目前存在的問題fix permission denied,我們需要將
alpine-bundle
的owner改成root,執行chown root:root -R alpine-bundle/
,如下爲rootfs下的文件信息eric@ubuntu:~/images_tmp$ lsl alpine-bundle/rootfs/ total 68 drwxrwxr-x 2 root root 4096 Oct 21 21:39 bin drwxrwxr-x 2 root root 4096 Oct 21 21:39 dev ... drwxrwxr-x 7 root root 4096 Oct 21 21:39 usr drwxrwxr-x 11 root root 4096 Oct 21 21:39 var
-
在當前文件夾下
alpine-bundle/
下執行sudo runc run hello
,其中hello
爲容器的名字eric@ubuntu:~/images_tmp/alpine-bundle$ sudo runc run hello / # whoami root
-
執行
adduser
命令並login
/ # adduser jeff Changing password for jeff New password: Bad password: too short Retype password: passwd: password for jeff changed by root / # login jeff Password: Welcome to Alpine! The Alpine Wiki contains a large amount of how-to guides and general information about administrating Alpine systems. See <http://wiki.alpinelinux.org/>. You can setup the system with the command: setup-alpine You may change this message by editing /etc/motd. ubuntu:~$
能夠正常添加用戶並登陸了。
問題與解決
如果按照上述過程執行的話應該不會遇到問題,如下的問題是我在摸索過程中遇到的,感興趣的可以參考。
-
root運行
runc run
出現chdir
錯誤- 原因是目標目錄的owner與當前用戶(root)不同,一個解決方案是chown,參考#2086
-
alpine容器內添加用戶
adduser
出錯 -permission denied
- 容器權限 - 容器需要
setuid, setgid, setfcap
等權限 - 目錄可執行位 - 容器文件系統目錄及其父目錄需要有所有用戶的可執行權限(755: rwxrwxr-x)
- 容器權限 - 容器需要
-
alpine容器
login/su
出錯 -login: can't execute '/bin/ash': Permission denied
- 目錄可讀、可執行位(
chmod 755
),使用chmod 755 -R rootfs
命令將所有文件權限設爲可讀,參考Can’t change to home directory - 鏈接庫的可執行位,使用
ldd
命令查看鏈接庫,與1同理,參考unable-to-su-with-root-bin-bash-permission-denied的第二個回答
- 目錄可讀、可執行位(
總結
Linux的權限信息比較複雜,感興趣的可以參考手冊。本文主要以記錄爲主,歡迎評論。