podman安装及使用命令

Podman是一个无需守护进程和root权限的容器运行时工具,兼容Docker命令。它比Docker更轻量,没有dockerd守护进程,直接调用oci runtime。Podman的使用包括安装、基础命令、容器管理和镜像签名。安装时可能需要配置加速器,基础命令如`run`、`start`、`inspect`等与Docker类似。镜像签名可以通过GPG密钥实现,确保安全分发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是Podman?

在这里插入图片描述
Podman 是一个开源的容器运行时项目,可在大多数 Linux 平台上使用。Podman 提供与 Docker 非常相似的功能。正如前面提到的那样,它不需要在你的系统上运行任何守护进程,并且它也可以在没有 root 权限的情况下运行。

Podman 可以管理和运行任何符合 OCI(Open Container Initiative)规范的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来管理 Docker 镜像。

Podman 官网地址:https://podman.io/

Podman和Docker的主要区别是什么?

dockers在实现CRI的时候,它需要一个守护进程,其次需要以root运行,因此这也带来了安全隐患。
podman不需要守护程序,也不需要root用户运行,从逻辑架构上,比docker更加合理。
在docker的运行体系中,需要多个daemon才能调用到OCI的实现RunC。
在容器管理的链路中,Docker Engine的实现就是dockerd
daemon,它在linux中需要以root运行,dockerd调用containerd,containerd调用containerd-shim,然后才能调用runC。顾名思义shim起的作用也就是“垫片”,避免父进程退出影响容器的运训
podman直接调用OCI,runtime(runC),通过common作为容器进程的管理工具,但不需要dockerd这种以root身份运行的守护进程。
在podman体系中,有个称之为common的守护进程,其运行路径通常是/usr/libexec/podman/conmon,它是各个容器进程的父进程,每个容器各有一个,common的父则通常是1号进程。podman中的common其实相当于docker体系中的containerd-shim。
在这里插入图片描述

Podman的使用与docker有什么区别?

podman的定位也是与docker兼容,因此在使用上面尽量靠近docker。在使用方面,可以分成两个方面来说,一是系统构建者的角度,二是使用者的角度。

在系统构建者方面,用podman的默认软件,与docker的区别不大,只是在进程模型、进程关系方面有所区别。如果习惯了docker几个关联进程的调试方法,在podman中则需要适应。可以通过pstree命令查看进程的树状结构。总体来看,podman比docker要简单。由于podman比docker少了一层daemon,因此重启的机制也就不同了。

在使用者方面,podman与docker的命令基本兼容,都包括容器运行时(run/start/kill/ps/inspect),本地镜像(images/rmi/build)、镜像仓库(login/pull/push)等几个方面。因此podman的命令行工具与docker类似,比如构建镜像、启停容器等。甚至可以通过alias

docker=podman可以进行替换。因此,即便使用了podman,仍然可以使用http://docker.io作为镜像仓库,这也是兼容性最关键的部分。

podman安装和基础命令

安装podman

可以不用安装yum源,因为当前yum源版本有podman,但是我这边安装的镜像是不一样的所以还得弄几个命令修改一下才能使用

[root@192 ~]# ls /etc/yum.repos.d/
CentOS-Linux-AppStream.repo          CentOS-Linux-FastTrack.repo
CentOS-Linux-BaseOS.repo             CentOS-Linux-HighAvailability.repo
CentOS-Linux-ContinuousRelease.repo  CentOS-Linux-Media.repo
CentOS-Linux-Debuginfo.repo          CentOS-Linux-Plus.repo
CentOS-Linux-Devel.repo              CentOS-Linux-PowerTools.repo
CentOS-Linux-Extras.repo             CentOS-Linux-Sources.repo

修改 centos 文件内容

[root@192 ~]# dnf list all |grep podman
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
[root@192 ~]# sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
[root@192 ~]# sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

生成缓存更新(第一次更新,速度稍微有点慢,耐心等待两分钟左右)

[root@192 ~]# yum makecache
CentOS Linux 8 - AppStream              3.0 MB/s | 8.4 MB     00:02    
CentOS Linux 8 - BaseOS                 2.2 MB/s | 4.6 MB     00:02    
CentOS Linux 8 - Extras                  16 kB/s |  10 kB     00:00    
Metadata cache created.

运行 yum update 升级

[root@192 ~]# yum update -y

安装podman

[root@192 ~]# dnf -y install podman-docker

查看有没有包,并看看能不能使用

[root@192 ~]# which podman
/usr/bin/podman
[root@192 ~]# which docker
/usr/bin/docker
[root@192 ~]# rpm -qa |grep docker
podman-docker-3.3.1-9.module_el8.5.0+988+b1f0b741.noarch
[root@192 ~]# podman images
REPOSITORY  TAG         IMAGE ID    CREATED     SIZE

配置一个加速器,这边用的是阿里云的

[root@192 ~]# cd /etc/containers/
[root@192 containers]# ls
certs.d  policy.json      registries.conf.d  storage.conf
oci      registries.conf  registries.d
[root@192 containers]# vim registries.conf

unqualified-search-registries = ["registry.fedoraproject.org", "registry
.access.redhat.com", "registry.centos.org", "docker.io"]

[[registry]]
prefix = "docker.io"
location = "6e5o0ntr.mirror.aliyuncs.com"
# # The "prefix" field is used to choose the relevant [[registry]] TOML 
table;

拉取一个镜像

[root@192 ~]# 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

[root@192 ~]# podman pull centos
Resolved "centos" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull quay.io/centos/centos:latest...
Getting image source signatures
Copying blob 7a0437f04f83 done  
Copying config 300e315adb done  
Writing manifest to image destination
Storing signatures
300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55
[root@192 ~]# 

明确指定在哪个网站拉取镜像
比如去官方

[root@192 ~]# podman pull docker.io/library/centos
Trying to pull docker.io/library/centos:latest...
Getting image source signatures
Copying blob a1d0c7532777 done  
Copying config 5d0da3dc97 done  
Writing manifest to image destination
Storing signatures
5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
[root@192 ~]# 

这里可以看到用指定的跟不指定的版本都不一样

[root@192 ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED        SIZE
docker.io/library/busybox  latest      7a80323521cc  2 weeks ago    1.47 MB
docker.io/library/centos   latest      5d0da3dc9764  11 months ago  239 MB
quay.io/centos/centos      latest      300e315adb2f  20 months ago  217 MB
[root@192 ~]# 


podman基础命令使用

cp 在容器和本地文件系统之间复制文件/文件夹‎

[root@192 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND     CREATED             STATUS                 PORTS       NAMES
e8cc176fdcd7  docker.io/library/busybox:latest  sh          About a minute ago  Up About a minute ago              frosty_stonebraker
[root@192 ~]# podman cp anaconda-ks.cfg e8cc176fdcd7:/
[root@192 ~]# 

[root@192 ~]# podman run -it busybox
/ # ls
anaconda-ks.cfg  etc              root             tmp
bin              home             run              usr
dev              proc             sys              var
/ # 

[root@192 ~]# podman cp  e8cc176fdcd7:/anaconda-ks.cfg /opt/
[root@192 ~]# ls /opt/
anaconda-ks.cfg
[root@192 ~]# 

create 创建但不启动容器‎

[root@192 ~]# podman create --name web httpd
1d771fd1a125e70cb7c843a8086d695535598ab8c10175286ff078dd862266f1
[root@192 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND     CREATED        STATUS            PORTS       NAMES
e8cc176fdcd7  docker.io/library/busybox:latest  sh          8 minutes ago  Up 8 minutes ago              frosty_stonebraker
[root@192 ~]# 
[root@192 ~]# podman ps -a
CONTAINER ID  IMAGE                             COMMAND           CREATED         STATUS            PORTS       NAMES
e8cc176fdcd7  docker.io/library/busybox:latest  sh                9 minutes ago   Up 9 minutes ago              frosty_stonebraker
1d771fd1a125  docker.io/library/httpd:latest    httpd-foreground  28 seconds ago  Created                       web
[root@192 ~]# 

diff ‎检查容器文件系统上的更改‎

[root@192 ~]# podman diff e8cc176fdcd7
A /anaconda-ks.cfg
C /etc
C /root
A /root/.ash_history
[root@192 ~]# 

events ‎显示podman事件‎

[root@192 ~]# podman events

exec ‎在正在运行的容器中运行进程‎

[root@192 ~]# podman exec -it e8cc176fdcd7 /bin/sh
/ # exit
[root@192 ~]# 

attach ‎附加到正在运行的容器‎

//这边ls,这边会话退出
[root@192 ~]# podman attach e8cc176fdcd7
/ # ls
anaconda-ks.cfg  etc              root             tmp
bin              home             run              usr
dev              proc             sys              var
/ # exit
//
[root@192 ~]# 

/ # 这边也运行ls,这边会话也退出
anaconda-ks.cfg  etc              root             tmp
bin              home             run              usr
dev              proc             sys              var
/ # exit
[root@192 ~]# 

history ‎显示指定图像的历史记录

[root@192 ~]# podman history httpd
ID            CREATED       CREATED BY                                     SIZE              COMMENT
dabbfbe0c57b  7 months ago  /bin/sh -c #(nop)  CMD ["httpd-foreground"]    0 B               
<missing>     7 months ago  /bin/sh -c #(nop)  EXPOSE 80                   0 B               
<missing>     7 months ago  /bin/sh -c #(nop) COPY file:c432ff61c4993e...  3.58 kB           
<missing>     7 months ago  /bin/sh -c #(nop)  STOPSIGNAL SIGWINCH         0 B               
<missing>     7 months ago  /bin/sh -c set -eux;                                             savedAptMark="$(apt...  61.1 MB     
<missing>     7 months ago  /bin/sh -c #(nop)  ENV HTTPD_PATCHES=          0 B               
<missing>     7 months ago  /bin/sh -c #(nop)  ENV HTTPD_SHA256=0127f7...  0 B               
<missing>     7 months ago  /bin/sh -c #(nop)  ENV HTTPD_VERSION=2.4.52    0 B               
<missing>     7 months ago  /bin/sh -c set -eux;                           apt-get update;   apt...      2.72 MB     
<missing>     7 months ago  /bin/sh -c #(nop) WORKDIR /usr/local/apache2   0 B               
<missing>     7 months ago  /bin/sh -c mkdir -p "$HTTPD_PREFIX"            && ch...          3.07 kB     
<missing>     7 months ago  /bin/sh -c #(nop)  ENV PATH=/usr/local/apa...  0 B               
<missing>     7 months ago  /bin/sh -c #(nop)  ENV HTTPD_PREFIX=/usr/l...  0 B               
<missing>     7 months ago  /bin/sh -c #(nop)  CMD ["bash"]                0 B               
<missing>     7 months ago  /bin/sh -c #(nop) ADD file:09675d11695f65c...  83.9 MB           
[root@192 ~]# 


images ‎列出本地存储中的图像‎

[root@192 ~]# podman image --help
Manage images

Description:
  Manage images

Usage:
  podman image [command]

Available Commands:
  build       Build an image using instructions from Containerfiles
  diff        Inspect changes to the image's file systems
  exists      Check if an image exists in local storage
  history     Show history of a specified image
  import      Import a tarball to create a filesystem image
  inspect     Display the configuration of an image
  list        List images in local storage
  load        Load image(s) from a tar archive
  mount       Mount an image's root filesystem
  prune       Remove unused images
  pull        Pull an image from a registry
  push        Push an image to a specified destination
  rm          Removes one or more images from local storage
  save        Save image(s) to an archive
  search      Search registry for image
  sign        Sign an image
  tag         Add an additional name to a local image
  tree        Prints layer hierarchy of an image in a tree format
  trust       Manage container image trust policy
  unmount     Unmount an image's root filesystem
  untag       Remove a name from a local image

[root@192 ~]# 

network ‎管理网络‎

[root@192 ~]# podman network ls
NETWORK ID    NAME        VERSION     PLUGINS
2f259bab93aa  podman      0.4.0       bridge,portmap,firewall,tuning
[root@192 ~]# 

generate ‎生成的结构化数据‎

[root@192 ~]# podman run -d --name web1 -p 80:80 httpd
e09f3a613fd02214484d9e5c08fc478b1e1e068d5055ff9b2802e0992c871de1
[root@192 ~]# podman generate systemd --name  web1 --files --new 
/root/container-web1.service
[root@192 ~]# ls
anaconda-ks.cfg  container-web1.service
//可以设置一个开机自启,并且每次开机都会自动创建一个web1新文件
[root@192 ~]# podman rm -f web1
e09f3a613fd02214484d9e5c08fc478b1e1e068d5055ff9b2802e0992c871de1
[root@192 ~]# podman ps -a
CONTAINER ID  IMAGE                             COMMAND           CREATED       STATUS                   PORTS       NAMES
e8cc176fdcd7  docker.io/library/busybox:latest  sh                23 hours ago  Exited (0) 23 hours ago              frosty_stonebraker
1d771fd1a125  docker.io/library/httpd:latest    httpd-foreground  23 hours ago  Exited (0) 23 hours ago              web
a9c7f99b809e  docker.io/library/busybox:latest  /bin/sh           23 hours ago  Created                              compassionate_chebyshev
[root@192 ~]# cp container-web1.service /usr/lib/systemd/system/
[root@192 ~]# systemctl enable --now container-web1
Created symlink /etc/systemd/system/multi-user.target.wants/container-web1.service → /usr/lib/systemd/system/container-web1.service.
Created symlink /etc/systemd/system/default.target.wants/container-web1.service → /usr/lib/systemd/system/container-web1.service.
[root@192 ~]# systemctl status container-web1
● container-web1.service - Podman container-web1.service
   Loaded: loaded (/usr/lib/systemd/system/container-web1.service; enab>
   Active: active (running) since Mon 2022-08-15 22:49:14 CST; 35s ago
     Docs: man:podman-generate-systemd(1)
  Process: 2964 ExecStartPre=/bin/rm -f /run/container-web1.service.ctr>
 Main PID: 3081 (conmon)
    Tasks: 2 (limit: 23512)
   Memory: 1.9M
   CGroup: /system.slice/container-web1.service
           └─3081 /usr/bin/conmon --api-version 1 -c b3e8f7401b134e24c4>

Aug 15 22:49:13 192.168.64.130 systemd[1]: Starting Podman container-we>
Aug 15 22:49:14 192.168.64.130 systemd[1]: Started Podman container-web>
[root@192 ~]# podman ps
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS             PORTS               NAMES
b3e8f7401b13  docker.io/library/httpd:latest  httpd-foreground  45 seconds ago  Up 44 seconds ago  0.0.0.0:80->80/tcp  web1
[root@192 ~]# 


logs ‎获取容器的日志‎

[root@192 ~]# podman logs web1
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.3. 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.3. Set the 'ServerName' directive globally to suppress this message
[Mon Aug 15 14:49:14.035862 2022] [mpm_event:notice] [pid 1:tid 140547627834688] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations
[Mon Aug 15 14:49:14.035967 2022] [core:notice] [pid 1:tid 140547627834688] AH00094: Command line: 'httpd -D FOREGROUND'
[root@192 ~]# 


port ‎列出容器的端口映射或特定映射‎

[root@192 ~]# podman port web1
80/tcp -> 0.0.0.0:80
[root@192 ~]# 

rename ‎重命名现有容器‎
这里只是修改正在运行的容器名字

[root@192 ~]# podman ps
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS             PORTS               NAMES
b3e8f7401b13  docker.io/library/httpd:latest  httpd-foreground  13 minutes ago  Up 13 minutes ago  0.0.0.0:80->80/tcp  myweb
[root@192 ~]# 

stats ‎显示容器资源使用情况统计信息的实时流‎

[root@192 ~]# podman stats 

ID            NAME        CPU %       MEM USAGE / LIMIT  MEM %       NET IO         BLOCK IO      PIDS        CPU TIME      AVG CPU %
e9c6d2482cb4  web1        6.98%       39.99MB / 3.89GB   1.03%       978B / 1.87kB  17.33MB / 0B  82          115.984212ms  6.98%

system ‎管理 podman‎

[root@192 ~]# podman system --help
Manage podman

Description:
  Manage podman

Usage:
  podman system [command]

Available Commands:
  connection  Manage remote ssh destinations
  df          Show podman disk usage
  info        Display podman system information
  migrate     Migrate containers
  prune       Remove unused data
  renumber    Migrate lock numbers
  reset       Reset podman storage
  service     Run API service

[root@192 ~]# podman system df
TYPE           TOTAL       ACTIVE      SIZE        RECLAIMABLE
Images         4           2           604.3MB     455.1MB (0%)
Containers     4           1           1.556kB     1.542kB (0%)
Local Volumes  0           0           0B          0B (0%)
//显示系统信息
[root@192 ~]# podman system info
host:
  arch: amd64
  buildahVersion: 1.22.3
  cgroupControllers:
  - cpuset
  - cpu
  - cpuacct
  - blkio
  - memory
  - devices
  - freezer
  - net_cls
  - perf_event
  - net_prio
  - hugetlb
  - pids
  - rdma
  cgroupManager: systemd
  cgroupVersion: v1

[root@192 ~]# podman system migrate 
stopped e9c6d2482cb4a379faa623413090cc828fa917dd0247758b6a5c0fb7af6b7375
[root@192 ~]# 

[root@192 ~]# podman system prune 
WARNING! This will remove:
	- all stopped containers
	- all networks not used by at least one container
	- all dangling images
	- all dangling build cache

Are you sure you want to continue? [y/N] n
[root@192 ~]# 

top ‎显示容器的运行进程‎
1表示都是同一个进程

[root@192 ~]# podman top web
USER        PID         PPID        %CPU        ELAPSED       TTY         TIME        COMMAND
root        1           0           0.000       4.582774869s  ?           0s          httpd -DFOREGROUND 
www-data    9           1           0.000       4.58293767s   ?           0s          httpd -DFOREGROUND 
www-data    10          1           0.000       4.582970597s  ?           0s          httpd -DFOREGROUND 
www-data    11          1           0.000       4.583251623s  ?           0s          httpd -DFOREGROUND 
[root@192 ~]# 

unmount ‎卸载工作容器的根文件系统‎
虽然卸载了但是它还是能工作的

[root@192 ~]# podman unmount web
web
[root@192 ~]# podman ps
CONTAINER ID  IMAGE                           COMMAND           CREATED       STATUS                 PORTS       NAMES
1d771fd1a125  docker.io/library/httpd:latest  httpd-foreground  36 hours ago  Up About a minute ago              web
[root@192 ~]# 
//这里错误是没有文件能指定这所以要挂载才能解决
[root@192 ~]# podman exec -it web /bin/bash
Error: exec failed: container_linux.go:380: starting container process caused: process_linux.go:99: starting setns process caused: fork/exec /proc/self/exe: no such file or directory: OCI runtime attempted to invoke a command that was not found
[root@192 ~]# 

[root@192 ~]# podman mount web
/var/lib/containers/storage/overlay/b3805d888dbe4b41729bc27573a81e5eff9075c19d3cd1f7fa938b26b4196373/merged
[root@192 ~]# podman exec -it web /bin/bash
root@1d771fd1a125:/usr/local/apache2# 

version ‎显示 Podman 版本信息‎

[root@192 ~]# podman version 
Version:      3.3.1
API Version:  3.3.1
Go Version:   go1.16.7
Built:        Wed Nov 10 05:23:56 2021
OS/Arch:      linux/amd64
[root@192 ~]# 

volume ‎管理卷‎

[root@192 ~]# podman volume --help
Manage volumes

Description:
  Volumes are created in and can be shared between containers

Usage:
  podman volume [command]

Available Commands:
  create      Create a new volume
  exists      volume exists
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused volumes
  rm          Remove one or more volumes

[root@192 ~]# 

//判断卷存不存在
[root@192 ~]# podman volume exists 
Error: accepts 1 arg(s), received 0
[root@192 ~]# 

-l 是最近使用的最后一次

[root@192 ~]# podman run -itd busybox
b7d2997db888b433a2585264c3c41e75e4ed560417c49bcf6f7a4ae3c372d5db
[root@192 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND           CREATED        STATUS            PORTS       NAMES
1d771fd1a125  docker.io/library/httpd:latest    httpd-foreground  36 hours ago   Up 9 minutes ago              web
b7d2997db888  docker.io/library/busybox:latest  sh                8 seconds ago  Up 8 seconds ago              festive_wilson
[root@192 ~]# podman stop -l
b7d2997db888b433a2585264c3c41e75e4ed560417c49bcf6f7a4ae3c372d5db
[root@192 ~]# podman ps
CONTAINER ID  IMAGE                           COMMAND           CREATED       STATUS            PORTS       NAMES
1d771fd1a125  docker.io/library/httpd:latest  httpd-foreground  36 hours ago  Up 9 minutes ago              web
[root@192 ~]# 

//删除是删除当前最近的一个和当前最新的一个
[root@192 ~]# podman rm -fl
b7d2997db888b433a2585264c3c41e75e4ed560417c49bcf6f7a4ae3c372d5db
[root@192 ~]# 
[root@192 ~]# podman rm -fl
a9c7f99b809e94ed0ab1d3161ce87542b45845c2b7a73845f3a0d1c1a5f464e4
[root@192 ~]# 

podman基本设置和使用

运行示例容器
此示例容器将运行一个非常基本的 httpd 服务器,该服务器仅为其索引页提供服务。

[root@192 ~]# podman run -dt -p 8080:8080/tcp -e HTTPD_VAR_RUN=/run/httpd -e HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \
>                   -e HTTPD_MAIN_CONF_PATH=/etc/httpd/conf \
>                   -e HTTPD_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/httpd/ \
>                   registry.fedoraproject.org/f29/httpd /usr/bin/run-httpd
Trying to pull registry.fedoraproject.org/f29/httpd:latest...
Getting image source signatures
Copying blob 7692efc5f81c done  
Copying blob aaf5ad2e1aa3 done  
Copying blob d77ff9f653ce done  
Copying config 25c76f9dcd done  
Writing manifest to image destination
Storing signatures
9929c2e22c0530e705ba94b0c0f5080b184394533a61a037daf34f5805e19b87
[root@192 ~]# 

由于容器在分离模式下运行(在命令中由 -d 表示),因此 Podman 将在运行后打印容器 ID。请注意,我们使用端口转发来访问 HTTP 服务器。要成功运行,至少需要 slirp4netns v0.3.0。podman run

检查正在运行的容器
您可以“检查”正在运行的容器,以获取有关其自身的元数据和详细信息。我们甚至可以使用 inspect 子命令来查看分配给容器的 IP 地址。由于容器在无根模式下运行,因此不会分配 IP 地址,并且该值将在检查的输出中列为“无”。

[root@192 ~]# podman inspect -l|grep -i ipaddress
            "IPAddress": "10.88.0.5",
                    "IPAddress": "10.88.0.5",
[root@192 ~]# 


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

测试 httpd 服务器
由于我们没有容器的IP地址,因此我们可以使用curl测试主机操作系统和容器之间的网络通信。以下命令应显示容器化 httpd 服务器的索引页。
在这里插入图片描述

查看容器的日志
您还可以使用 Podman 查看容器的日志:

[root@192 ~]# podman logs --latest 
=> sourcing 10-set-mpm.sh ...
=> sourcing 20-copy-config.sh ...
=> sourcing 40-ssl-certs.sh ...
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message
[Tue Aug 16 03:40:17.564183 2022] [ssl:warn] [pid 1:tid 140116922916224] AH01882: Init: this version of mod_ssl was compiled against a newer library (OpenSSL 1.1.1b FIPS  26 Feb 2019, version currently loaded is OpenSSL 1.1.1 FIPS  11 Sep 2018) - may result in undefined or erroneous behavior


对容器执行检查点操作
对容器执行检查点操作会停止容器,同时将容器中所有进程的状态写入磁盘。这样,容器以后可以还原,并在与检查点完全相同的时间点继续运行。此功能要求在系统上安装 CRIU 3.11 或更高版本。不支持此功能作为无根;因此,如果您想尝试一下,则需要使用相同的命令(但使用sudo)以root身份重新创建容器。

要对容器使用检查点,请使用:

[root@192 ~]# podman container checkpoint -l
9929c2e22c0530e705ba94b0c0f5080b184394533a61a037daf34f5805e19b87
[root@192 ~]# podman ps
CONTAINER ID  IMAGE                           COMMAND           CREATED       STATUS             PORTS       NAMES
[root@192 ~]# podman ps -a
CONTAINER ID  IMAGE                                        COMMAND               CREATED        STATUS                     PORTS                   NAMES
9929c2e22c05  registry.fedoraproject.org/f29/httpd:latest  /usr/bin/run-http...  7 minutes ago  Exited (0) 25 seconds ago  0.0.0.0:8080->8080/tcp  jolly_sutherland
[root@192 ~]# 


还原容器
还原容器仅适用于以前检查点的容器。还原的容器将继续在检查点操作的同一时间点运行。要恢复容器,请使用:

[root@192 ~]# podman container restore -l
9929c2e22c0530e705ba94b0c0f5080b184394533a61a037daf34f5805e19b87
[root@192 ~]# podman ps -a
CONTAINER ID  IMAGE                                        COMMAND               CREATED        STATUS                   PORTS                   NAMES
9929c2e22c05  registry.fedoraproject.org/f29/httpd:latest  /usr/bin/run-http...  8 minutes ago  Up 8 minutes ago         0.0.0.0:8080->8080/tcp  jolly_sutherland
[root@192 ~]# 

还原后,容器将像检查点之前一样再次应答请求。

curl http://<IP_address>:8080

迁移容器
要将容器从一个主机实时迁移到另一个主机,容器将在迁移的源系统上执行检查点操作,传输到目标系统,然后在目标系统上还原。传输检查点时,可以指定输出文件。

在源系统上:

[root@192 ~]# podman container checkpoint 9929c2e22c05 -e /tmp/checkpoint.tar.gz
9929c2e22c0530e705ba94b0c0f5080b184394533a61a037daf34f5805e19b87
[root@192 ~]# scp /tmp/checkpoint.tar.gz 192.168.64.131:/tmp
The authenticity of host '192.168.64.131 (192.168.64.131)' can't be established.
ECDSA key fingerprint is SHA256:wwFm8Hgm+WWr8IS/U4pesqpYm2efZVb2wQSBz0uJ1mw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.64.131' (ECDSA) to the list of known hosts.
root@192.168.64.131's password: 
checkpoint.tar.gz                     100% 2791KB 119.2MB/s   00:00    
[root@192 ~]# 


在目标系统上:

[root@192 ~]# podman container restore -i /tmp/checkpoint.tar.gz
Trying to pull registry.fedoraproject.org/f29/httpd:latest...
Getting image source signatures
Copying blob aaf5ad2e1aa3 done  
Copying blob d77ff9f653ce done  
Copying blob 7692efc5f81c done  
Copying config 25c76f9dcd done  
Writing manifest to image destination
Storing signatures
9929c2e22c0530e705ba94b0c0f5080b184394533a61a037daf34f5805e19b87
[root@192 ~]# 


还原后,容器将像检查点之前一样再次应答请求。这一次,容器将继续在目标系统上运行。

curl http://<IP_address>:8080

在这里插入图片描述

如何使用 Podman 对容器映像进行签名和分发:了解如何通过 Podman 设置和使用映像签名。

对容器映像进行签名源于仅信任专用映像提供程序的动机,以缓解中间人 (MITM) 攻击或对容器注册表的攻击。对图像进行签名的一种方法是使用 GNU 隐私卫士 (GPG) 密钥。此技术通常与任何符合 OCI 的容器注册表(如 Quay.io)兼容。值得一提的是,OpenShift 集成容器注册表开箱即用地支持这种签名机制,这使得单独的签名存储变得不必要。

从技术角度来看,我们可以在将映像推送到远程注册表之前利用 Podman 对映像进行签名。之后,所有运行Podman的系统都必须配置为从远程服务器检索签名,远程服务器可以是任何简单的Web服务器。这意味着在映像拉取操作期间,每个未签名的映像都将被拒绝。但是这是如何工作的呢?

首先,我们必须创建一个GPG密钥对或选择一个本地可用的密钥对。要生成新的GPG密钥,只需运行并按照交互式对话框进行操作即可。现在我们应该能够验证密钥是否在本地存在:gpg --full-gen-key

[root@192 ~]# gpg --full-gen-key
gpg (GnuPG) 2.2.20; Copyright (C) 2020 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: cys486@126.com
Email address: cys486@126.com
Comment: jjyy
You selected this USER-ID:
    "cys486@126.com (jjyy) <cys486@126.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.




        ┌──────────────────────────────────────────────────────┐
        │ Please enter the passphrase to                       │
        │ protect your new key                                 │
        │                                                      │
        │ Passphrase: ________________________________________ │
        │                                                      │
        │	<OK>                              <Cancel>     │
        └──────────────────────────────────────────────────────┘






        ┌──────────────────────────────────────────────────────┐
        │ Please enter the passphrase to                       │
        │ protect your new key                                 │
        │                                                      │
        │ Passphrase: ******__________________________________ │
        │                                                      │
        │	<OK>                              <Cancel>     │
        └──────────────────────────────────────────────────────┘




 ┌────────────────────────────────────────────────────────────────────┐
 │ Warning: You have entered an insecure passphrase.                  │
 │                                                                    │
 │ A passphrase should be at least 8 characters long.                 │
 │                                                                    │
 │ <Take this one anyway>                      <Enter new passphrase> │
 └────────────────────────────────────────────────────────────────────┘




        ┌──────────────────────────────────────────────────────┐
        │ Please re-enter this passphrase                      │
        │                                                      │
        │ Passphrase: ******__________________________________ │
        │                                                      │
        │	<OK>                              <Cancel>     │
        └──────────────────────────────────────────────────────┘



We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
	gpg: key 7292FB6288A4475F marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/E3725E6DB597AAC61BAC70137292FB6288A4475F.rev'
public and secret key created and signed.

pub   rsa2048 2022-08-16 [SC]
      E3725E6DB597AAC61BAC70137292FB6288A4475F
uid                      cys486@126.com (jjyy) <cys486@126.com>
sub   rsa2048 2022-08-16 [E]

[root@192 ~]# 
[root@192 ~]# gpg --list-keys cys486@126.com
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   rsa2048 2022-08-16 [SC]
      E3725E6DB597AAC61BAC70137292FB6288A4475F
uid           [ultimate] cys486@126.com (jjyy) <cys486@126.com>
sub   rsa2048 2022-08-16 [E]

[root@192 ~]# 

现在,让我们假设我们运行一个容器注册表。例如,我们可以简单地在本地机器上启动一个:

[root@192 ~]# podman run -d -p 5000:5000 docker.io/registry
Trying to pull docker.io/library/registry:latest...
Getting image source signatures
Copying blob e2ead8259a04 done  
Copying blob 0d96da54f60b done  
Copying blob 3790aef225b9 done  
Copying blob 79e9f2f55bf5 done  
Copying blob 5b27040df4a2 done  
Copying config b8604a3fe8 done  
Writing manifest to image destination
Storing signatures
0f5fd8046d16b822d55b2f3bc043fc2947a7b6ffdd1cdced399011466070a208
[root@192 ~]# 
[root@192 ~]# ss -antl
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            0.0.0.0:5000        0.0.0.0:*            
LISTEN  0       128               [::]:22             [::]:*            
[root@192 ~]# 

注册表对映像签名一无所知,它只是为容器映像提供远程存储。这意味着,如果我们要对图像进行签名,则必须注意如何分发签名。

让我们为签名实验选择一个标准映像:alpine

[root@192 ~]# podman pull docker://docker.io/alpine:latest
Trying to pull docker.io/library/alpine:latest...
Getting image source signatures
Copying blob 59bf1c3509f3 done  
Copying config c059bfaa84 done  
Writing manifest to image destination
Storing signatures
c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18
[root@192 ~]# 
[root@192 ~]# podman images alpine
REPOSITORY                TAG         IMAGE ID      CREATED       SIZE
docker.io/library/alpine  latest      c059bfaa849c  8 months ago  5.87 MB
[root@192 ~]# 

现在,我们可以重新标记映像以将其指向本地注册表:

[root@192 ~]# podman images alpine
REPOSITORY                TAG         IMAGE ID      CREATED       SIZE
docker.io/library/alpine  latest      c059bfaa849c  8 months ago  5.87 MB
[root@192 ~]# podman tag alpine localhost:5000/alpine
[root@192 ~]# podman images alpine
REPOSITORY                TAG         IMAGE ID      CREATED       SIZE
docker.io/library/alpine  latest      c059bfaa849c  8 months ago  5.87 MB
localhost:5000/alpine     latest      c059bfaa849c  8 months ago  5.87 MB
[root@192 ~]# 


Podman现在能够推送图像并在一个命令中签名。但是要让它工作,我们必须修改系统范围的注册表配置,网址为:/etc/containers/registries.d/default.yaml

[root@192 ~]# cd /etc/containers/
[root@192 containers]# ls
certs.d  policy.json      registries.conf.d  storage.conf
oci      registries.conf  registries.d
[root@192 containers]# cd registries.d
[root@192 registries.d]# ls
default.yaml  registry.access.redhat.com.yaml  registry.redhat.io.yaml
[root@192 registries.d]# vim default.yaml 

default-docker:
#  sigstore: file:///var/lib/containers/sigstore
  sigstore: http://localhost:8000
  sigstore-staging: file:///var/lib/containers/sigstore



我们可以看到,我们配置了两个签名存储:

sigstore:引用 Web 服务器进行签名读取
sigstore-staging:引用文件路径以进行签名写入
现在,让我们推送并签署映像:

[root@192 ~]# podman push --tls-verify=false --sign-by cys486@126.com localhost:5000/alpine
Getting image source signatures
Copying blob 8d3ac3489996 done  
Copying config c059bfaa84 [============================] 1.4KiB / 1.4KiB
Writing manifest to image destination
Signing manifest


   ┌────────────────────────────────────────────────────────────────┐
   │ Please enter the passphrase to unlock the OpenPGP secret key:  │
   │ "cys486@126.com (jjyy) <cys486@126.com>"                       │
   │ 2048-bit RSA key, ID 7292FB6288A4475F,                         │
   │ created 2022-08-16.                                            │
   │                                                                │
   │                                                                │
   │ Passphrase: ******____________________________________________ │
   │                                                                │
   │         <OK>                                    <Cancel>       │
   └────────────────────────────────────────────────────────────────┘

Storing signatures
[root@192 ~]# 

如果我们现在看一下系统签名存储,那么我们看到有一个新的签名可用,这是由映像推送引起的:

[root@192 ~]# ls /var/lib/containers/sigstore
'alpine@sha256=964248be4bb8e3052c8b411271126f70c5c5015df31e014bfc41fad50edf78d8'
[root@192 ~]# 

我们编辑的版本中的默认签名存储引用了侦听 的 Web 服务器。对于我们的实验,我们只需在本地暂存签名存储中启动一个新服务器:/etc/containers/registries.d/default.yamlhttp://localhost:8000
首先我们先安装一个python

[root@192 ~]# dnf module install python38 -y

然后进入文件配置网站服务

[root@192 ~]# cd /var/lib/containers/
[root@192 containers]# ls
cache  sigstore  storage
[root@192 containers]# cd sigstore/
[root@192 sigstore]# ls
'alpine@sha256=964248be4bb8e3052c8b411271126f70c5c5015df31e014bfc41fad50edf78d8'
[root@192 sigstore]# cat /etc/containers/registries.d/default.yaml 
# This is a default registries.d configuration file.  You may
# add to this file or create additional files in registries.d/.
#
# sigstore: indicates a location that is read and write
# sigstore-staging: indicates a location that is only for write
#
# sigstore and sigstore-staging take a value of the following:
#   sigstore:  {schema}://location
#
# For reading signatures, schema may be http, https, or file.
# For writing signatures, schema may only be file.

# This is the default signature write location for docker registries.
default-docker:
#  sigstore: file:///var/lib/containers/sigstore
  sigstore: http://localhost:8000
  sigstore-staging: file:///var/lib/containers/sigstore

# The 'docker' indicator here is the start of the configuration
# for docker registries.
#
# docker:
#
#   privateregistry.com:
#    sigstore: http://privateregistry.com/sigstore/
#    sigstore-staging: /mnt/nfs/privateregistry/sigstore

[root@192 sigstore]# pwd
/var/lib/containers/sigstore
[root@192 sigstore]# ss -antl
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            0.0.0.0:5000        0.0.0.0:*            
LISTEN  0       128               [::]:22             [::]:*            
[root@192 sigstore]# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

在添加一个防火墙规则让浏览器能够访问这IP

[root@192 ~]# firewall-cmd --add-rich-rule 'rule family=ipv4 source address=192.168.64.0/24 port port=8000 protocol=tcp accept' --permanent
success
[root@192 ~]# firewall-cmd --reload 
success
[root@192 ~]# 

访问网站看看
在这里插入图片描述
这边会话也有日志显示出来

[root@192 sigstore]# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

192.168.64.1 - - [16/Aug/2022 12:32:27] "GET / HTTP/1.1" 200 -
192.168.64.1 - - [16/Aug/2022 12:32:28] code 404, message File not found
192.168.64.1 - - [16/Aug/2022 12:32:28] "GET /favicon.ico HTTP/1.1" 404 -


让我们删除本地图像以进行验证测试:


[root@192 ~]# podman rmi docker.io/alpine localhost:5000/alpine
Untagged: docker.io/library/alpine:latest
Untagged: localhost:5000/alpine:latest
Deleted: c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18
[root@192 ~]# 

我们必须编写一个策略来强制签名必须有效。这可以通过在 中添加新规则来完成。从下面的示例中,将条目复制到
./etc/containers/policy.json"docker""transports"policy.json

{
  "default": [{ "type": "insecureAcceptAnything" }],
  "transports": {
    "docker": {
      "localhost:5000": [
        {
          "type": "signedBy",
          "keyType": "GPGKeys",
          "keyPath": "/tmp/key.gpg"
        }
      ]
    }
  }
}

尚不存在,因此我们必须将 GPG 密钥放在那里:keyPath

gpg --output /tmp/key.gpg --armor --export sgrunert@suse.com

如果我们现在拉动图像:

sudo podman pull --tls-verify=false localhost:5000/alpine
…
Storing signatures
e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a

然后,我们可以在Web服务器的日志中看到签名已被访问:

127.0.0.1 - - [04/Mar/2020 11:18:21] "GET /alpine@sha256=e9b65ef660a3ff91d28cc50eba84f21798a6c5c39b4dd165047db49e84ae1fb9/signature-1 HTTP/1.1" 200 -

作为对应的例子,如果我们在以下位置指定了错误的键:/tmp/key.gpg

gpg --output /tmp/key.gpg --armor --export mail@saschagrunert.de
File '/tmp/key.gpg' exists. Overwrite? (y/N) y

然后拉动就不可能了:

sudo podman pull --tls-verify=false localhost:5000/alpine
Trying to pull localhost:5000/alpine...
Error: error pulling image "localhost:5000/alpine": unable to pull localhost:5000/alpine: unable to pull image: Source image rejected: Invalid GPG signature: …

因此,一般来说,在使用 Podman 和 GPG 对容器映像进行签名时,需要考虑四个主要事项:

我们需要在签名计算机上有一个有效的私有GPG密钥,并在每个系统上需要相应的公钥来拉取映像
Web服务器必须在可以访问签名存储的地方运行
必须在任何文件中配置 Web 服务器/etc/containers/registries.d/*.yaml
每个映像拉取系统都必须配置为包含强制策略配置,通过以下方式policy.conf
这就是图像签名和GPG。很酷的是,此设置也可以与CRI-O开箱即用,并且可用于在Kubernetes环境中对容器映像进行签名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值