在無根環境中的基本設置和使用Podman 在允許沒有root許可權的用戶運行Podman之前,管理員必須安裝或構建Podman並完成以下配置。 cgroup V2Linux內核功能允許用戶限制普通用戶容器可以使用的資源,如果使用cgroupV2啟用了運行Podman的Linux發行版,則可能需要更改默 ...
在無根環境中的基本設置和使用Podman
目錄
在允許沒有root許可權的用戶運行Podman之前,管理員必須安裝或構建Podman並完成以下配置。
cgroup V2Linux內核功能允許用戶限制普通用戶容器可以使用的資源,如果使用cgroupV2啟用了運行Podman的Linux發行版,則可能需要更改預設的OCI運行時。某些較舊的版本runc不適用於cgroupV2,必須切換到備用OCI運行時crun。
[root@localhost ~]# dnf -y install crun //centos8系統自帶
[root@localhost ~]# vim /usr/share/containers/containers.conf
# Default OCI runtime
#
runtime = "crun"//更改為這個
#runtime = "runc"//註釋掉
[root@localhost ~]# podman run -d --name web nginx
//拉取鏡像並啟動web容器
Resolving "nginx" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 186b1aaa4aa6 done
Copying blob b4df32aa5a72 done
Copying blob a9edb18cadd1 done
Copying blob 589b7251471a done
Copying blob a2abf6c4d29d done
Copying blob a0bcbecc962e done
Copying config 605c77e624 done
Writing manifest to image destination
Storing signatures
2ec76edba3d4bd735765edde236783d0ede72cbd81cc26be96dd9045fc4fd75a
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ec76edba3d4 docker.io/library/nginx:latest nginx -g daemon o... 59 seconds ago Up 58 seconds ago web
[root@localhost ~]# podman inspect web |grep -i ociruntime
"OCIRuntime": "crun",
安裝slirp4netns和fuse-overlayfs
在普通用戶環境中使用Podman時,建議使用fuse-overlayfs而不是VFS文件系統,至少需要版本0.7.6。現在新版本預設就是了。
[root@localhost ~]# dnf -y install slirp4netns
[root@localhost ~]# dnf -y install fuse-overlayfs
[root@localhost ~]# vim /etc/containers/storage.conf
mount_program = "/usr/bin/fuse-overlayfs" //取消註釋
subuid和subgid配置
Podman要求運行它的用戶在/ etc / subuid和/ etc / subgid文件中列出一系列UID,shadow-utils或newuid包提供這些文件
[root@localhost ~]# dnf -y install shadow-utils
//可以在/etc/subuid和/etc/subgid查看,每個用戶的值必須唯一且沒有任何重疊。
[root@localhost ~]# useradd lnh
[root@localhost ~]# useradd lnh2
[root@localhost ~]# cat /etc/subuid
lnh:100000:65536
lnh2:165536:65536
[root@localhost ~]# cat /etc/subgid
lnh:100000:65536
lnh2:165536:65536
啟動非特權ping
[root@localhost ~]# sysctl -w "net.ipv4.ping_group_range=0 200000"
net.ipv4.ping_group_range = 0 200000
//0 200000就是從100000開始,到200000區間內的用戶都可使用podman
也可以在/etc/sysctl.conf裡面修改配置文件net.ipv4.ping_group_range = 0 200000使其永久生效
這個文件的格式是 USERNAME:UID:RANGE中/etc/passwd或輸出中列出的用戶名getpwent。
為用戶分配的初始 UID。
為用戶分配的 UID 範圍的大小。
該usermod程式可用於為用戶分配 UID 和 GID,而不是直接更新文件。
[root@localhost ~]# usermod --add-subuids 200000-201000 --add-subgids 200000-201000 lnh
[root@localhost ~]# cat /etc/subuid
lnh:100000:65536
lnh2:165536:65536
lnh:200000:1001
[root@localhost ~]# cat /etc/subgid
lnh:100000:65536
lnh2:165536:65536
lnh:200000:100
也可以刪除:
[root@localhost ~]# usermod --del-subuids 100000-165536 --del-subgids 100000-165536 lnh
[root@localhost ~]# cat /etc/subuid
lnh2:165536:65536
lnh:200000:1001
[root@localhost ~]# cat /etc/subgid
lnh2:165536:65536
lnh:200000:1001
用戶配置文件
三個主要的配置文件是container.conf、storage.conf和registries.conf。用戶可以根據需要修改這些文件。
container.conf
/usr/share/containers/containers.conf
/etc/containers/containers.conf
$HOME/.config/containers/containers.conf //優先順序最高
//如果它們以該順序存在。每個文件都可以覆蓋特定欄位的前一個文件
配置storage.conf文件
1./etc/containers/storage.conf
2.$HOME/.config/containers/storage.conf
在普通用戶中/etc/containers/storage.conf的一些欄位將被忽略
[root@localhost ~]# vim /etc/containers/storage.conf
# Default Storage Driver, Must be set for proper operation.
driver = "overlay" //此處改為overlay
mount_program = "/usr/bin/fuse-overlayfs" //取消註釋
如果版本為8以下,則需要做以下操作:
[root@localhost ~]# sysctl user.max_user_namespaces=15000
或者
[root@localhost ~]# vim /etc/sysctl.conf
user.max_user_namepaces=15000
在普通用戶中這些欄位預設
[root@localhost ~]# vim /etc/containers/storage.conf
# Temporary storage location
runroot = "/run/containers/storage"
# Primary Read/Write location of container storage
graphroot = "/var/lib/containers/storage"
registries.conf
配置按此順序讀入,這些文件不是預設創建的,可以從/usr/share/containers或複製文件/etc/containers併進行修改。
1./etc/containers/registries.conf
2./etc/containers/registries.d/*
3.HOME/.config/containers/registries.conf
授權文件
此文件裡面寫了docker賬號的密碼,以加密方式顯示
[root@localhost ~]# podman login
Username: lvnanhai66
Password:
Login Succeeded!
[root@localhost ~]# cat /run/user/0/containers/auth.json
{
"auths": {
"docker.io": {
"auth": "bHZuYW5oYWk2NjoxOTk5MzI0cXdlcnQxMjM0"
}
}
}
普通用戶是無法看見root用戶的鏡像的
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx latest 605c77e624dd 7 months ago 146 MB
[root@localhost ~]# su - lnh
Last login: Wed Aug 17 11:28:29 CST 2022 on pts/0
[lnh@localhost ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
[lnh@localhost ~]$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
捲
容器與root用戶一起運行,則root容器中的用戶實際上就是主機上的用戶。
UID GID是在/etc/subuid和/etc/subgid等中用戶映射中指定的第一個UID GID。
如果普通用戶的身份從主機目錄掛載到容器中,併在該目錄中以根用戶身份創建文件,則會看到它實際上是你的用戶在主機上擁有的。
使用捲
[lnh2@localhost ~]$ mkdir /home/lnh2/data
[lnh2@localhost ~]$ podman run -dit --name web -v /home/lnh2/data/:/data:Z -p 8080:80 httpd
Resolving "httpd" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob dcc4698797c8 done
Copying blob d982c879c57e done
Copying blob a2abf6c4d29d done
Copying blob 41c22baa66ec done
Copying blob 67283bbdd4a0 done
Copying config dabbfbe0c5 done
Writing manifest to image destination
Storing signatures
b8d77d3d51351a8de4d2ae1eaada927230db901184bac7463b62db24d256d272
[lnh2@localhost ~]$ podman exec -it web /bin/bash
root@b8d77d3d5135:/usr/local/apache2# cd
root@f0eb826145ed:~# cd /
root@f0eb826145ed:/# ls
bin data etc lib media opt root sbin sys usr
boot dev home lib64 mnt proc run srv tmp var
root@f0eb826145ed:/# cd data/
root@f0eb826145ed:/data# touch 123
root@f0eb826145ed:/data# ls -l
total 0
-rw-r--r--. 1 root root 0 Aug 17 10:06 123
在主機上查看
[root@localhost ~]# su - lnh2
Last login: Wed Aug 17 18:03:07 CST 2022 on pts/0
[lnh2@localhost ~]$ cd /home/lnh2/data/
[lnh2@localhost data]$ ls
123
[lnh2@localhost data]$ echo "hello lnh" >> 123
[lnh2@localhost data]$ cat 123
hello lnh
容器里查看
root@f0eb826145ed:/data# ls
123
root@f0eb826145ed:/data# cat 123
hello lnh
將容器中的目錄和文件的屬主和屬組修改為lnh2
[lnh2@localhost ~]$ podman rm -f -l //刪除最新最近的容器
f0eb826145edf810c1c101be1746d44dc1f1ab7619212c2990c5e29465a54e7e
[lnh2@localhost ~]$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[lnh2@localhost ~]$ ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[lnh2@localhost ~]$ podman run -itd --name web --userns=keep-id -v $(pwd)/data:/data:Z busybox
//只要在運行容器的時候加上一個--userns=keep-id即可。保持一直id
Resolved "busybox" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/busybox:latest...
Getting image source signatures
Copying blob 5cc84ad355aa done
Copying config beae173cca done
Writing manifest to image destination
Storing signatures
c1944ff72cdce194558a399929a0dac45758d619870d8211cc967d77df5e0ac0
[lnh2@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1944ff72cdc docker.io/library/busybox:latest sh 6 seconds ago Up 6 seconds ago web
[lnh2@localhost ~]$ podman exec -it web /bin/sh
~ $ ls -l
total 16
drwxr-xr-x 2 root root 12288 Dec 29 2021 bin
drwxrwxr-x 2 lnh2 lnh2 17 Aug 17 10:06 data
drwxr-xr-x 5 root root 360 Aug 17 10:13 dev
drwxr-xr-x 3 root root 93 Aug 17 10:13 etc
drwxr-xr-x 2 nobody nobody 6 Dec 29 2021 home
dr-xr-xr-x 244 nobody nobody 0 Aug 17 10:13 proc
drwx------ 2 root root 6 Dec 29 2021 root
drwxr-xr-x 3 root root 62 Aug 17 10:13 run
dr-xr-xr-x 13 nobody nobody 0 Aug 15 02:04 sys
drwxrwxrwt 2 root root 6 Dec 29 2021 tmp
drwxr-xr-x 3 root root 18 Dec 29 2021 usr
drwxr-xr-x 4 root root 30 Dec 29 2021 var
//可以看見/data的所屬主所屬組都是lnh2
使用普通用戶映射容器埠時會報“ permission denied”的錯誤
[lnh2@localhost ~]$ podman run -itd --name web -p 80:80 httpd
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied
普通用戶可以映射>= 1024的埠
[lnh2@localhost ~]$ podman run -itd --name web -p 1024:80 httpd
1754f938a722e57e1a9f4d545ed24a243ecb1ddd9229ebf042d976f3ff36ef03
[lnh2@localhost ~]$ ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:1024 *:*
LISTEN 0 128 [::]:22 [::]:*
配置echo ‘net.ipv4.ip_unprivileged_port_start=80’ >> /etc/sysctl.conf後可以映射大於等於80的埠
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ip_unprivileged_port_start = 80 //在最後面添加
[root@localhost ~]# sysctl -p //使其立即生效
net.ipv4.ip_unprivileged_port_start = 80
將之前的80埠還有容器都刪除
[root@localhost ~]# ss -antl //確保沒有80埠
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@localhost ~]# podman ps -a //確保沒有正在運行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
進行測試:
[root@localhost ~]# podman run -itd --name web -p 80:80 httpd
Resolving "httpd" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob 41c22baa66ec done
Copying blob dcc4698797c8 done
Copying blob a2abf6c4d29d done
Copying blob 67283bbdd4a0 done
Copying blob d982c879c57e done
Copying config dabbfbe0c5 done
Writing manifest to image destination
Storing signatures
6f42e56db56a6ccb791b12bf0b482e13bb1d14747828e3a95657a3745c31b94f