此示例容器将运行一个非常基本的 httpd 服务器,该服务器仅为其索引页提供服务
[[email protected] ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [[email protected] ~]# 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 d77ff9f653ce done Copying blob aaf5ad2e1aa3 done Copying blob 7692efc5f81c done Copying config 25c76f9dcd done Writing manifest to image destination Storing signatures 78dda9890d0f6cb13e47b347445ac93f43e4d993f4da5405943bf98c5bc9ab1a [[email protected] ~]#
由于容器在分离模式下运行(在命令中由 -d 表示),因此 Podman 将在运行后打印容器 ID。请注意,我们使用端口转发来访问 HTTP 服务器。要成功运行,至少需要 slirp4netns v0.3.0。
[[email protected] ~]# rpm -qa|grep slirp4netns slirp4netns-1.1.8-2.module_el8.7.0+1106+45480ee0.x86_64
检查正在运行的容器您可以“检查”正在运行的容器,以获取有关其自身的元数据和详细信息。我们甚至可以使用 inspect 子命令来查看分配给容器的 IP 地址。由于容器在无根模式下运行,因此不会分配 IP 地址,并且该值将在检查的输出中列为“无”。
[[email protected] ~]# podman inspect -l|grep -i ipaddress "IPAddress": "10.88.0.4", "IPAddress": "10.88.0.4", [[email protected] ~]#
注意:-l 是最新容器的便利参数。还可以使用容器的 ID 而不是 -l。
查看容器的日志您还可以使用 Podman 查看容器的日志:
[[email protected] ~]# podman logs -l => 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.4. Set the 'ServerName' directive globally to suppress this message [Mon Aug 15 16:09:45.049113 2022] [ssl:warn] [pid 1:tid 140289699057024] 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 [Mon Aug 15 16:09:45.053794 2022] [ssl:warn] [pid 1:tid 140289699057024] AH01909: 10.88.0.4:8443:0 server certificate does NOT include an ID which matches the server name AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.4. Set the 'ServerName' directive globally to suppress this message [Mon Aug 15 16:09:45.135165 2022] [ssl:warn] [pid 1:tid 140289699057024] 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 [Mon Aug 15 16:09:45.136249 2022] [ssl:warn] [pid 1:tid 140289699057024] AH01909: 10.88.0.4:8443:0 server certificate does NOT include an ID which matches the server name [Mon Aug 15 16:09:45.136619 2022] [lbmethod_heartbeat:notice] [pid 1:tid 140289699057024] AH02282: No slotmem from mod_heartmonitor [Mon Aug 15 16:09:45.143579 2022] [mpm_event:notice] [pid 1:tid 140289699057024] AH00489: Apache/2.4.39 (Fedora) OpenSSL/1.1.1 configured -- resuming normal operations [Mon Aug 15 16:09:45.143701 2022] [core:notice] [pid 1:tid 140289699057024] AH00094: Command line: 'httpd -D FOREGROUND' [Mon Aug 15 16:13:55.037879 2022] [autoindex:error] [pid 49:tid 140289360692992] [client 192.168.29.1:62999] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html) found, and server-generated directory index forbidden by Options directive 192.168.29.1 - - [15/Aug/2022:16:13:55 +0000] "GET / HTTP/1.1" 403 4650 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.54" 192.168.29.1 - - [15/Aug/2022:16:13:55 +0000] "GET /icons/apache_pb2.gif HTTP/1.1" 200 4234 "http://192.168.29.138:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.54" 192.168.29.1 - - [15/Aug/2022:16:13:55 +0000] "GET /icons/poweredby.png HTTP/1.1" 200 2616 "http://192.168.29.138:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.54" 192.168.29.1 - - [15/Aug/2022:16:13:55 +0000] "GET /favicon.ico HTTP/1.1" 404 209 "http://192.168.29.138:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.54" [[email protected] ~]#
[[email protected] ~]# podman top -l USER PID PPID %CPU ELAPSED TTY TIME COMMAND default 1 0 0.000 6m41.225719555s pts/0 0s httpd -D FOREGROUND default 23 1 0.000 6m41.225933692s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat default 24 1 0.000 6m41.225970422s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat default 25 1 0.000 6m41.226000575s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat default 26 1 0.000 6m41.22807663s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat default 27 1 0.000 6m41.228195335s pts/0 0s httpd -D FOREGROUND default 28 1 0.000 6m41.228245362s pts/0 0s httpd -D FOREGROUND default 31 1 0.000 6m41.228288782s pts/0 0s httpd -D FOREGROUND default 49 1 0.000 6m41.228320044s pts/0 0s httpd -D FOREGROUND [[email protected] ~]#
对容器执行检查点操作对容器执行检查点操作会停止容器,同时将容器中所有进程的状态写入磁盘。这样,容器以后可以还原,并在与检查点完全相同的时间点继续运行。此功能要求在系统上安装 CRIU 3.11 或更高版本。不支持此功能作为无根;因此,如果您想尝试一下,则需要使用相同的命令(但使用sudo)以root身份重新创建容器。要对容器使用检查点,请使用
[[email protected] ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 78dda9890d0f registry.fedoraproject.org/f29/httpd:latest /usr/bin/run-http... 8 minutes ago Up 8 minutes ago 0.0.0.0:8080->8080/tcp hungry_bell [[email protected] ~]# podman container checkpoint -l 78dda9890d0f6cb13e47b347445ac93f43e4d993f4da5405943bf98c5bc9ab1a [[email protected] ~]# ls anaconda-ks.cfg container-web.service
还原容器还原容器仅适用于以前检查点的容器。还原的容器将继续在检查点操作的同一时间点运行。
[[email protected] ~]# podman container restore -l 78dda9890d0f6cb13e47b347445ac93f43e4d993f4da5405943bf98c5bc9ab1a [[email protected] ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 78dda9890d0f registry.fedoraproject.org/f29/httpd:latest /usr/bin/run-http... 10 minutes ago Up 10 minutes ago 0.0.0.0:8080->8080/tcp hungry_bell
迁移容器要将容器从一个主机实时迁移到另一个主机,容器将在迁移的源系统上执行检查点操作,传输到目标系统,然后在目标系统上还原。传输检查点时,可以指定输出文件。
停止容器
要停止 httpd 容器,请执行以下操作:
podman stop --latest
您还可以使用 ps 子命令检查一个或多个容器的状态。在这种情况下,我们应该使用 -a 参数列出所有容器。
podman ps -a
移除容器删除 httpd 容器:
podman rm --latest
您可以通过运行 podman ps -a 来验证容器的删除。
[[email protected] ~]# podman rmi docker.io/alpine localhost:5000/alpine Untagged: docker.io/library/alpine:latest Untagged: localhost:5000/alpine:latest Deleted: c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18 [[email protected] ~]#
对容器映像进行签名源于仅信任专用映像提供程序的动机,以缓解中间人 (MITM) 攻击或对容器注册表的攻击。对图像进行签名的一种方法是使用 GNU 隐私卫士 (GPG) 密钥。此技术通常与任何符合 OCI 的容器注册表(如 Quay.io)兼容。值得一提的是,OpenShift 集成容器注册表开箱即用地支持这种签名机制,这使得单独的签名存储变得不必要。从技术角度来看,我们可以在将映像推送到远程注册表之前利用 Podman 对映像进行签名。之后,所有运行Podman的系统都必须配置为从远程服务器检索签名,远程服务器可以是任何简单的Web服务器。这意味着在映像拉取操作期间,每个未签名的映像都将被拒绝。但是这是如何工作的呢?首先,我们必须创建一个GPG密钥对或选择一个本地可用的密钥对。要生成新的GPG密钥,只需运行并按照交互式对话框进行操作即可。现在我们应该能够验证密钥是否在本地存在
[[email protected] ~]# podman run -d -p 5000:5000 docker.io/registry Trying to pull docker.io/library/registry:latest... Getting image source signatures Copying blob 3790aef225b9 done Copying blob e2ead8259a04 done Copying blob 79e9f2f55bf5 done Copying blob 0d96da54f60b done Copying blob 5b27040df4a2 done Copying config b8604a3fe8 done Writing manifest to image destination Storing signatures 673e89cc9f072e6474e59413691a2fb08af9dda10f5e9898eb827bb84e2d4388 [[email protected] ~]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:5000 0.0.0.0:* LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* [[email protected] ~]# 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 [[email protected] ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/busybox latest 7a80323521cc 2 weeks ago 1.47 MB docker.io/library/httpd latest dabbfbe0c57b 7 months ago 148 MB docker.io/library/alpine latest c059bfaa849c 8 months ago 5.87 MB docker.io/library/registry latest b8604a3fe854 9 months ago 26.8 MB docker.io/library/centos latest 5d0da3dc9764 11 months ago 239 MB quay.io/centos/centos latest 300e315adb2f 20 months ago 217 MB registry.fedoraproject.org/f29/httpd latest 25c76f9dcdb5 3 years ago 482 MB [[email protected] ~]# podman images alpine REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/alpine latest c059bfaa849c 8 months ago 5.87 MB [[email protected] ~]# podman tag alpine localhost:5000/alpine [[email protected] ~]# 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 [[email protected] ~]# [[email protected] ~]# cd /etc/containers/ [[email protected] containers]# ls certs.d oci policy.json registries.conf registries.conf.d registries.d storage.conf [[email protected] containers]# cd registries.d [[email protected] registries.d]# ls default.yaml registry.access.redhat.com.yaml registry.redhat.io.yaml [[email protected] registries.d]# vim default.yaml sigstore: http://localhost:8000 sigstore-staging: file:///var/lib/containers/sigstore [[email protected] ~]# 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: marui Email address: marui Not a valid email address Email address: [email protected] Comment: marui You selected this USER-ID: "marui (marui) <[email protected]>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? 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. 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 5FFF7EFCD429C026 marked as ultimately trusted gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/146DAAB2D98BED4A566AD5DC5FFF7EFCD429C026.rev' public and secret key created and signed. pub rsa2048 2022-08-15 [SC] 146DAAB2D98BED4A566AD5DC5FFF7EFCD429C026 uid marui123 (jjyy) <[email protected]> sub rsa2048 2022-08-15 [E] [[email protected] ~]# gpg --list-keys marui 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-15 [SC] 146DAAB2D98BED4A566AD5DC5FFF7EFCD429C026 uid [ultimate] marui123 (jjyy) <[email protected]> sub rsa2048 2022-08-15 [E] [[email protected] ~]# podman push --tls-verify=false --sign-by marui localhost:5000/alpineGetting image source signatures Copying blob 8d3ac3489996 done Copying config c059bfaa84 done Writing manifest to image destination Signing manifest Error: creating signature: Invalid value [[email protected] ~]# podman push --tls-verify=false --sign-by marui123 localhost:5000/alpine Getting image source signatures Copying blob 8d3ac3489996 done Copying config c059bfaa84 done Writing manifest to image destination Storing signatures [[email protected] ~]# ls /var/lib/containers/sigstore '[email protected]=a65d71e7a88c3a63246ec299abb0dcec671579ac0af199d96e2a82339f061199' [[email protected] ~]# dnf module install python38 -y [[email protected] ~]# cd /var/lib/containers/ [[email protected] containers]# ls cache sigstore storage [[email protected] containers]# cd sigstore/ [[email protected] sigstore]# ls '[email protected]=a65d71e7a88c3a63246ec299abb0dcec671579ac0af199d96e2a82339f061199' [[email protected] sigstore]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:5000 0.0.0.0:* LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* [[email protected] sigstore]# python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... [[email protected] ~]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* LISTEN 0 128 0.0.0.0:5000 0.0.0.0:* LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* [[email protected] ~]# firewall-cmd --add-rich-rule 'rule family=ipv4 source address=192.168.29.0/24 port port=8000 protocol=tcp accept' --permanent success [[email protected] ~]# firewall-cmd --reload success