二进制授权:只允许部署受信镜像
FreeGuideOnline
最新
2026-07-04
bash cosign generate-key-pair
执行后会生成两个文件:
- `cosign.key`:私钥(务必妥善保管,不要上传到公开仓库)
- `cosign.pub`:公钥(用于验证签名)
### 1.2 登录镜像仓库
```bash
# 以 Docker Hub 为例
docker login
1.3 构建并推送一个测试镜像
创建一个简单的 Dockerfile:
FROM alpine:3.18
CMD ["echo", "hello secure world"]
构建并推送:
docker build -t <your-registry>/hello-secure:v1 .
docker push <your-registry>/hello-secure:v1
替换
<your-registry>为你的实际仓库路径,例如docker.io/myuser/hello-secure:v1。
1.4 用 Cosign 对镜像签名
cosign sign --key cosign.key <your-registry>/hello-secure:v1
执行后,签名会被上传到镜像仓库中(以 OCI artifact 形式存储)。你可以用以下命令验证签名已经存在:
cosign verify --key cosign.pub <your-registry>/hello-secure:v1
如果输出镜像摘要和验证通过的信息,则表示签名成功。
第二步:部署策略引擎(Kyverno)
我们使用 Kyverno 作为 Kubernetes 动态准入控制器,来强制执行“只允许已签名镜像”的策略。
2.1 安装 Kyverno
kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.10.0/install.yaml
等待所有 Pod 就绪:
kubectl get pods -n kyverno
2.2 创建验证公钥的 Secret
为了让 Kyverno 能校验镜像签名,需要将你的公钥注入集群。
kubectl create secret generic mycosign-pub --from-file=cosign.pub -n kyverno
本例中密钥放在
kyverno命名空间,策略可以跨命名空间引用它。
第三步:编写镜像验证策略
使用 Kyverno 的 ClusterPolicy 资源定义签名校验规则。
3.1 策略 YAML 示例
创建一个文件 require-image-signature.yaml:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-image-signature
spec:
validationFailureAction: Enforce # 拒绝未签名镜像
background: false
rules:
- name: check-image-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "*" # 匹配所有镜像,可根据需求限定仓库
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
<你的公钥内容>
-----END PUBLIC KEY-----
将
<你的公钥内容>替换为cosign.pub文件中的完整内容,注意保留 PEM 格式。
如果你希望直接从 Secret 引用公钥(更安全),可以使用:
attestors:
- count: 1
entries:
- keys:
secret:
name: mycosign-pub
namespace: kyverno
3.2 应用策略
kubectl apply -f require-image-signature.yaml
策略生效后,任何未签名的镜像在创建 Pod 时都会被拒绝。
第四步:测试二进制授权效果
4.1 测试已签名镜像
创建一个使用已签名镜像的 Pod:
# secure-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secure-test
spec:
containers:
- name: hello
image: <your-registry>/hello-secure:v1
部署:
kubectl apply -f secure-pod.yaml
Pod 应成功创建。
4.2 测试未签名镜像
尝试部署一个公共镜像(通常未签名):
kubectl run insecure-test --image=alpine:3.18 --command -- sleep 3600
你将看到类似以下的拒绝信息:
Error from server: admission webhook "validate.kyverno.svc-fail" denied the request:
failed to verify image alpine:3.18: no matching signatures found