当前位置: 首页 > 工具软件 > podman-static > 使用案例 >

Podman(续)

宫晟
2023-12-01

linux Podman(续)

使用 Podman

使用 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。

  • 为用户分配的初始 UID。
  • 为用户分配的 UID 范围的大小。

该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用户一起运行,则root容器中的用户实际上就是主机上的用户。
  • UID GID是在/etc/subuid和/etc/subgid等中用户映射中指定的第一个UID GID。
  • 如果普通用户的身份从主机目录挂载到容器中,并在该目录中以根用户身份创建文件,则会看到它实际上是你的用户在主机上拥有的。

使用卷

[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                     [::]:*                    
 类似资料: