Podman容器基础(二)

2022-11-19,,

Podman容器技术基础(二)

目录
Podman容器技术基础(二)
容器的使用
用户操作
用户配置文件
容器卷

容器的使用

运行一个容器

[root@cent1 ~]# podman pull httpd		#首先拉取镜像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 1efc276f4ff9 done
Copying blob 80cb79a80bbe done
Writing manifest to image destination
Storing signatures
f2a976f932ec6fe48978c1cdde2c8217a497b1f080c80e49049e02757302cf74
[root@cent1 ~]# podman run -dit --name httpd1 httpd
142e4cdcae4d44ef46a4d4f6fff35a654fcd0cfb500a3ff1c05fa9e0aaaf38fd

查看镜像

[root@cent1 ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest f2a976f932ec 13 days ago 149 MB

列出正在运行的容器

[root@cent1 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
142e4cdcae4d docker.io/library/httpd:latest httpd-foreground 29 seconds ago Up 29 seconds ago httpd1

注意:如果在ps命令中添加-a,Podman 将显示所有容器。

检查正在运行的容器

[root@cent1 ~]# podman inspect httpd1 |grep -i ipaddr		#利用grep过滤查看ip
"IPAddress": "10.88.0.6",
"IPAddress": "10.88.0.6",

注意:-l 是最新容器的便利参数。您还可以使用容器的 ID 代替 -l。

查看一个运行中容器的日志

选项
-l --latest #最近的 [root@cent1 ~]# podman logs -l
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.6. 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.6. Set the 'ServerName' directive globally to suppress this message
[Mon Aug 15 07:10:33.198432 2022] [mpm_event:notice] [pid 1:tid 139798604795200] AH00489: Apache/2.4.54 (Unix) configured -- resuming normal operations
[Mon Aug 15 07:10:33.198614 2022] [core:notice] [pid 1:tid 139798604795200] AH00094: Command line: 'httpd -D FOREGROUND'
10.88.0.1 - - [15/Aug/2022:07:34:41 +0000] "GET / HTTP/1.1" 200 45

查看一个运行容器中的进程资源使用情况,可以使用top观察容器中的 nginx pid

语法:
podman top <container_id> [root@cent1 ~]# podman top httpd1
USER PID PPID %CPU ELAPSED TTY TIME COMMAND
root 1 0 0.000 28m39.856159659s pts/0 0s httpd -DFOREGROUND
www-data 9 1 0.000 28m39.856392576s pts/0 0s httpd -DFOREGROUND
www-data 10 1 0.000 28m39.856431469s pts/0 0s httpd -DFOREGROUND
www-data 17 1 0.000 28m39.856463178s pts/0 0s httpd -DFOREGROUND

停止一个运行中的容器

[root@cent1 ~]# podman stop httpd1
httpd1
[root@cent1 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

删除一个容器

[root@cent1 ~]# podman rm -f httpd1
142e4cdcae4d44ef46a4d4f6fff35a654fcd0cfb500a3ff1c05fa9e0aaaf38fd
[root@cent1 ~]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

以上这些特性基本上都和 Docker 一样,Podman 除了兼容这些特性外,还支持了一些新的特性。

例如我们想在docker.io上分享我们新建的Nginx容器镜像

[root@cent1 nginx]# tree
.
├── Dockerfile
└── files
└── nginx-1.23.1.tar.gz 1 directory, 2 files
[root@cent1 ~]# podman pull centos #由于官方镜像内的yum仓库无法使用,所以这里利用官方镜像创建容器,重新配置yum仓库,然后再打包为镜像上传到自己的dockerhub下
[root@cent1 ~]# podman run -dit --name centos1 centos #使用centos镜像创建一个容器
0d9ba6a56252f077b2245133dd6f513224d6e70398eebee8766caddfd85aae36
[root@cent1 ~]# podman exec -it centos1 /bin/bash #进入容器
[root@0d9ba6a56252 /]# cd /etc/yum.repos.d/ #重新配置yum仓库
[root@0d9ba6a56252 yum.repos.d]# rm -rf *
[root@0d9ba6a56252 yum.repos.d]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
[root@0d9ba6a56252 yum.repos.d]# sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
[root@cent1 ~]# podman commit -p centos1 centos:v3 #重开一个终端,将容器重新打包为镜像
Getting image source signatures
Copying blob 2653d992f4ef skipped: already exists
Copying blob 3e576afe7647 done
Copying config ccd1007825 done
Writing manifest to image destination
Storing signatures
ccd1007825988982a9af46c6590d2f786e40e69c14e1c89bd66696dbf9bdd8da
[root@cent1 ~]# podman login #登录自己的dockerhub账号
Username: xiang0311
Password:
Login Succeeded!
[root@cent1 ~]# podman tag centos:v3 docker.io/xiang0311/centos:v2 #标记镜像
[root@cent1 ~]# podman push docker.io/xiang0311/centos/:v2 #上传到自己的docker hub账号仓库下
[root@cent1 nginx]# cat Dockerfile
FROM docker.io/xiang0311/centos:v2 #这里为自己dockerhub账号下的镜像 ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.23.1.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.23.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@cent1 nginx]# podman build -t nginx . #构建镜像
[root@cent1 nginx]# podman tag localhost/nginx docker.io/xiang0311/nginx:v1 #标记镜像
[root@cent1 nginx]# podman push docker.io/xiang0311/nginx:v1 #上传镜像

总而言之,Podman 使查找、运行、构建和共享容器变得容易。

用户操作

在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置

cgroup V2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgroupV2启用了运行Podman的Linux发行版,则可能需要更改默认的OCI运行时。某些较旧的版本runc不适用于cgroupV2,必须切换到备用OCI运行时crun。

[root@cent1 ~]# rpm -qa | grep crun			#先查看自己系统是否有crun
[root@cent1 ~]# dnf -y install crun
[root@cent1 ~]# vim /usr/share/containers/containers.conf
runtime = "crun" #取消此行注释
#runtime = "runc" #注释此行
[root@cent1 ~]# podman run -dit --name web1 -p 80:80 docker.io/xiang0311/nginx:v1
6351479af7a13edc6fe9b5d82fb82739e6866cb43d9fa0842ccc1ae52e0f1f48
[root@cent1 ~]# podman inspect web1 | grep crun
"OCIRuntime": "crun",
"crun",

安装slirp4netns和fuse-overlayfs

在普通用户环境中使用Podman时,建议使用fuse-overlayfs而不是VFS文件系统,至少需要版本0.7.6。现在新版本默认就是了。

[root@cent1 ~]# rpm -qa | grep slirp4netns		#先查找这两个包,如果没有就需要安装
slirp4netns-1.1.8-1.module_el8.5.0+890+6b136101.x86_64
[root@cent1 ~]# rpm -qa | grep fuse-overlayfs
fuse-overlayfs-1.7.1-1.module_el8.5.0+890+6b136101.x86_64
[root@cent1 ~]# 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@cent1 ~]# dnf -y install shadow-utils
[root@cent1 ~]# useradd zhangsan
[root@cent1 ~]# useradd lisi
[root@cent1 ~]# cat /etc/subgid #可以在/ etc / subuid和/ etc / subgid查看,每个用户的值必须唯一且没有任何重叠。
zhangsan:100000:65536
lisi:165536:65536
[root@cent1 ~]# cat /etc/subuid
zhangsan:100000:65536
lisi:165536:65536
[root@cent1 ~]# vim /etc/sysctl.conf #启动非特权ping
net.ipv4.ping_group_range=0 200000 #大于100000这个就表示tom可以操作podman
[root@cent1 ~]# sysctl -p #刷新
net.ipv4.ping_group_range = 0 200000

这个文件的格式是 USERNAME:UID:RANGE中/etc/passwd或输出中列出的用户名getpwent。

USERNAME:为用户分配的初始UID:为用户分配的UID范围的大小

该usermod程序可用于为用户分配 UID 和 GID,而不是直接更新文件。

[root@cent1 ~]# usermod --add-subuids 200000-201000 --add-subgids 200000-201000 zhangsan
[root@cent1 ~]# grep zhangsan /etc/subuid /etc/subgid
/etc/subuid:zhangsan:100000:65536
/etc/subuid:zhangsan:200000:1001
/etc/subgid:zhangsan:100000:65536
/etc/subgid:zhangsan:200000:1001

用户配置文件

三个主要的配置文件是container.confstorage.confregistries.conf。用户可以根据需要修改这些文件。

container.conf

用户配置文件
1.~/.config/containers/containers.conf #优先级最高
2.cat /etc/containers/containers.conf
3.cat /usr/share/containers/containers.conf

如果它们以该顺序存在。每个文件都可以覆盖特定字段的前一个文件。

配置storage.conf文件

1./etc/containers/storage.conf
2.$HOME/.config/containers/storage.conf

在普通用户中/etc/containers/storage.conf的一些字段将被忽略

[root@cent1 ~]# vi /etc/containers/storage.conf
driver = "overlay"
......
mount_program = "/usr/bin/fuse-overlayfs" #取消注释
[root@cent1 ~]# vim /etc/sysctl.conf
net.ipv4.ping_group_range=0 200000
user.max_user_namespaces=15000c
[root@cent1 ~]# sysctl -p #刷新

在普通用户中这些字段默认

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

授权文件

此文件里面写了docker账号的密码,以加密方式显示

[root@cent1 ~]# podman login
Username: xiang0311
Password:
Login Succeeded!
[root@cent1 ~]# cat /run/user/0/containers/auth.json
{
"auths": {
"docker.io": {
"auth": "eGlhbmcwMzExOmxvdmV6eXAzMzMu"
}
}

普通用户是无法看见root用户的镜像的

#root用户
[root@cent1 ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/xiang0311/centos v3 ccd100782598 3 hours ago 217 MB
localhost/centos v3 ccd100782598 3 hours ago 217 MB
docker.io/xiang0311/nginx v1 e3f50c7181d7 7 hours ago 545 MB
#普通用户
[root@cent1 ~]# su - zhangsan
[zhangsan@cent1 ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE

容器卷

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

使用卷

[lisi@cent1 ~]$ podman pull busybox
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
7a80323521ccd4c2b4b423fa6e38e5cea156600f40cd855e464cc52a321a24dd
[lisi@cent1 ~]$ mkdir data
[lisi@cent1 ~]$ podman run -it --name web -v "$(pwd)"/data:/data:Z docker.io/library/busybox:latest /bin/sh
/ # cd data/
/data # ls
/data # touch 123
/data # ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 15 11:43 123

在主机上查看

[lisi@cent1 data]$ ll
total 0
-rw-r--r--. 1 lisi lisi 0 Aug 15 19:43 123
[lisi@cent1 data]$ echo qqq > 123
[lisi@cent1 data]$ cat 123
qqq

在容器内查看

/data # cat 123
qqq
/data # ls -l
total 4
-rw-r--r-- 1 root root 4 Aug 15 11:46 123

我们可以发现在容器里面的文件的属主和属组都属于root,那么如何才能让其属于tom用户呢?下面告诉你答案

[lisi@cent1 ~]$ podman rm -f web2
130a2c19ef5ae099b5d157c2361c081777d555b5f5f7ce6b066e0084804b8142
[lisi@cent1 ~]$ podman run -it --name web2 -v "$(pwd)"/data:/data:Z --userns=keep-id docker.io/library/busybox /bin/sh
~ $ cd data/
/data $ ls -l
total 4
-rw-r--r-- 1 lisi lisi 4 Aug 15 11:46 123

使用普通用户映射容器端口时会报“ permission denied”的错误

[lisi@cent1 ~]$ 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的端口

[lisi@cent1 ~]$ podman run -d -p 1024:80 httpd
2206552f4a6a4d0e6ecd73f618489721a6d45d875e6cc20f9aa86f1006c890f4
[lisi@cent1 ~]$ ss -tanl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
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@cent1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_unprivileged_port_start=80
[root@cent1 ~]# sysctl -p
net.ipv4.ip_unprivileged_port_start = 80
[lisi@cent1 ~]$ podman run -d -p 80:80 httpd
77147eaac4b63b58840ddc1b0aab44ef29e5c9d4f2daf19e2a8afbfdd1e07ee5
[lisi@cent1 ~]$ ss -tanl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:1024 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22

Podman容器基础(二)的相关教程结束。

《Podman容器基础(二).doc》

下载本文的Word格式文档,以方便收藏与打印。