本指南演示如何配置 Kyverno,以验证容器镜像在 Kubernetes 集群中运行前是否已正确签名。可以将其类比为检查身份证——只有带有有效“签名”的镜像才被允许使用。
镜像签名验证就像门口的保安检查身份证。它确保:
# 创建签名密钥对(类似创建身份证系统)
cosign generate-key-pair
# 这会生成:cosign.key(私钥,需保密)和 cosign.pub(公钥,可自由分享)
# 签名镜像(类似盖上官方印章)
cosign sign --key cosign.key registry.company.com/app:v1.0.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-signed-images
spec:
validationFailureAction: Enforce # 阻止未签名镜像
background: false
rules:
- name: check-signatures
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.company.com/*" # 检查公司镜像仓库的镜像
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
# 在此粘贴 cosign.pub 内容
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
-----END PUBLIC KEY-----
mutateDigest: true # 将标签转换为安全的摘要格式
# 应用策略
kubectl apply -f signature-policy.yaml
# 尝试运行未签名镜像(应失败)
kubectl run test --image=nginx:latest
# 尝试运行已签名镜像(应成功)
kubectl run test --image=registry.company.com/app:v1.0.0
对于关键应用,开发团队和安全团队都可能需要对镜像进行签名:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-dual-signatures
spec:
validationFailureAction: Enforce
background: false
rules:
- name: critical-app-signatures
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.company.com/critical/*"
attestors:
# 两个团队都必须签名
- count: 1 # 安全团队签名
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
# 安全团队公钥
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
-----END PUBLIC KEY-----
- count: 1 # 开发团队签名
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
# 开发团队公钥
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyctVd7iEcnessRQjU917hmKO6JWV
GHpDguIyakZA8nXRh950IZbRj8Ra/N9sbqOPZrfM5/KAQN0/KjHcorm/J5==
-----END PUBLIC KEY-----
mutateDigest: true
生产环境需要严格验证,开发环境可以更宽松:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: environment-specific-verification
spec:
validationFailureAction: Enforce
background: false
rules:
# 生产环境严格规则
- name: production-must-be-signed
match:
any:
- resources:
kinds:
- Pod
namespaces:
- production
verifyImages:
- imageReferences:
- "*" # 所有镜像必须签名
failureAction: Enforce # 未签名时阻止
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
# 生产签名密钥
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
-----END PUBLIC KEY-----
mutateDigest: true
# 开发环境宽松规则
- name: development-warn-unsigned
match:
any:
- resources:
kinds:
- Pod
namespaces:
- development
- staging
verifyImages:
- imageReferences:
- "registry.company.com/*" # 仅检查公司镜像
failureAction: Audit # 审计但允许未签名镜像
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
# 开发签名密钥
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyctVd7iEcnessRQjU917hmKO6JWV
GHpDguIyakZA8nXRh950IZbRj8Ra/N9sbqOPZrfM5/KAQN0/KjHcorm/J5==
-----END PUBLIC KEY-----
mutateDigest: true
在企业环境中,可能使用 X.509 证书:
# 使用证书签名
cosign sign --cert company-cert.pem --cert-chain ca-chain.pem \
registry.company.com/myapp:v1.0.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: certificate-verification
spec:
validationFailureAction: Enforce
background: false
rules:
- name: verify-with-certificates
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.company.com/*"
attestors:
- count: 1
entries:
- certificates:
cert: |-
-----BEGIN CERTIFICATE-----
# 公司的签名证书(请替换为真实证书)
MIIDXTCCAkWgAwIBAgIJAKoK/heBjcOuMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwODI4MTExNzQwWhcNMTgwODI4MTExNzQwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuuExVilGcXIZ3ulNuL7wLrA7VkqJoGpB1YPmYnlS7sobTggOGSqMUvqU
BdLXcAo3ZCOXuKrBHBlltvcNdFHynfxOtkAOCZjirD6uQBrNPiQDlgMYMy14QIDAQAB
o1AwTjAdBgNVHQ4EFgQUhKs8VQFhVLp5J4W1sFVLOVgnQxwwHwYDVR0jBBgwFoAU
hKs8VQFhVLp5J4W1sFVLOVgnQxwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUF
AAOCAQEAuuExVilGcXIZ3ulNuL7wLrA7VkqJoGpB1YPmYnlS7sobTggOGSqMUvqU
-----END CERTIFICATE-----
rekor:
url: https://rekor.sigstore.dev
mutateDigest: true