使用 Podman 非常的简单,Podman 的指令跟 Docker 大多数都是相同的。下面我们来看几个常用的例子:
运行一个容器
[root@localhost ~]# podman run -d --name httpd docker.io/library/httpd
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob 80cb79a80bbe done
Copying blob aed046121ed8 done
Copying blob 80e368ef21fc done
Copying blob 1efc276f4ff9 done
Copying blob 4340e7be3d7f done
Copying config f2a976f932 done
Writing manifest to image destination
Storing signatures
68629de5b29d3858e79a3d5ac6b79541f65d07dcf25a00a3eb2f3ac611464e3f
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest f2a976f932ec 13 days ago 149 MB
列出运行的容器
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68629de5b29d docker.io/library/httpd:latest httpd-foreground 2 minutes ago Up 2 minutes ago httpd
注意:如果在ps命令中添加-a,Podman 将显示所有容器。
检查正在运行的容器
您可以“检查”正在运行的容器的元数据和有关其自身的详细信息。我们甚至可以使用 inspect 子命令查看分配给容器的 IP 地址。由于容器以无根模式运行,因此未分配 IP 地址,并且该值将在检查的输出中列为“无”。
[root@localhost ~]# podman inspect -l | grep Address
"IPAddress": "10.88.0.2",
"GlobalIPv6Address": "",
"MacAddress": "52:3e:89:1e:b4:da",
"LinkLocalIPv6Address": "",
"IPAddress": "10.88.0.2",
"GlobalIPv6Address": "",
"MacAddress": "52:3e:89:1e:b4:da",
[root@localhost ~]# curl 10.88.0.2
<html><body><h1>It works!</h1></body></html>
注意:-l 是最新容器的便利参数。可以使用容器的 ID 代替 -l。
[root@localhost ~]# podman logs -l
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.2. Set the 'ServerName' directive globally to suppress this message
[Mon Aug 15 06:09:30.579343 2022] [mpm_event:notice] [pid 1:tid 140622331190592] AH00489: Apache/2.4.54 (Unix) configured -- resuming normal operations
[Mon Aug 15 06:09:30.579732 2022] [core:notice] [pid 1:tid 140622331190592] AH00094: Command line: 'httpd -D FOREGROUND'
10.88.0.1 - - [15/Aug/2022:06:16:10 +0000] "GET / HTTP/1.1" 200 45
查看一个运行容器中的进程资源使用情况,可以使用top观察容器中的 nginx pid
[root@localhost ~]# podman top httpd
USER PID PPID %CPU ELAPSED TTY TIME COMMAND
root 1 0 0.000 10m33.840617117s ? 0s httpd -DFOR
www-data 7 1 0.000 10m33.840701395s ? 0s httpd -DFOR
www-data 8 1 0.000 10m33.840941476s ? 0s httpd -DFOR
www-data 9 1 0.000 10m33.841065999s ? 0s httpd -DFOR
停止一个运行中的容器 删除一个容器
[root@localhost ~]# podman stop -l
68629de5b29d3858e79a3d5ac6b79541f65d07dcf25a00a3eb2f3ac611464e3f
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ~]# podman rm -l
68629de5b29d3858e79a3d5ac6b79541f65d07dcf25a00a3eb2f3ac611464e3f
[root@localhost ~]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
新的特性 上传镜像
例如,如果我们想在 docker.io上分享我们新建的 Nginx 容器镜像,这很容易。首先登录码头:
[root@localhost nginx]# sudo yum -y install tree
[root@localhost nginx]# tree
.
├── Dockerfile
└── files
└── nginx-1.22.0.tar.gz
1 directory, 2 files
[root@localhost nginx]# cat Dockerfile
FROM docker.io/library/centos
ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.22.0.tar.gz /usr/src
RUN useradd -r -M -s /sbin/nologin nginx && \
yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make && \
mkdir -p /var/log/nginx && \
cd /usr/src/nginx-1.20.1 && \
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log && \
make && make install
CMD ["nginx","-g","daemon off"]
[root@localhost nginx]# podman build -t nginx .
[root@localhost nginx]# cd
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 5aaa7dd3ac7d 36 seconds ago 245 MB
docker.io/library/httpd latest f2a976f932ec 13 days ago 149 MB
docker.io/library/centos latest 5d0da3dc9764 11 months ago 239 MB
[root@localhost ~]# podman tag 5aaa docker.io/yijq200708/nginx:latest
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/yijq200708/nginx latest 5aaa7dd3ac7d 3 minutes ago 245 MB
docker.io/library/httpd latest f2a976f932ec 13 days ago 149 MB
docker.io/library/centos latest 5d0da3dc9764 11 months ago 239 MB
[root@localhost ~]# podman login docker.io
Username: yijq200708
Password:
Login Succeeded!
[root@localhost ~]# podman push docker.io/yijq200708/nginx:latest
Getting image source signatures
Copying blob adeea0d6c3d1 done
Copying blob 74ddd0ec08fa skipped: already exists
Copying config 5aaa7dd3ac done
Writing manifest to image destination
Storing signatures
总而言之,Podman 使查找、运行、构建和共享容器变得容易。
配置别名
如果习惯了使用 Docker 命令,可以直接给 Podman 配置一个别名来实现无缝转移。你只需要在 .bashrc 下加入以下行内容即可:
短时有效
[root@localhost ~]# alias docker='podman'
修改配置文件 永久有效
[root@localhost ~]# vim .bashrc
[root@localhost ~]# cat .bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias docker='podman'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
用户操作
在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置
cgroup V2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgroupV2启用了运行Podman的Linux发行版,则可能需要更改默认的OCI运行时。某些较旧的版本runc不适用于cgroupV2,必须切换到备用OCI运行时crun。
[root@localhost ~]# yum -y install crun
[root@localhost ~]# vi /usr/share/containers/containers.conf
# Default OCI runtime
#
runtime = "crun"
#runtime = "runc"
[root@localhost ~]# podman run -dit --name web -p 80:80 docker.io/library/nginx
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 1efc276f4ff9 skipped: already exists
Copying blob 05396a986fd3 done
Copying blob b1349eea8fc5 done
Copying blob 6a17c8e7063d done
Copying blob 27e0d286aeab done
Copying blob baf2da91597d done
Copying config b692a91e4e done
Writing manifest to image destination
Storing signatures
337dd668fd8de1218383fc68e2821d3129ab93e87d0c547b3d6e813399a439f4
[root@localhost ~]# podman inspect web | grep crun
"OCIRuntime": "crun",
"crun",
安装slirp4netns和fuse-overlayfs
在普通用户环境中使用Podman时,建议使用fuse-overlayfs而不是VFS文件系统,至少需要版本0.7.6。现在新版本默认就是了。
[root@localhost ~]# rpm -qa | grep slirp4netns
slirp4netns-1.1.8-1.module_el8.5.0+890+6b136101.x86_64
[root@localhost ~]# rpm -qa | grep fuse-overlayfs
fuse-overlayfs-1.7.1-1.module_el8.5.0+890+6b136101.x86_64
[root@localhost ~]# yum -y install slirp4netns
[root@localhost ~]# yum -y install fuse-overlayfs
[root@localhost ~]# vim /etc/containers/storage.conf
mount_program = "/usr/bin/fuse-overlayfs" //取消注释
/ etc / subuid和/ etc / subgid配置
[root@localhost ~]# yum -y install shadow-utils
[root@localhost ~]# ls /etc/sub
subgid subuid
[root@localhost ~]# useradd xx
[root@localhost ~]# cat /etc/subuid
xx:100000:65536
[root@localhost ~]# cat /etc/subgid
xx:100000:65536
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ping_group_range=0 200000 //大于100000这个就表示tom可以操作podman
[root@localhost ~]# sysctl -p
net.ipv4.ping_group_range = 0 200000
这个文件的格式是 USERNAME:UID:RANGE中/etc/passwd或输出中列出的用户名getpwent。
该usermod程序可用于为用户分配 UID 和 GID,而不是直接更新文件。
[root@localhost ~]# usermod --add-subuids 200000-201000 --add-subgids 200000-201000 xx
[root@localhost ~]# grep xx /etc/subuid /etc/subgid
/etc/subuid:xx:100000:65536
/etc/subuid:xx:200000:1001
/etc/subgid:xx:100000:65536
/etc/subgid:xx:200000:1001
用户配置文件
三个主要的配置文件是container.conf、storage.conf和registries.conf。用户可以根据需要修改这些文件。
container.conf
// 用户配置文件
[root@localhost ~]# cat /usr/share/containers/containers.conf
[root@localhost ~]# cat /etc/containers/containers.conf
[root@localhost ~]# cat ~/.config/containers/containers.conf //优先级最高
如果它们以该顺序存在。每个文件都可以覆盖特定字段的前一个文件。
配置storage.conf文件
1./etc/containers/storage.conf
2.$HOME/.config/containers/storage.conf
[root@localhost ~]# find / -name containers.conf
/usr/share/containers/containers.conf
[root@localhost ~]# find / -name storage.conf
/etc/containers/storage.conf
在普通用户中/etc/containers/storage.conf的一些字段
[root@localhost ~]# vim /etc/containers/storage.conf
mount_program = "/usr/bin/fuse-overlayfs"
driver = "overlay"
[root@localhost ~]# vim /etc/sysctl.conf
[root@localhost ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ping_group_range=0 200000
user.max_user_namespaces=15000
[root@localhost ~]# sysctl -p
net.ipv4.ping_group_range = 0 200000
user.max_user_namespaces = 15000
在普通用户中这些字段默认
graphroot="$HOME/.local/share/containers/storage"
runroot="$XDG_RUNTIME_DIR/containers"
registries.conf
配置按此顺序读入,这些文件不是默认创建的,可以从/usr/share/containers或复制文件/etc/containers并进行修改。
1./etc/containers/registries.conf
2./etc/containers/registries.d/*
3.HOME/.config/containers/registries.conf
[root@localhost ~]# find / -name registries.conf
/etc/containers/registries.conf
授权文件
此文件里面写了docker账号的密码,以加密方式显示
[root@localhost ~]# cat /run/user/0/containers/auth.json
{
"auths": {
"docker.io": {
"auth": "eWlqcTIwMDcwODoyMDAzMDQxNXlqcQ=="
}
}
普通用户是无法看见root用户的镜像的
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
337dd668fd8d docker.io/library/nginx:latest nginx -g daemon o... 40 minutes ago Up 40 minutes ago 0.0.0.0:80->80/tcp web
[root@localhost ~]# su - xx
Last login: Mon Aug 15 15:51:55 CST 2022 on pts/1
[xx@localhost ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
[xx@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
卷
使用卷
[root@localhost ~]# su - xx
Last login: Mon Aug 15 15:52:13 CST 2022 on pts/1
[xx@localhost ~]$ pwd
/home/xx
[xx@localhost ~]$ mkdir /home/xx/data
[xx@localhost ~]$ podman run -it -v "$(pwd)"/data:/data:Z busybox /bin/sh
/ # ls
bin data dev etc home proc root run sys tmp usr var
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ # cd /data/
/data # ls
/data # touch 1 2 3
/data # ls
1 2 3
/data # ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 15 08:00 1
-rw-r--r-- 1 root root 0 Aug 15 08:00 2
-rw-r--r-- 1 root root 0 Aug 15 08:00 3
在主机上查看
[xx@localhost ~]$ ll data/
total 0
-rw-r--r--. 1 xx xx 0 Aug 15 16:00 1
-rw-r--r--. 1 xx xx 0 Aug 15 16:00 2
-rw-r--r--. 1 xx xx 0 Aug 15 16:00 3
[xx@localhost ~]$ echo "hell world" >> 123
[xx@localhost ~]$ cat 123
hell world
容器里查看
/data # cat 123
hell world
//我们可以发现在容器里面的文件的属主和属组都属于root,那么如何才能让其属于tom用户呢?下面告诉你答案
/data # ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 15 08:00 1
-rw-r--r-- 1 root root 0 Aug 15 08:14 123
-rw-r--r-- 1 root root 0 Aug 15 08:00 2
-rw-r--r-- 1 root root 0 Aug 15 08:00 3
//只要在运行容器的时候加上一个--userns=keep-id即可。
[xx@localhost ~]$ podman run -it -v "$(pwd)"/data:/data:Z --userns=keep-id busybox /bin/sh
~ $ ls
bin data dev etc home proc root run sys tmp usr var
~ $ cd /data/
/data $ ls
1 123 2 3
/data $ ls -l
total 0
-rw-r--r-- 1 xx xx 0 Aug 15 08:00 1
-rw-r--r-- 1 xx xx 0 Aug 15 08:14 123
-rw-r--r-- 1 xx xx 0 Aug 15 08:00 2
-rw-r--r-- 1 xx xx 0 Aug 15 08:00 3
使用普通用户映射容器端口时会报“ permission denied”的错误
[xx@localhost ~]$ podman run -d -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 80e368ef21fc done
Copying blob 1efc276f4ff9 done
Copying blob aed046121ed8 done
Copying blob 4340e7be3d7f done
Copying blob 80cb79a80bbe done
Copying config f2a976f932 done
Writing manifest to image destination
Storing signatures
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的端口
[xx@localhost ~]$ podman run -d -p 1024:80 httpd
a43a5d8f933b361e8b549ccc83e8059c01cdb1504b26d204be97f43cc8b67dc8
[xx@localhost ~]$ ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
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
[root@localhost ~]# sysctl -p
net.ipv4.ping_group_range = 0 200000
user.max_user_namespaces = 15000
net.ipv4.ip_unprivileged_port_start = 80
[root@localhost ~]# podman run -d -p 81:80 httpd
54ab8c830f83d240a0fdbbd3e977bd990c29264e537cbff200fb409721478e46
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:81 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*