podman的使用
1.使用 Podman
使用 Podman 非常的简单,Podman 的指令跟 Docker 大多数都是相同的。下面我们来看几个常用的例子:
podman run -d --name httpd docker.io/library/httpd //运行一个容器
[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 4340e7be3d7f done
Copying blob 80cb79a80bbe done
Copying blob 80e368ef21fc done
Copying blob 1efc276f4ff9 done
Copying blob aed046121ed8 done
Copying config f2a976f932 done
Writing manifest to image destination
Storing signatures
da77d5d773b9356e1c3784259a4576d421b5232a8fa33a0be162a7cc4fb0e4c6
//查看镜像
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest f2a976f932ec 12 days ago 149 MB
podman ps //列出运行的容器
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da77d5d773b9 docker.io/library/httpd:latest httpd-foreground About a minute ago Up About a minute ago httpd
注意:如果在ps命令中添加-a,Podman 将显示所有容器。
检查正在运行的容器
podman inspect -l| grep -i address //使用 inspect 子命令查看分配给容器的 IP 地址
[root@localhost ~]# podman inspect -l| grep -i address
"IPAddress": "10.88.0.2",
"GlobalIPv6Address": "",
"MacAddress": "4a:ff:a1:2c:27:56",
"LinkLocalIPv6Address": "",
"IPAddress": "10.88.0.2",
"GlobalIPv6Address": "",
"MacAddress": "4a:ff:a1:2c:27:56",
[root@localhost ~]# curl 10.88.0.2
<html><body><h1>It works!</h1></body></html>
注意:-l 是最新容器的便利参数。您还可以使用容器的 ID 代替 -l , -i 不用区别大小写。
您可以“检查”正在运行的容器的元数据和有关其自身的详细信息。我们甚至可以使用 inspect 子命令查看分配给容器的 IP 地址。由于容器以无根模式运行,因此未分配 IP 地址,并且该值将在检查的输出中列为“无”。
podman logs --latest //查看一个运行中容器的日志
选项
–latest #最近的
[root@localhost ~]# podman logs --latest
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 01:23:31.931372 2022] [mpm_event:notice] [pid 1:tid 140149175897408] AH00489: Apache/2.4.54 (Unix) configured -- resuming normal operations
[Mon Aug 15 01:23:31.931527 2022] [core:notice] [pid 1:tid 140149175897408] AH00094: Command line: 'httpd -D FOREGROUND'
10.88.0.1 - - [15/Aug/2022:01:27:49 +0000] "GET / HTTP/1.1" 200 45
podman top httpd //查看一个运行容器中的进程资源使用情况,可以使用top观察容器中的 nginx pid
语法:
podman top <container_id>
[root@localhost ~]# podman top httpd
USER PID PPID %CPU ELAPSED TTY TIME COMMAND
root 1 0 0.000 11m24.717551803s ? 0s httpd -DFOREGROUND
www-data 7 1 0.000 11m24.717860255s ? 0s httpd -DFOREGROUND
www-data 8 1 0.000 11m24.71789592s ? 0s httpd -DFOREGROUND
www-data 9 1 0.000 11m24.717981411s ? 0s
podman stop --latest //停止一个运行中的容器
[root@localhost ~]# podman stop --latest
da77d5d773b9356e1c3784259a4576d421b5232a8fa33a0be162a7cc4fb0e4c6
[root@localhost ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
删除一个容器
[root@localhost ~]# podman rm --latest
da77d5d773b9356e1c3784259a4576d421b5232a8fa33a0be162a7cc4fb0e4c6
[root@localhost ~]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
以上这些特性基本上都和 Docker 一样,Podman 除了兼容这些特性外,还支持了一些新的特性。
上传镜像
例如,如果我们想在 http://docker.io 上分享我们新建的 Nginx 容器镜像,这很容易。首先登录码头:
[root@localhost ~]# mkdir nginx
[root@localhost ~]# cd nginx/
[root@localhost nginx]# mkdir files
[root@localhost nginx]# cd files/
[root@localhost ~]# cd nginx/files/
[root@localhost files]# wget https://nginx.org/download/nginx-1.20.2.tar.gz
[root@localhost nginx]# vim Dockerfile
[root@localhost nginx]# tree
.
├── Dockerfile
└── files
└── nginx-1.20.2.tar.gz
1 directory, 2 files
[root@localhost nginx]# cat Dockerfile
FROM docker.io/yhm1206/centos:v1
ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.20.2.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.2 && \
./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 login
Username: yhm1206
Password:
Login Succeeded!
[root@localhost nginx]# podman build -t nginx .
Error: Failed to download metadata for repo 'appstream': cannot prepare internal mirrorlist: Mrlist //如果出现这样的报错,按照下面的方法进行解决
[root@localhost ~]#podman login
Username: yhm1206
Password:
Login Succeeded!
[root@localhost ~]#podman pull centos
[root@localhost ~]#podman run -dit --name centos1 centos:latest
[root@localhost ]# podman exec -it centos1 /bin/bash
[root@b700e4f957c5 /]# cd /etc/yum.repos.d/
[root@b700e4f957c5 /]# rm -rf *
[root@b700e4f957c5 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
[root@b700e4f957c5 /]# sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
[root@b700e4f957c5 /]# ls
CentOS-Base.repo
//另开一个终端
[root@localhost ~]# podman commit -p centos1 centos:v1
Getting image source signatures
Copying blob 74ddd0ec08fa skipped: already exists
Copying blob 7860de1a8658 done
Copying config 236457a52a done
Writing manifest to image destination
Storing signatures
236457a52ac2cd8a1e7d3ded5eceab3ecaef532f0a7741fc8da61b07d470bad7
[root@localhost ~]# podman tag centos:v1 docker.io/yhm1206/centos:v1
[root@localhost ~]# podman push docker.io/yhm1206/centos:v1 docker.io/yhm1206/centos:v1
Getting image source signatures
Copying blob 7860de1a8658 done
Copying blob 74ddd0ec08fa skipped: already exists
Copying config 236457a52a done
Writing manifest to image destination
Storing signatures
[root@localhost nginx]# podman build -t nginx .
......
make[1]: Leaving directory '/usr/src/nginx-1.20.2'
--> 3f4bfd521a9
STEP 5/5: CMD ["nginx","-g","daemon off"]
COMMIT nginx
--> 9df2261e5c4
Successfully tagged localhost/nginx:latest
9df2261e5c42b548fbc7e699a11499e7bac7d96125887a19d9c940a246b6eb13 //成功
podman tag localhost/nginx docker.io/yhm1206/nginx:v1
// 修改镜像名
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/nginx latest 9df2261e5c42 36 minutes ago 568 MB
[root@localhost ~]# podman tag localhost/nginx docker.io/yhm1206/nginx:v1
podman login docker.io // 登录并上传镜像
[root@localhost ~]# podman login docker.io // 需要告诉其要登录到docker仓库
[root@localhost ~]# podman login docker.io
Username: yhm1206 //账户
Password: //密码
Login Succeeded!
[root@localhost ~]# podman push docker.io/yhm1206/nginx:v1 //上传镜像
Getting image source signatures
Copying blob bc51ff8954f8 done
Copying blob fadbc43358c5 done
Copying blob 7860de1a8658 skipped: already exists
Copying blob 74ddd0ec08fa skipped: already exists
Copying config 9df2261e5c done
Writing manifest to image destination
Storing signatures
//请注意,我们将四层推送到我们的注册表,现在可供其他人共享。快速浏览一下:
[root@localhost ~]# podman inspect yhm1206/nginx:v1
[
{
"Id": "9df2261e5c42b548fbc7e699a11499e7bac7d96125887a19d9c940a246b6eb13",
"Digest": "sha256:5d3fe8879ef2751a0f43ddedc2e23f918062f67a88bb5e9235815f1396ef78e4",
"RepoTags": [
"localhost/nginx:latest",
"docker.io/yhm1206/nginx:v1"
],
"RepoDigests": [
"docker.io/yhm1206/nginx@sha256:5d3fe8879ef2751a0f43ddedc2e23f918062f67a88bb5e9235815f1396ef78e4",
....
总而言之,Podman 使查找、运行、构建和共享容器变得容易。
2.用户操作
在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置
cgroup V2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgroupV2启用了运行Podman的Linux发行版,则可能需要更改默认的OCI运行时。某些较旧的版本runc不适用于cgroupV2,必须切换到备用OCI运行时crun。
[root@localhost ~]# yum -y install crun //centos8系统自带
[root@localhost ~]# vim /usr/share/containers/containers.conf
# Default OCI runtime
#
#runtime = "crun"
runtime = "crun"
//取消注释并将runc改为crun
[root@localhost ~]# podman run -d --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 baf2da91597d done
Copying blob 27e0d286aeab done
Copying blob b1349eea8fc5 done
Copying blob 05396a986fd3 done
Copying blob 6a17c8e7063d done
Copying config b692a91e4e done
Writing manifest to image destination
Storing signatures
de4039b202d786211eef066f16cc8ff7c2ce066b60a98d04c209145871f626dc
[root@localhost ~]# podman inspect web | grep crun
"OCIRuntime": "crun",
"crun",
安装slirp4netns和fuse-overlayfs
在普通用户环境中使用Podman时,建议使用fuse-overlayfs而不是VFS文件系统,至少需要版本0.7.6。现在新版本默认就是了。
[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配置
Podman要求运行它的用户在/ etc / subuid和/ etc / subgid文件中列出一系列UID,shadow-utils或newuid包提供这些文件
[root@localhost ~]# yum -y install shadow-utils
可以在/ etc / subuid和/ etc / subgid查看,每个用户的值必须唯一且没有任何重叠。
[root@localhost ~]# useradd xiaoqi
[root@localhost ~]# cat /etc/subuid
xiaoqi:100000:65536
[root@localhost ~]# cat /etc/subuid
xiaoqi:100000:65536
// 启动非特权ping
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ping_group_range = 0 200000
[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 xiaoqi
[root@localhost ~]# grep xiaoqi /etc/subuid /etc/subgid
/etc/subuid:xiaoqi:100000:65536
/etc/subuid:xiaoqi:200000:1001
/etc/subgid:xiaoqi:100000:65536
/etc/subgid:xiaoqi: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 //优先级最高
在普通用户中这些字段默认
[root@localhost ~]# grephroot="$HOME/.local/share/containers/storage"
[root@localhost ~]# runroot="$XDG_RUNTIME_DIR/containers"
登录账号
[root@localhost ~]# podman login
Authenticating with existing credentials for docker.io
Existing credentials are valid. Already logged in to docker.io
[root@localhost ~]# cat /run/user/0/containers/auth.json
{
"auths": {
"docker.io": {
"auth": "eWhtMTIwNjp5aG0xMjM0NTY="
}
}
[root@localhost ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/yhm1206/nginx v1 9df2261e5c42 4 hours ago 568 MB
docker.io/yhm1206/centos v1 236457a52ac2 4 hours ago 239 MB
docker.io/library/nginx latest b692a91e4e15 13 days ago 146 MB
docker.io/library/busybox latest 7a80323521cc 2 weeks ago 1.47 MB
docker.io/library/centos latest 5d0da3dc9764 11 months ago 239 MB
[root@localhost ~]# su - xiaoqi
[xiaoqi@localhost ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
3.卷
- 容器与root用户一起运行,则root容器中的用户实际上就是主机上的用户。
- UID GID是在/etc/subuid和/etc/subgid等中用户映射中指定的第一个UID GID。
- 如果普通用户的身份从主机目录挂载到容器中,并在该目录中以根用户身份创建文件,则会看到它实际上是你的用户在主机上拥有的。
使用卷
[root@localhost ~]# su - xiaoqi
[xiaoqi@localhost ~]$ pwd
/home/xiaoqi
[xiaoqi@localhost ~]$ ls
[xiaoqi@localhost ~]$ mkdir data
[xiaoqi@localhost ~]$ cd data/
[xiaoqi@localhost data]$ pwd
/home/xiaoqi/data
[xiaoqi@localhost data]$ podman login
Username: yhm1206
Password:
Login Succeeded!
[xiaoqi@localhost data]$ podman run -it -v /home/xiaoqi/data/:/data:Z busybox /bin/sh
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 50783e0dfb64 done
Copying config 7a80323521 done
Writing manifest to image destination
Storing signatures
/ # ls
bin dev home root sys usr
data etc proc run tmp var
/ # cd data/
/data # ls
/data # touch y h m
/data # ls
h m y
在主机上查看
[xiaoqi@localhost data]$ ls
h m y
//写入文件
[xiaoqi@localhost data]$ echo qi > y
[xiaoqi@localhost data]$ cat y
qi
容器里查看
[xiaoqi@localhost data]$ podman run -it -v /home/xiaoqi/data/:/data:Z busybox /bin/sh
/ # cd data/
/data # ls
h m y
/data # cat y
qi
/data #
//我们可以发现在容器里面的文件的属主和属组都属于root,那么如何才能让其属于tom用户呢?下面告诉你答案
/data # ls -l
total 4
-rw-r--r-- 1 root root 0 Aug 15 11:20 h
-rw-r--r-- 1 root root 0 Aug 15 11:20 m
-rw-r--r-- 1 root root 3 Aug 15 11:23 y
//只要在运行容器的时候加上一个–userns=keep-id即可。
[xiaoqi@localhost ~]$ podman run -it --name qq -v "$(pwd)"/data:/data:Z --userns=keep-id docker.io/library/busybox:latest /bin/sh
~ $ cd data/
/data $ ls -l
total 4
-rw-r--r-- 1 xiaoqi xiaoqi 0 Aug 15 11:20 h
-rw-r--r-- 1 xiaoqi xiaoqi 0 Aug 15 11:20 m
-rw-r--r-- 1 xiaoqi xiaoqi 3 Aug 15 11:23 y
使用普通用户映射容器端口时会报“ permission denied”的错误
[xiaoqi@localhost ~]$ podman run -d -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的端口
[xiaoqi@localhost ~]$ podman run -d -p 1024:80 httpd
f2f5a7e0f38e82f73908b63e2fbb0c1ba8a47516eafc9989bbe53a130f5f5698
[xiaoqi@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2f5a7e0f38e docker.io/library/httpd:latest httpd-foreground 37 seconds ago Up 37 seconds ago 0.0.0.0:1024->80/tcp hardcore_lehmann
配置echo ‘net.ipv4.ip_unprivileged_port_start=80’ >> /etc/sysctl.conf后可以映射大于等于80的端口
[root@localhost ~]# su - xiaoqi
Last login: Mon Aug 15 20:04:57 CST 2022 on pts/1
[xiaoqi@localhost ~]$ podman run -d -p 80:80 httpd
7a80126c605fa4e774d275e592bed0de1d86df629c28fe838c2dbb266897485d
[xiaoqi@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7a80126c605f docker.io/library/httpd:latest httpd-foreground 8 seconds ago Up 8 seconds ago 0.0.0.0:80->80/tcp naughty_darwin