podman进阶
文章目录
如何使用 Podman 签署和分发容器镜像
签署容器镜像的动机是只信任专门的镜像提供者以减轻中间人 (MITM) 攻击或对容器注册表的攻击。签署图像的一种方法是使用 GNU Privacy Guard ( GPG ) 密钥。这种技术通常与任何符合 OCI 的容器注册表兼容,例如Quay.io。值得一提的是,OpenShift 集成容器注册表开箱即用地支持这种签名机制,这使得单独的签名存储变得不必要。
从技术角度来看,我们可以利用 Podman 对镜像进行签名,然后再将其推送到远程注册表。之后,所有运行 Podman 的系统都必须配置为从远程服务器检索签名,远程服务器可以是任何简单的 Web 服务器。这意味着在图像拉取操作期间,每个未签名的图像都将被拒绝。但这是如何工作的?
首先,我们必须创建一个 GPG 密钥对或选择一个已经在本地可用的密钥对。要生成新的 GPG 密钥,只需运行gpg --full-gen-key并按照交互式对话框操作。现在我们应该能够验证密钥在本地是否存在:
gpg --list-keys sgrunert@suse.com
pub rsa2048 2018-11-26 [SC] [expires: 2020-11-25]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid [ultimate] Sascha Grunert <sgrunert@suse.com>
sub rsa2048 2018-11-26 [E] [expires: 2020-11-25]
现在让我们假设我们运行一个容器注册表。例如,我们可以简单地在本地机器上启动一个:
[root@localhost ~]# sudo podman run -d -p 5000:5000 docker.io/registry
532c7d4fd848e05fc39dc75b772e27df842f5ed5308745889c4487aadcf20f9f
[root@localhost ~]#
注册表对镜像签名一无所知,它只是为容器镜像提供远程存储。这意味着如果我们想要对图像进行签名,我们必须注意如何分发签名。
alpine让我们为我们的签名实验选择一个标准图像:
[root@localhost ~]# sudo podman pull docker://docker.io/alpine:latest
9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5
[root@localhost ~]#
[root@localhost ~]# sudo podman images alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/alpine latest 9c6f07244728 6 days ago 5.83 MB
[root@localhost ~]#
现在我们可以重新标记图像以将其指向我们的本地注册表:
[root@localhost ~]# sudo podman tag alpine localhost:5000/alpine
[root@localhost ~]# sudo podman images alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/alpine latest 9c6f07244728 6 days ago 5.83 MB
localhost:5000/alpine latest 9c6f07244728 6 days ago 5.83 MB
[root@localhost ~]#
Podman 现在可以通过一个命令推送图像并对其进行签名。但是要让它工作,我们必须在以下位置修改我们的系统范围的注册表配置
[root@localhost ~]# vim /etc/containers/registries.d/default.yaml
14 default-docker:
15 sigstore: sigstore: http://localhost:8000 # Added by us
16 sigstore-staging: file:///var/lib/containers/sigstore
我们可以看到我们配置了两个签名存储:
- sigstore: 引用 Web 服务器进行签名读取
- sigstore-staging: 引用文件路径进行签名写入
现在,让我们推送并签署图像:
sudo -E GNUPGHOME=$HOME/.gnupg \
podman push \
--tls-verify=false \
--sign-by sgrunert@suse.com \
localhost:5000/alpine
…
Storing signatures
如果我们现在看一下系统签名存储,我们会看到有一个新的签名可用,这是由图像推送引起的:
[root@localhost ~]# sudo ls /var/lib/containers/sigstore
'alpine@sha256=e9b65ef660a3ff91d28cc50eba84f21798a6c5c39b4dd165047db49e84ae1fb9'
我们编辑的版本中的默认签名存储 /etc/containers/registries.d/default.yaml引用了一个正在监听的 Web 服务器 http://localhost:8000。对于我们的实验,我们只需在本地临时签名存储中启动一个新服务器:
sudo bash -c 'cd /var/lib/containers/sigstore && python3 -m http.server'
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
让我们删除本地图像以进行验证测试:
[root@localhost ~]# sudo podman rmi docker.io/alpine localhost:5000/alpine
我们必须编写一个策略来强制签名必须是