容器安全与镜像扫描
1. 镜像漏洞扫描
1.1 Trivy(推荐,开源)
brew install trivy
# 扫镜像
trivy image myapp:latest
trivy image --severity HIGH,CRITICAL myapp:latest
trivy image --ignore-unfixed myapp:latest # 忽略无修复的
# 扫文件系统
trivy fs .
# 扫配置(K8s yaml / Dockerfile)
trivy config .
# 扫 git repo
trivy repo https://github.com/myorg/myapp
CI 集成:
- uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:$}} github.sha }}
severity: HIGH,CRITICAL
exit-code: 1
ignore-unfixed: true
1.2 Snyk
snyk container test myapp:latest
snyk container monitor myapp:latest
1.3 Docker Scout
docker scout cves myapp:latest
docker scout quickview myapp:latest
docker scout recommendations myapp:latest
1.4 Grype
grype myapp:latest
2. 镜像签名
防中间人篡改 + 来源验证。
2.1 Cosign(Sigstore)
# 安装
brew install cosign
# 生成密钥对
cosign generate-key-pair
# 签名
cosign sign --key cosign.key ghcr.io/myorg/myapp@sha256:xxx
# 验证
cosign verify --key cosign.pub ghcr.io/myorg/myapp@sha256:xxx
无密钥(OIDC)签名:
COSIGN_EXPERIMENTAL=1 cosign sign ghcr.io/myorg/myapp@sha256:xxx
K8s 强制只运行已签名镜像(Kyverno / Sigstore Policy Controller):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-images
spec:
validationFailureAction: enforce
rules:
- name: check-image
match:
resources: { kinds: [Pod] }
verifyImages:
- imageReferences: ["ghcr.io/myorg/*"]
attestors:
- entries:
- keys:
publicKeys: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
3. 运行时安全
3.1 容器配置加固
详见模块 04 「生产安全与资源限制」。要点:
- 非 root(
USER node) - 只读文件系统
- 删 capabilities
- seccomp 默认 profile
- 资源限制
- no-new-privileges
# K8s
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
seccompProfile:
type: RuntimeDefault
3.2 运行时威胁检测:Falco
监控容器内异常行为(spawn shell、读敏感文件、外联恶意 IP):
helm install falco falcosecurity/falco -n falco --create-namespace
规则示例:
- rule: Shell in Container
desc: Detect shell spawned in container
condition: >
spawned_process and container.id != host
and proc.name in (sh, bash, zsh, ash)
output: Shell in container (}}container.name}})
priority: WARNING
4. K8s Pod Security Standards
baseline / restricted 级别强制(详见模块 05 RBAC):
metadata:
labels:
pod-security.kubernetes.io/enforce: restricted
5. 网络隔离
NetworkPolicy 默认拒绝(详见模块 05):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
6. Secret 管理
详见模块 05 ConfigMap / Secret 与 Vault 实践:
- etcd 加密
- sealed-secrets / external-secrets
- 不挂 Docker socket
- Pod 内不调 K8s API(除非必要)
7. 镜像最小化
# ✗ 完整 Ubuntu,几百 MB,CVE 多
FROM ubuntu:22.04
# ✓ Alpine
FROM node:20-alpine
# ✓✓ Distroless 无 shell
FROM gcr.io/distroless/nodejs20-debian12
# ✓✓✓ scratch(Go 二进制)
FROM scratch
镜像越小 = 攻击面越小 + CVE 越少。
8. CI 安全门
- name: Build image
uses: docker/build-push-action@v6
with: { tags: temp:scan }
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: temp:scan
severity: CRITICAL,HIGH
exit-code: 1 # 高危阻断
- name: Cosign sign
if: success()
run: cosign sign --key env://COSIGN_KEY ghcr.io/myorg/myapp@$DIGEST
- name: Push
uses: docker/build-push-action@v6
with: { tags: ghcr.io/myorg/myapp:v1.0.0, push: true }
9. 常见反模式
- 不扫描就上线:CVE 累积
- 以 root 跑容器:逃逸 = 宿主 root
- 挂 Docker socket:等于给容器宿主管理员权限
--privileged:关掉所有安全机制- 不签镜像:可能拉到被替换的镜像
- secret 写镜像:所有 layer 包含
- 生产装 SSH / 调试工具:扩大攻击面
- 不限网络:被入侵后横向移动毫无障碍