podman
什么是podman?
Podman是一个开源项目,可以在大多数Linux平台上使用,可将代码放在[GitHub]上。Podman 是一个无守护容器引擎,用于在 Linux 系统上开发、管理和运行开放容器计划 (OCI) 容器和容器映像。Podman 提供了一个与 Docker 兼容的命令行前端,可以简单地别名 Docker cli,alias docker=podman。Podman还提供了套接字激活的REST API服务,以允许远程应用程序启动按需容器。这个REST API还支持Docker API,允许docker-py和docker-compose的用户与Podman即服务进行交互。
Podman 控制下的容器可以由 root 用户运行,也可以由非特权用户运行。Podman 使用[libpod]库管理整个容器生态系统,包括 Pod、容器、容器映像和容器卷。Podman 专注于帮助您维护和修改 OCI 容器映像的所有命令和功能,例如拉取和标记。它允许您在生产环境中创建、运行和维护从这些映像创建的容器。
Podman服务仅在Linux平台上运行,但是podman远程REST API客户端存在于Mac和Windows平台上,并且可以通过ssh与Linux机器或VM上运行的Podman服务进行通信。
podman(Pod Manager)是一个由RedHat公司推出的容器管理工具,它的定位就是docker的替代品,在使用上与docker的体验类似。 podman源于CRI-O项目,可以直接访问OCI的实现(如runC),流程比docker要短。 二者主要的区别在于,podman是一个开源的产品;而docker已经是商业化的产品。 podman的开源代码,由RedHat的OpenShift项目维护。 podman.io上面的文档还不算很健全,作为普通开发者,将其当成docker去用,难度也不算很大。
概述和范围
从高层次上讲,libpod 和 Podman 的范围如下:
- 支持多种镜像格式,包括 OCI 和 Docker 镜像格式。
- 支持多种安全下载图像的方法,包括信任和图像验证。
- 容器映像管理(管理映像层、覆盖文件系统等)。
- 全面管理容器生命周期。
- 支持 Pod 一起管理容器组。
- 容器和 Pod 的资源隔离。
策略
- 有关 podman pod 命令的进一步工作。
- 无根容器的进一步改进。
- 支持无根 Podman 与 NFS Homedirs。
- 支持原生叠加层上的无根 Podman。
- 增强了图像的加速拉取功能。
- Podman 程序,用于设置用于在 Mac 和 Linux 上运行 nativley 的 VM。
podman -remote run
podman的安装
podman 在 CentOS 7 的默认 Extras 存储库中可用,在 CentOS 8 和 Stream 的 AppStream 存储库中可用。
[root@localhost ~]# dnf -y install podman
[root@localhost ~]# rpm -qa | grep podman
podman-3.4.1-3.module_el8.6.0+954+963caf36.x86_64
podman-catatonit-3.4.1-3.module_el8.6.0+954+963caf36.x86_64
# 我们可以给podman定义一个别名叫docker
[root@localhost ~]# alias docker=podman
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
查看帮助
[root@localhost ~]# podman --help
Manage pods, containers and images
Usage:
podman [options] [command]
Available Commands:
attach Attach to a running container
auto-update Auto update containers according to their auto-update policy
build Build an image using instructions from Containerfiles
......
查看帮助文档
[root@localhost ~]# man podman
......
# 查看子命令,示例(example),比如查看 podman run
[root@localhost ~]# man podman-run
.......
poman 的常用命令:
Podman可以使用一些简单的关键字在远程官方仓库上搜索镜像
podman search <search_term>
[root@localhost ~]# podman search nginx
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
fedoraproject.org registry.fedoraproject.org/f29/nginx 0
redhat.com registry.access.redhat.com/ubi8/nginx-118 Platform for running nginx 1.18 or building ... 0
......
centos.org registry.centos.org/centos/nginx 0
.......
docker.io docker.io/library/nginx Official build of Nginx. 15928 [OK]
......
# 搜索的镜像有多个拉取地址,所以拉取的时候要指定具体的地址
还可以使用过滤器增强搜索:
podman search httpd --filter=is-official
[root@localhost ~]# podman search nginx --filter=is-official (--filter=is-official 过滤官方镜像)
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/library/nginx Official build of Nginx. 15928 [OK]
下载(拉取)图像也很容易
[root@localhost ~]# podman pull docker.io/library/nginx
......
# 注意:Podman在不同的注册管理机构中搜索。因此,建议使用完整的映像名称(docker.io/library/httpd而不是httpd)来确保使用正确的映像。
拉取一些图像后,您可以列出计算机上存在的所有图像
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx latest f652ca386ed1 11 days ago 146 MB
运行容器
示例容器将运行一个非常基本的 nginx 服务器,该服务器仅为其索引页提供服务
[root@localhost ~]# podman run -d -p 80:80 docker.io/library/nginx:latest
81462774ef3a27079293143a15b361a9672100e44868ac3d72ec238142ef5f84
列出正在运行的容器
该命令用于列出已创建和正在运行的容器。podman ps
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81462774ef3a docker.io/library/nginx:latest nginx -g daemon o... 6 seconds ago Up 5 seconds ago 0.0.0.0:80->80/tcp silly_goldberg
podman ps -a
Podman 将显示所有容器(已创建、已退出、正在运行等)
测试nginx容器
[root@localhost ~]# curl 192.168.220.17
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
......
检查正在运行的容器
我(你)可以"检查"正在运行的容器,以查找有关其自身的元数据和详细信息。 将提供许多有用的信息,如环境变量,网络设置或分配的资源。podman inspect
由于容器在root模式下运行,因此会为容器分配 IP 地址
[root@localhost ~]# podman inspect -l |grep -i ipaddress
"IPAddress": "10.88.0.2",
"IPAddress": "10.88.0.2",
注意:这是最新容器的便利参数。还可以使用容器的 ID 或名称,而不是 long 参数 。-l--latest
。-i
(忽略大小写)
查看容器的日志
我(你)也可以使用 Podman 查看容器的日志
[root@localhost ~]# podman logs -l(最近创建容器的日志)
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/12/14 07:07:36 [notice] 1#1: using the "epoll" event method
2021/12/14 07:07:36 [notice] 1#1: nginx/1.21.4
2021/12/14 07:07:36 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2021/12/14 07:07:36 [notice] 1#1: OS: Linux 4.18.0-257.el8.x86_64
2021/12/14 07:07:36 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/12/14 07:07:36 [notice] 1#1: start worker processes
2021/12/14 07:07:36 [notice] 1#1: start worker process 30
2021/12/14 07:07:36 [notice] 1#1: start worker process 31
192.168.220.17 - - [14/Dec/2021:07:10:49 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.61.1" "-"
查看容器的 pids
我(你)可以使用 观察到 容器中的 httpd pid。podman top
[root@localhost ~]# podman top -l
USER PID PPID %CPU ELAPSED TTY TIME COMMAND
root 1 0 0.000 11m15.438007076s ? 0s nginx: master process nginx -g daemon off;
nginx 30 1 0.000 11m14.438123979s ? 0s nginx: worker process
nginx 31 1 0.000 11m14.438153549s ? 0s nginx: worker process
停止容器
我(你)可以停止容器:
[root@localhost ~]# podman stop -l
81462774ef3a27079293143a15b361a9672100e44868ac3d72ec238142ef5f84
我(你)可以使用该命令检查一个或多个容器的状态。在这种情况下,应使用参数列出所有容器。podman ps``-a
[root@localhost ~]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81462774ef3a docker.io/library/nginx:latest nginx -g daemon o... 12 minutes ago Exited (0) 27 seconds ago 0.0.0.0:80->80/tcp silly_goldberg
删除容器
最后,我(你)可以删除容器:
[root@localhost ~]# podman rm -l
81462774ef3a27079293143a15b361a9672100e44868ac3d72ec238142ef5f84
我(你)可以通过运行 来验证容器的删除。podman ps -a
[root@localhost ~]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
镜像修改标签(改名)
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx latest f652ca386ed1 11 days ago 146 MB
[root@localhost ~]# podman tag docker.io/library/nginx:latest docker.io/yunjisuanlp/nginx:v1.0
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx latest f652ca386ed1 11 days ago 146 MB
docker.io/yunjisuanlp/nginx v1.0 f652ca386ed1 11 days ago 146 MB
普通用户使用podman的方式
在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置
cgroup V2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgroup V2启用了运行Podman的Linux发行版,则可能需要更改默认的OCI运行时。某些较旧的版本runc不适用于cgroup V2,必须切换到备用OCI运行时crun。
[root@localhost ~]# dnf -y install crun # centos8系统自带
[root@localhost ~]# vim /usr/share/containers/containers.conf
......
446 # Default OCI runtime
447 #
448 runtime = "crun" # 取消注释并将值改为crun
......
[root@localhost ~]# podman run -d -p 80 docker.io/library/nginx
81462774ef3a27079293143a15b361a9672100e44868ac3d72ec238142ef5f84
[root@localhost ~]# podman inspect -l | grep crun
"OCIRuntime": "crun",
"crun",
slirp4netns
slirp4netns包为普通用户提供一种网络模式
[root@localhost ~]# rpm -qa| grep slirp4netns
slirp4netns-1.1.8-1.module_el8.6.0+926+8bef8ae7.x86_64
安装fuse-overlayfs
在普通用户环境中使用Podman时,建议使用fuse-overlayfs而不是VFS文件系统,至少需要版本0.7.6。现在新版本默认就是
[root@localhost ~]# rpm -qa |grep fuse-overlayfs
fuse-overlayfs-1.7.1-1.module_el8.6.0+926+8bef8ae7.x86_64
[root@localhost ~]# vim /etc/containers/storage.conf
......
77 mount_program = "/usr/bin/fuse-overlayfs" # 取消注释
......
/etc/subuid和/etc/subgid配置
Podman要求运行它的用户在/etc/subuid和/etc/subgid文件中列出一系列UID,shadow-utils或newuid包提供这些文件
[root@localhost ~]# rpm -qa| grep shadow-utils
shadow-utils-4.6-12.el8.x86_64
# 可以在/etc/subuid和/etc/subgid查看,每个用户的值必须唯一且没有任何重叠。
[root@localhost ~]# podman exec -it -l /bin/bash
root@g5456sf4d5df:/# id
uid=0(root) gid=0(root) groups=0(root)
root@g5456sf4d5df:/# useradd liuliu
root@g5456sf4d5df:/# cat /etc/subuid
liuliu:100000:65536
root@g5456sf4d5df:/# useradd xixi
root@g5456sf4d5df:/# cat /etc/subuid
liuliu:100000:65536
xixi:165536:65536
该文件的格式为USERNAME:UID:RANGE
- 在/ etc / passwd或getpwent中列出的用户名。
- 为用户分配的初始uid。
- 为用户分配的UID范围的大小
用户的配置文件
三个主要的配置文件是container.conf,storage.conf和registries.conf。用户可以根据需要修改这些文件。
container.conf
Podman读取时,按照循序来了,当前面一位找不到时,就去找下一个
1./usr/share/containers/containers.conf
2./etc/containers/containers.conf
3.$HOME/.config/containers/containers.conf
storage.conf
storge.conf则是
1./etc/containers/storage.conf
2.$HOME/.config/containers/storage.conf
在普通用户中/etc/containers/storage.conf的一些字段将被忽略
graphroot=``""`` ``container storage graph ``dir` `(default: ``"/var/lib/containers/storage"``)`` ``Default directory to store all writable content created by container storage programs.` `runroot=``""`` ``container storage run ``dir` `(default: ``"/run/containers/storage"``)`` ``Default directory to store all temporary writable content created by container storage programs.
在普通用户中这些字段默认
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
授权文件
podman login 登录,默认授权文件在${XDG_RUNTIME_DIR}/containers/auth.json
[root@localhost ~]# cat /run/user/0/containers/auth.json
{
"auths": {
"docker.io": {
"auth": "********************="
}
}
}
podman容器开机自启(root用户与普通用户)
root用户
运行容器
[root@localhost ~]# podman run -d -p 80:80 --name nginx f652ca386ed1
b444383f36708ac37dd818cf1d37f3e7268194cf13c30322a75bb773f0a15d61
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b444383f3670 docker.io/library/nginx:latest nginx -g daemon o... 6 seconds ago Up 6 seconds ago 0.0.0.0:80->80/tcp nginx
配置启动文件
[root@localhost bin]# vim /etc/systemd/system/nginx_conteainer.service
[root@localhost bin]# cat /etc/systemd/system/nginx_conteainer.service
[Unit]
Description=Podman Nginx Service
After=network.target
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/podman start -a nginx
ExecStop=/usr/bin/podman stop -t 10 nginx
Restart=always
[Install]
WantedBy=multi-user.target
重新加载并启动查看
[root@localhost bin]# systemctl daemon-reload
[root@localhost bin]# systemctl enable --now nginx_conteainer.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx_conteainer.service → /etc/systemd/system/nginx_conteainer.service.
[root@localhost bin]# systemctl status nginx_conteainer.service
● nginx_conteainer.service - Podman Nginx Service
Loaded: loaded (/etc/systemd/system/nginx_conteainer.service; enabled; vendor >
Active: active (running) since Wed 2021-12-15 02:53:26 EST; 9s ago
Main PID: 38185 (podman)
Tasks: 9 (limit: 4743)
Memory: 41.2M
CGroup: /system.slice/nginx_conteainer.service
└─38185 /usr/bin/podman start -a nginx
12月 15 02:53:26 localhost.localdomain systemd[1]: Started Podman Nginx Service.
普通用户
切换用户
[root@localhost ~]# id test
uid=1000(test) gid=1000(test) 组=1000(test)
[root@localhost ~]# su - test
上一次登录:三 12月 15 02:58:37 EST 2021pts/0 上
启动容器
[test@localhost ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx latest f652ca386ed1 12 days ago 146 MB
[test@localhost ~]$ podman run -d --name nginx f652ca386ed1
4ceeb68d0e986bc604dc5d649d631703a82a8017102f19f80bb04dff4bb0bfd7
[test@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ceeb68d0e98 docker.io/library/nginx:latest nginx -g daemon o... 9 seconds ago Up 9 seconds ago nginx
生成启动配置文件
[test@localhost ~]$ mkdir -p .config/systemd/user
[test@localhost ~]$ cd .config/systemd/user/
[test@localhost user]$ podman generate systemd --files --name nginx
/home/test/.config/systemd/user/container-nginx.service
[test@localhost user]$ cat /home/test/.config/systemd/user/container-nginx.service
# container-nginx.service
# autogenerated by Podman 3.4.1-dev
# Wed Dec 15 03:02:57 EST 2021
[Unit]
Description=Podman container-nginx.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/tmp/podman-run-1000/containers
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman start nginx
ExecStop=/usr/bin/podman stop -t 10 nginx
ExecStopPost=/usr/bin/podman stop -t 10 nginx
PIDFile=/tmp/podman-run-1000/containers/overlay-containers/4ceeb68d0e986bc604dc5d649d631703a82a8017102f19f80bb04dff4bb0bfd7/userdata/conmon.pid
Type=forking
[Install]
WantedBy=multi-user.target default.target
远程连接test用户
[root@localhost ~]# ssh test@localhost
test@localhost's password:
Last login: Wed Dec 15 03:07:58 2021 from ::1
设置开机自启
[test@localhost ~]$ systemctl --user enable --now container-nginx.service
Created symlink /home/test/.config/systemd/user/multi-user.target.wants/container-nginx.service → /home/test/.config/systemd/user/container-nginx.service.
Created symlink /home/test/.config/systemd/user/default.target.wants/container-nginx.service → /home/test/.config/systemd/user/container-nginx.service.
[test@localhost ~]$ systemctl --user status container-nginx.service
● container-nginx.service - Podman container-nginx.service
Loaded: loaded (/home/test/.config/systemd/user/container-nginx.service; enabl>
Active: active (running) since Wed 2021-12-15 03:12:33 EST; 33s ago
Docs: man:podman-generate-systemd(1)
Process: 4785 ExecStart=/usr/bin/podman start nginx (code=exited, status=0/SUCC>
Main PID: 4896 (conmon)
CGroup: /user.slice/user-1000.slice/user@1000.service/container-nginx.service
├─4888 /usr/bin/slirp4netns --disable-host-loopback --mtu=65520 --enab>
├─4889 /usr/bin/fuse-overlayfs -o ,lowerdir=/home/test/.local/share/co>
├─4896 /usr/bin/conmon --api-version 1 -c 4ceeb68d0e986bc604dc5d649d63>
├─4899 nginx: master process nginx -g daemon off;
├─4955 nginx: worker process
├─4956 nginx: worker process
├─4957 nginx: worker process
└─4958 nginx: worker process
podman网络
指定网络运行容器
创建podman网络
# 创建cni-podman2网络
[root@localhost ~]# podman network create cni-podman2
/etc/cni/net.d/cni-podman2.conflist
# --subnet指定subnet创建网络
## podman network create --sunet 网段 创建的网络名
[root@localhost ~]# podman network create --subnet 192.6.0.0/16 newnet
/etc/cni/net.d/newnet.conflist
# --gateway 指定网关
## podman network create --subnet 网段 --gateway 网关地址 newnet1
[root@localhost ~]# podman network create --subnet 192.168.33.0/24 --gateway 192.168.33.3 newnet1
/etc/cni/net.d/newnet1.conflist
# --ip-range 指定ip起始地址
[root@localhost ~]# podman network create --subnet 192.168.55.0/24 --ip-range 192.168.55.128/25 newnet2
/etc/cni/net.d/newnet2.conflist
#查看网络
[root@localhost ~]# podman network ls
NETWORK ID NAME VERSION PLUGINS
2f259bab93aa podman 0.4.0 bridge,portmap,firewall,tuning
603e960751dc cni-podman2 0.4.0 bridge,portmap,firewall,tuning
884e74728f04 newnet 0.4.0 bridge,portmap,firewall,tuning
45b3499a170b newnet1 0.4.0 bridge,portmap,firewall,tuning
31213d4efd11 newnet2 0.4.0 bridge,portmap,firewall,tuning
使用创建的网络运行容器
# podman run --name 容器名 --network 网络名称 镜像名
[root@localhost ~]# podman run -d --name nginx --network cni-podman2 nginx:latest
c69f0c65dace38250b5b244d7f2650a78cf93446ae3383afd959312db5f6df82
查看该容器的网络IP
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ~]# podman inspect nginx |grep IP
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"IPAddress": "10.89.0.5",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAMConfig": null,
podman网络管理
启动一个容器后,会出现cni-poman0网卡,容器启动时,默认会连接podman网络
[root@localhost ~]# ip a show cni-podman0
3: cni-podman0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether de:ad:ca:93:bd:4c brd ff:ff:ff:ff:ff:ff
inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
valid_lft forever preferred_lft forever
inet6 fe80::dcad:caff:fe93:bd4c/64 scope link
valid_lft forever preferred_lft forever
ls 查看容器网路
[root@localhost ~]# podman network ls
NETWORK ID NAME VERSION PLUGINS
2f259bab93aa podman 0.4.0 bridge,portmap,firewall,tuning
603e960751dc cni-podman2 0.4.0 bridge,portmap,firewall,tuning
disconnect 断开网络
[root@localhost ~]# podman network disconnect cni-podman2 nginx
reload 重启容器网络
[root@localhost ~]# podman network reload nginx2
e922ba3fc8bfade7f9f40d9650d83630bbf43ad5b58cca0dd395e4e58ab122e5
rm 删除podman网络
[root@localhost ~]# podman network ls
NETWORK ID NAME VERSION PLUGINS
2f259bab93aa podman 0.4.0 bridge,portmap,firewall,tuning
603e960751dc cni-podman2 0.4.0 bridge,portmap,firewall,tuning
884e74728f04 newnet 0.4.0 bridge,portmap,firewall,tuning
45b3499a170b newnet1 0.4.0 bridge,portmap,firewall,tuning
31213d4efd11 newnet2 0.4.0 bridge,portmap,firewall,tuning
[root@localhost ~]# podman network rm newnet2
newnet2
[root@localhost ~]# podman network ls
NETWORK ID NAME VERSION PLUGINS
2f259bab93aa podman 0.4.0 bridge,portmap,firewall,tuning
603e960751dc cni-podman2 0.4.0 bridge,portmap,firewall,tuning
884e74728f04 newnet 0.4.0 bridge,portmap,firewall,tuning
45b3499a170b newnet1 0.4.0 bridge,portmap,firewall,tuning