Podman使用入门 | Word Count: 2.6k | Reading Time: 14mins | Post Views:
Podman是一个开源的容器运行时项目,提供与Docker相似的功能,可以管理和运行任何符合OCI规范的容器和镜像。Podman提供了一个与Docker兼容的命令行前端来管理容器镜像。其主要的优点有:
无根模式运行,没有任何额外特权需要;
不需要守护进程
原生systemd集成,允许用户创建systemd单元文件并将容器作为系统服务运行。
2024.11 天津·和平区·解放北路·利顺德大酒店
初始安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 # 部署 [root@podman ~]# dnf install -y podman podman-docker podman-compose touch /etc/containers/nodocker [root@podman ~]# podman -v podman version 5.3.1 # 配置镜像代理 [root@podman ~]# vim /etc/containers/registries.conf unqualified-search-registries = ["docker.io"] [[registry]] prefix="docker.io" location="docker.1ms.run" # 重启服务 [root@podman ~]# systemctl enable podman [root@podman ~]# systemctl restart podman # 拉取镜像 [root@podman ~]# podman run hello-world !... Hello Podman World ...! .--"--. / - - \ / (O) (O) \ ~~~| -=(,Y,)=- | .---. /` \ |~~ ~/ o o \~~~~.----. ~~ | =(X)= |~ / (O (O) \ ~~~~~~~ ~| =(Y_)=- | ~~~~ ~~~| U |~~ Project: https://github.com/containers/podman Website: https://podman.io Desktop: https://podman-desktop.io Documents: https://docs.podman.io YouTube: https://youtube.com/@Podman X/Twitter: @Podman_io Mastodon: @Podman_io@fosstodon.org
使用管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 # 交互式运行容器 [root@podman ~]# podman run -it ubuntu /bin/bash root@b6089f227b55:/# # 容器后台运行 [root@podman ~]# podman run -itd --name ubuntu_test ubuntu /bin/bash 36811becd0b716687bc8e5ab0c6c29cd64ee159ceac1d2f7b7a685e69f7b7ea1 [root@podman ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 36811becd0b7 docker.io/library/ubuntu:latest /bin/bash 11 seconds ago Up 12 seconds ubuntu_test # 使用容器ID进入容器 [root@podman ~]# podman exec -it 368 /bin/bash root@36811becd0b7:/# # 启动容器 [root@podman ~]# podman start ubuntu_test ubuntu_test # 停止容器 [root@podman ~]# podman stop ubuntu_test WARN[0010] StopSignal SIGTERM failed to stop container ubuntu_test in 10 seconds, resorting to SIGKILL ubuntu_test # 重启容器 [root@podman ~]# podman restart ubuntu_test ubuntu_test # 删除容器 [root@podman ~]# podman rm -f ubuntu_test WARN[0010] StopSignal SIGTERM failed to stop container ubuntu_test in 10 seconds, resorting to SIGKILL ubuntu_test # 删除所有容器 [root@podman ~]# podman rm -f $(podman ps -aq) b6089f227b55 155c6d4d9fae 115938151fc0 1395177f65e0 c1f9a18de6bd # 查看pod属性 [root@podman ~]# podman inspect ubuntu_test [ { "Id": "98f6fb407b3cf7d3c4094ead7df7a3e1b45151bd88b2ff0df48e065476a8286c", "Created": "2025-01-15T21:11:54.305532006+08:00", "Path": "/bin/bash", "Args": [ "/bin/bash" ], "State": { "OciVersion": "1.2.0", "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 5638, "ConmonPid": 5636, "ExitCode": 0, "Error": "", "StartedAt": "2025-01-15T21:11:54.565491536+08:00", "FinishedAt": "0001-01-01T00:00:00Z", "CgroupPath": "/machine.slice/libpod-98f6fb407b3cf7d3c4094ead7df7a3e1b45151bd88b2ff0df48e065476a8286c.scope", "CheckpointedAt": "0001-01-01T00:00:00Z", "RestoredAt": "0001-01-01T00:00:00Z" }, "Image": "b1d9df8ab81559494794e522b380878cf9ba82d4c1fb67293bcf931c3aa69ae4", "ImageDigest": "sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6734ab", "ImageName": "docker.io/library/ubuntu:latest", "Rootfs": "", "Pod": "", # 从宿主机向容器复制文件 [root@podman ~]# cat helloworld.txt Hello World! [root@podman ~]# podman cp helloworld.txt ubuntu_test:/home [root@podman ~]# podman exec -it ubuntu_test /bin/bash root@98f6fb407b3c:/# cd /home/ root@98f6fb407b3c:/home# ls helloworld.txt ubuntu root@98f6fb407b3c:/home# cat helloworld.txt Hello World! # 从容器向宿主机复制文件 root@98f6fb407b3c:/home# mv helloworld.txt OneWorld.txt [root@podman ~]# podman cp ubuntu_test:/home/OneWorld.txt /tmp [root@podman ~]# cat /tmp/OneWorld.txt Hello World! # 资源限制,限制使用1核cpu,2GB内存 podman run --cpus=1 -m=2g --name nginx -d docker.io/library/nginx Trying to pull docker.io/library/nginx:latest... [root@podman ~]# podman stats ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS CPU TIME AVG CPU % 070a8c63fb69 nginx 0.00% 1.884MB / 2.147GB 0.09% 1.726kB / 838B 8.192kB / 20.48kB 2 15.93ms 0.02%
镜像管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 # 拉取镜像 [root@podman ~]# podman pull node:22-alpine # 查看已有镜像 [root@podman ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/node 22-alpine 546c0b137912 10 days ago 161 MB docker.io/library/nginx latest 9bea9f2796e2 7 weeks ago 196 MB docker.io/library/ubuntu latest b1d9df8ab815 8 weeks ago 80.6 MB docker.io/library/busybox latest af4709625109 3 months ago 4.52 MB docker.io/traefik/whoami latest aeef15490f2b 4 months ago 7.01 MB quay.io/podman/hello latest 5dd467fce50b 7 months ago 787 kB # 删除镜像 [root@podman ~]# podman rmi 5dd Untagged: quay.io/podman/hello:latest Deleted: 5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0 # 生成镜像 [root@podman ~]# podman run -it ubuntu:24.04 Resolved "ubuntu" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf) Trying to pull docker.io/library/ubuntu:24.04... Getting image source signatures Copying blob de44b265507a skipped: already exists Copying config b1d9df8ab8 done | Writing manifest to image destination root@3f5c2dbde6c0:/# apt update && apt upgrade -y && apt install vim root@3f5c2dbde6c0:/# exit # podman不支持-m参数 [root@podman ~]# podman commit -a "sujx@live.cn" 3f5c2 ubuntu:24.04.1 Getting image source signatures Copying blob 687d50f2f6a6 skipped: already exists Copying blob 01b59003fab2 done | Copying config 4c10e10b43 done | Writing manifest to image destination 4c10e10b437b46c62f3175097dce553d01ef3b9ec4a390c68da35b93a2e42b44 [root@podman ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/ubuntu 24.04.1 4c10e10b437b 21 seconds ago 199 MB
自定义镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # 创建Podmanfile [root@podman ~]# cat > ./Podmanfile <<EOF FROM node:22-alpine MAINTAINER sujx@live.cn EXPOSE 4000 RUN npm config set registry https://registry.npmmirror.com \ && npm install -g hexo-cli --save \ && mkdir /opt/blog \ && cd /opt \ && hexo init blog \ && cd /opt/blog \ && npm install hexo-renderer-pug hexo-renderer-stylus --save \ && npm install hexo-wordcount --save \ && npm install hexo-douban --save \ && npm install hexo-generator-sitemap --save \ && npm install hexo-generator-feed --save \ && npm install hexo-generator-baidu-sitemap --save\ && npm install hexo-generator-searchdb --save \ && npm install hexo-theme-butterfly --save \ && npm install hexo-butterfly-extjs --save \ && npm install hexo-butterfly-tag-plugins-plus --save \ && npm install hexo-pdf --save \ && npm install hexo-deployer-git --save \ && npm install hexo-deployer-ali-oss --save \ && npm uninstall hexo-generator-index --save \ && npm install hexo-generator-index-pin-top --save \ && npm install hexo-asset-image --save CMD cd /opt/blog && hexo clean && hexo g && hexo server EOF [root@podman ~]# podman build -f Podmanfile -t hexo:v1 [root@podman ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/hexo v1 5a535420cf24 6 minutes ago 962 MB
容器网络 端口暴露 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # 端口暴露 [root@podman ~]# podman run -itd --name busybox-test -p80 busybox b02b05b1881f8aa0cbca93f905a6559729e0a5c0e3be69adae2877d146579143 [root@podman ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b02b05b1881f docker.io/library/busybox:latest sh 5 seconds ago Up 6 seconds 0.0.0.0:38171->80/tcp busybox-test [root@podman ~]# podman exec -it b02 /bin/sh / # cd /var/ /var # ls spool www /var # httpd -h www /var # netstat -tlnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 :::80 :::* LISTEN 5/httpd # 端口映射,把容器的端口映射为宿主机的一个特定或者随机端口,使得外部用户可以访问服务器内部服务,其原理是在容器底层做了iptables的地址转发,转出的流量做SNAT源地址转发,转入的流量做DNAT目标地址转发。 # 指定端口转发 [root@podman ~]# podman run -itd --name myipaddr -p 80:80 traefik/whoami bbcc67b5fb1ce98b51335755c13498e87ace3da420b5a430001738cb27768e28 [root@podman ~]# curl 127.0.0.1 Hostname: bbcc67b5fb1c IP: 127.0.0.1 IP: ::1 IP: 10.88.0.5 IP: fe80::c79:daff:fe48:4cb8 RemoteAddr: 10.88.0.1:55560 GET / HTTP/1.1 Host: 127.0.0.1 User-Agent: curl/8.6.0 Accept: */*
网络架构 Podman的网络架构有4种模式:
桥接模式(默认)
non模式(仅本地回环)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 # 桥接模式(默认) [root@podman ~]# podman inspect myipaddr |grep IPAdd* "IPAddress": "10.88.0.5", "IPAddress": "10.88.0.5", # none模式(仅本地回环) [root@podman ~]# podman run -d --name=network-none --net=none nginx 539143ba161c73617ac1fd15e74a599753a71ce9658326bc5b8ebacaae114b86 [root@podman ~]# podman inspect 539143 |grep IPAdd* "IPAddress": "", "IPAddress": "", # host模式,容器使用当前主机IP root@podman ~]# podman run --network=host nginx /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: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh /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 2025/01/18 16:47:15 [notice] 1#1: using the "epoll" event method 2025/01/18 16:47:15 [notice] 1#1: nginx/1.27.3 2025/01/18 16:47:15 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2025/01/18 16:47:15 [notice] 1#1: OS: Linux 6.12.9-100.fc40.x86_64 2025/01/18 16:47:15 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2025/01/18 16:47:15 [notice] 1#1: start worker processes 2025/01/18 16:47:15 [notice] 1#1: start worker process 24 127.0.0.1 - - [18/Jan/2025:16:47:22 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.6.0" "-" # container:<id >模式,容器之间共享Network Namespace,荣期间进程通过lo网卡通信 [root@podman ~]# podman run -itd --name bb busybox 365cf25286131e596f3aef54c43fed1b83e5be5ecc5f18e4de98242812f4002d [root@podman ~]# podman run -d --name nginx --network=container:bb nginx 1287874746dcc6f72158b8fdb1ddf07ba13bdda06bd5a04bfdecaf86426fb927 [root@podman ~]# podman exec -it bb /bin/sh [root@podman ~]# curl 10.88.0.7 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
网络实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # 查看网络模式,可以看到名为podman的网桥 [root@podman ~]# podman network ls NETWORK ID NAME DRIVER 2f259bab93aa podman bridge # 查看podman网桥信息 [root@podman ~]# ip a …… 5: podman0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether ca:2c:2d:8d:b8:21 brd ff:ff:ff:ff:ff:ff inet 10.88.0.1/16 brd 10.88.255.255 scope global podman0 valid_lft forever preferred_lft forever inet6 fe80::c82c:2dff:fe8d:b821/64 scope link proto kernel_ll valid_lft forever preferred_lft forever 6: veth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master podman0 state UP group default qlen 1000 link/ether fa:55:23:21:f6:c3 brd ff:ff:ff:ff:ff:ff link-netns netns-0e73c46a-0951-048b-fbc8-5e25f3d52e72 inet6 fe80::18b5:62ff:fec9:3476/64 scope link proto kernel_ll valid_lft forever preferred_lft forever # 查看NAT规则 [root@podman ~]# iptables -L -t nat Chain POSTROUTING (policy ACCEPT) target prot opt source destination NETAVARK-HOSTPORT-MASQ all -- anywhere anywhere NETAVARK-1D8721804F16F all -- 10.88.0.0/16 anywhere Chain NETAVARK-1D8721804F16F (1 references) target prot opt source destination ACCEPT all -- anywhere 10.88.0.0/16 MASQUERADE all -- anywhere !base-address.mcast.net/4
本地存储 存储卷 1 2 # 将本地web文件夹挂载到容器中,使用本地文件进行存储 podman run -itd -v /root/web:/var/www/html -p 8080:80 httpd
存储容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 通过创建多个容器,使用容器来存储数据 [root@podman ~]# podman run -itd --name db_data -v /db_data ubuntu 8e48de5ce3d36803352052643734689b2a2250ef9e3558253342e603b315b94a [root@podman ~]# podman run -id --name db1 --volumes-from db_data ubuntu 83c227c5c077582cd700862508958d41e0532023ead11c95953aae0c4bc6faef # 查看存储容器内容 [root@podman ~]# podman exec -it 8e48de /bin/bash root@8e48de5ce3d3:/# ls bin boot db_data dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@8e48de5ce3d3:/# ls db_data/ root@8e48de5ce3d3:/# cd db_data/ root@8e48de5ce3d3:/db_data# touch TestDB root@8e48de5ce3d3:/db_data# exit exit # 查看应用容器内容 [root@podman ~]# podman exec -it 83c227 /bin/bash root@83c227c5c077:/# ls /db_data/ TestDB root@83c227c5c077:/# exit exit # 查看文件实际位置 [root@podman ~]# ls /var/lib/containers/storage/volumes/84a3b4a00b1557b6754f1ed9633294df117697d1608adc91701b335297caa61f/_data/ TestDB
性能监控 1 2 3 4 5 6 7 8 9 # stats命令 查看当前主机上容器的具体资源占用情况 [root@podman _data]# podman stats ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS CPU TIME AVG CPU % 8e48de5ce3d3 db_data 0.01% 606.2kB / 4.044GB 0.01% 1.942kB / 978B 9.97MB / 4.096kB 1 29.762ms 0.01% 83c227c5c077 db1 0.00% 241.7kB / 4.044GB 0.01% 1.216kB / 978B 0B / 4.096kB 1 10.716ms 0.00% # top命令 查看容器内的应用使用情况 [root@podman _data]# podman top 83c22 USER PID PPID %CPU ELAPSED TTY TIME COMMAND root 1 0 0.000 7m29.133340188s ? 0s /bin/bash