容器镜像在进入生产环境之前是否满足安全合规要求,不能只依赖漏洞扫描报告。Anchore 提供了一套策略即代码机制,让团队能够把允许或拒绝镜像的条件描述成结构化规则,并在构建或推送阶段由机器自动判定。相比临时的人工核查,策略合规真正把安全要求变成可重复执行的流水线环节。

Anchore 的核心能力不只是列出镜像里有多少个 CVE,它更强调根据自定义策略对镜像做出整体裁决。策略可以规定只有高危漏洞数量为零才允许进入生产仓库,也可以要求基础镜像必须来自白名单列表,还可以检查镜像是否包含特定许可证的组件。这样,合规就变成了一组可追踪、可审计的规则,而不是运维人员靠经验做的口头判断。
合规判定的基础:策略包与规则结构
Anchore 使用 policy bundle 来组织策略。一个 policy bundle 由多个 policy 组成,每个 policy 包含若干 rule,而每个 rule 又关联到一个 gate 和 trigger。简单理解,gate 表示检查类别,比如漏洞、许可证、Dockerfile 配置;trigger 表示该类别下的具体条件,比如出现高危漏洞、发现 GPL 许可证、暴露了未声明的端口。action 则决定命中该条件时执行什么操作,通常可以设置为 go、warn 或 stop。
下面是一个最小化的 policy bundle 结构,用来演示规则层级关系。它定义了一条漏洞策略,当扫描结果中出现高危漏洞时直接拒绝镜像。
apiVersion: v1
kind: PolicyBundle
metadata:
name: production-compliance
spec:
policies:
- name: vulnerability-policy
version: 1_0
rules:
- gate: vulnerabilities
trigger: package
action: stop
parameters:
- name: package_type
value: all
- name: severity
value: high
实际使用中,policy bundle 还需要配合 allowed images 和 mapping 规则来指定哪些镜像受该策略约束。Anchore 会先根据 registry、repository 或 tag 匹配镜像,再执行对应的策略。策略匹配支持通配符和精确名称,因此可以为生产镜像、测试镜像分别绑定不同严苛程度的规则。
理解 gate 和 trigger 的组合是编写有效策略的前提。比如 vulnerabilities gate 下有 package、severity、cve_id 等多个 trigger。如果只想检查特定操作系统包的高危漏洞,可以限制 package_type;如果只想针对某个 CVE 做拦截,可以使用 cve_id trigger 并指定具体编号。这种细粒度控制使得合规策略既能覆盖全局安全要求,也能处理临时性的紧急漏洞通告。
编写实用的镜像合规策略
生产环境常见的合规要求包括:禁止高危漏洞、禁止使用非白名单基础镜像、禁止包含未经批准的许可证类型,以及要求镜像必须声明健康检查或暴露的端口。下面这个策略片段展示了如何同时检查漏洞和许可证,并将漏洞级别设置为高危及以上才阻断,许可证则只拦截 GPL 和 AGPL 类组件。
- name: license-compliance
version: 1_0
rules:
- gate: licenses
trigger: license
action: stop
parameters:
- name: licenses
value: GPL,AGPL
- name: exact_match
value: false
另一个高频场景是检查 Dockerfile 中的敏感配置。例如,如果镜像暴露了 SSH 端口 22,或者以 root 用户运行,应该触发告警或直接失败。Anchore 的 dockerfile gate 可以读取构建指令并据此判断。下面这段策略会对暴露 22 端口的镜像发出警告,同时阻断使用 root 用户的镜像。
- name: dockerfile-policy
version: 1_0
rules:
- gate: dockerfile
trigger: exposed_ports
action: warn
parameters:
- name: ports
value: 22
- gate: dockerfile
trigger: user
action: stop
parameters:
- name: user
value: root
编写策略时要注意,action 为 stop 的规则会让整个镜像判定为失败,action 为 warn 则只记录警告但不会阻断流水线。因此,刚引入策略合规时可以先从 warn 开始,观察一段时间后再逐步调整为 stop,避免误报打乱正常发布节奏。策略文件本身可以纳入版本管理,与代码库一起评审和变更,这也是策略即代码带来的直接收益。
把策略检查接入CI/CD流水线
单靠命令行手动执行策略检查很难形成稳定约束。把 Anchore 策略评估集成到 CI/CD 流程中,可以让每次镜像构建都自动完成合规判定。典型做法是在镜像推送到 registry 后,调用 Anchore 的 CLI 或 API 触发分析,等待分析完成,再根据策略结果决定是否继续部署。
下面是一组常用的 anchore-cli 命令,用来添加镜像、等待分析结束并执行策略检查。命令中的 --tag 参数用于指定策略映射标签,该标签需要与 policy bundle 中的 mapping 对应。
anchore-cli image add registry.ipipp.com/app:latest anchore-cli image wait registry.ipipp.com/app:latest anchore-cli evaluate check registry.ipipp.com/app:latest --tag production-compliance --detail
在 Jenkins、GitLab CI 或 GitHub Actions 中,可以通过捕获 evaluate check 的退出码来判断是否放行。命令返回非零时表示镜像未通过策略,流水线应终止后续部署步骤。为了减少等待时间,可以在镜像推送后立即调用 analysis-import 或利用 Anchore 的 webhook 通知机制,当分析完成后再触发策略评估。
此外,可以将 Anchore 策略检查与镜像扫描工具区分开来。扫描工具只负责产生数据,策略引擎负责根据数据做出业务决策。CI/CD 中应调用策略评估结果,而不是直接解析扫描报告。这样当漏洞库更新或策略调整后,只需要重新运行评估命令,无需修改流水线脚本。
误报治理与白名单机制
策略上线初期往往会出现大量误报,原因可能是基础镜像不包含实际可利用的漏洞,或者某些许可证组件只在构建阶段使用而不进入最终运行环境。Anchore 允许在策略规则内设置排除条件,也可以使用 whitelist 来忽略特定镜像、CVE 或包。白名单并不是简单关闭检查,而是精准标记某个已经人工确认过的风险项。
例如,某个高危 CVE 只影响 Windows 平台,但镜像运行在 Linux 上,就可以在策略中忽略该 CVE。或者某个 GPL 组件被打包进镜像但最终会被多阶段构建丢弃,则可以根据包名加版本进行排除。白名单应集中管理,并定期评审,否则时间一长就会积累大量例外,削弱策略合规的严肃性。
Anchore 的策略执行结果会输出每个 rule 的触发原因、命中的包或 CVE 信息,这为误报排查提供了完整上下文。团队可以建立流程:当某个镜像被策略拦截时,开发者先查看 evaluate 详情,确认是否属于误报;如果属实,再提交白名单变更请求。只有经过负责人审批的白名单项才能合入策略仓库,从而在安全与效率之间保持平衡。
随着对误报的处理,策略本身也会越来越贴合实际业务。与其追求一次性写出一套完美策略,不如采用渐进式收紧的方式。先拦截最高风险项,再逐步增加许可证和配置类规则,最终形成覆盖构建、测试、生产全链路的镜像合规基线。