使用 Cosign 对容器镜像进行签名,并确保未签名的镜像不被部署
通过对容器镜像进行签名,可以防止意外使用第三方镜像导致的安全事件。这次我们将使用cosign对容器镜像进行签名,并确认签名的具体运作方式。在此不讨论cosign是什么。knqyf263的sigstore上有一篇关于容器镜像和软件签名的文章非常易懂,如果想了解cosign的话推荐阅读该文章。
前提 tí)
以满足以下条件的状态开始。
-
- クライアントPCでDocker Daemonが起動済み
-
- Kubernetesが構築済み
- Harborが構築済み
为了确认Harbor的签名是否有效,可以使用它。但如果没有Harbor,也可以使用DockerHub等,但需要注意部分步骤可能会有变化。
署名的使用
安装cosign。
从官方网站获取安装步骤,但需要额外进行符号链接操作,所以请注意。
针对每个操作系统都有相应的安装步骤可供使用,除了Debian系统的用户外,其他用户需要参考各自的安装步骤进行安装。
wget "https://github.com/sigstore/cosign/releases/download/v1.6.0/cosign_1.6.0_amd64.deb"
sudo dpkg -i "cosign_1.6.0_amd64.deb"
sudo ln -s /usr/local/bin/cosign-linux-amd64 /usr/local/bin/cosign
在进行cosign签名之前,需要提前创建密钥对。在这里,我们将密码设置为hogefuga。
$ cosign generate-key-pair
Enter password for private key:
Enter password for private key again:
Private key written to cosign.key
Public key written to cosign.pub
执行完成后,将在当前目录下创建私钥和公钥。
$ ls
cosign.key cosign.pub
使用创建的密钥对对容器镜像进行签名。
cosign sign --key cosign.key myharbor.info/myapp/mynginx
确认署名的效果
将未署名的映像为了测试目的,将DockerHub上的nginx复制到自己的Harbor上。
docker pull nginx
docker tag nginx myharbor.info/myapp/nginx-not-signed
docker push myharbor.info/myapp/nginx-not-signed
尝试使用各自的形象来启动Pod。
kubectl run --image myharbor.info/myapp/nginx-not-signed nginx-not-signed
kubectl run --image myharbor.info/myapp/mynginx mynginx
可以发现只有使用了未署名的图像的Pod启动失败。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
mynginx 1/1 Running 0 81s
nginx-not-signed 0/1 ImagePullBackOff 0 72s
查看错误详情,如下所示。
$ kubectl describe pod nginx-not-signed
:(省略)
Warning Failed 17s (x4 over 111s) kubelet Failed to pull image "myharbor.info/myapp/nginx-not-signed": rpc error: code = Unknown desc = failed to pull and unpack image "myharbor.info/myapp/nginx-not-signed:latest": failed to resolve reference "myharbor.info/myapp/nginx-not-signed:latest": pulling from host myharbor.info failed with status code [manifests latest]: 412 Precondition Failed
如果未署名,则会返回错误代码412。