news 2026/9/16 23:13:40

在 Kubernetes 集群内集成 Checkov:以只读 Job 方式扫描运行时资源

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Kubernetes 集群内集成 Checkov:以只读 Job 方式扫描运行时资源

在 Kubernetes 集群内集成 Checkov:以只读 Job 方式扫描运行时资源

【免费下载链接】checkovPrevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.项目地址: https://gitcode.com/GitHub_Trending/ch/checkov

Checkov 本质上是一个面向构建期的静态代码扫描工具,但 Kubernetes 集群中运行的资源与构建期的声明式描述(YAML/JSON)具有完全相同的结构,因此 Checkov 完全可以部署进集群内部,以只读权限扫描真实的运行时资源并输出违规报告。本文将基于当前仓库的 Kubernetes 集成文档 与 kubernetes/ 目录下的完整实现,讲解如何把 Checkov 以 Kubernetes Job 形式部署到集群、如何解读其 RBAC 权限模型、如何理解运行脚本的数据流,以及如何在运行时场景下跳过与 CI 语义冲突的检查项。

为什么要在集群内运行 Checkov

Checkov 的常规用法是在构建阶段对基础设施即代码(IaC)文件做静态分析:提交代码 → CI 触发扫描 → 输出违规报告。但这种方式只能覆盖“仓库里写的配置”,无法覆盖“集群里实际运行的资源”。例如:

  • 运维人员通过kubectl run临时创建的 Pod;
  • 通过 Helm、Kustomize 或其他工具在运行时生成的资源;
  • 其他团队直接kubectl apply进集群的配置。

Checkov 的静态扫描模型与 Kubernetes 资源模型天然兼容——集群中的 Deployment、Service、NetworkPolicy 等资源与仓库里的 YAML 文件拥有相同的apiVersionkindmetadataspec结构。因此可以让 Checkov 在集群内部以只读访问方式枚举并导出全部资源,再对其执行与构建期完全一致的扫描逻辑(复用 checkov/kubernetes/runner.py 中的 Kubernetes Runner),从而对集群的“实际状态”做合规审计。

这种模式的一个关键差异在于报告维度:构建期 Checkov 报告的是“不合规的文件”,而运行时没有文件概念,报告对象是集群中的资源对象(如Deployment.default.nginx)。从 kubernetes_utils.py 可以看到,Kubernetes Runner 通过get_resource_id生成{Kind}.{namespace}.{name}形式的资源标识,这正是运行时报告的组织方式。

前置条件

在集群中运行 Checkov 之前需要满足以下条件:

  1. Kubernetes CLI 访问权限:必须能够通过kubectl访问目标集群(文档原话:To run Checkov in your cluster, you must have Kubernetes CLI access to the cluster)。Job 容器内部会调用kubectl枚举集群资源,容器本身不依赖外部凭据,而是通过 ServiceAccount 挂载的集群内凭据完成认证。
  2. 集群支持创建 Namespace、ServiceAccount、ClusterRole、ClusterRoleBinding 与 Job:清单需要相应的创建权限。
  3. 容器运行时能拉取镜像:默认使用bridgecrew/checkov-k8s:latest,并设置了imagePullPolicy: Always

部署:一条命令创建完整的只读扫描 Job

文档给出的部署命令为:

kubectl apply -f https://raw.githubusercontent.com/bridgecrewio/checkov/main/kubernetes/checkov-job.yaml

在当前仓库中,该清单即 kubernetes/checkov-job.yaml。与文档中的一句话部署相比,仓库内的完整清单实际包含五个对象,各司其职:

对象名称作用
Namespacecheckov隔离扫描任务及其配套对象
ServiceAccountcheckov(namespace: checkov)为 Job 提供集群内身份
ClusterRolecheckov-view只读权限集合,覆盖绝大多数资源类型,但不含 secrets
ClusterRoleBindingcheckov将 ServiceAccount 绑定到 ClusterRole
Jobcheckov(namespace: checkov)执行一次性的扫描任务

应用后可通过以下命令查看任务状态与输出:

kubectl get jobs -n checkov kubectl logs job/checkov -n checkov

权限模型:只读、最小化、不含 Secrets

checkov-viewClusterRole 的设计遵循最小权限原则,核心特征如下:

  • 权限动词全部为getlistwatch,没有任何createupdatepatchdelete
  • 覆盖的资源包括:ConfigMap、Endpoint、PersistentVolumeClaim、Pod、ReplicationController、ServiceAccount、Service、Deployment、DaemonSet、StatefulSet、ReplicaSet、CronJob、Job、Ingress、NetworkPolicy、PodSecurityPolicy、Role/RoleBinding/ClusterRole/ClusterRoleBinding、ResourceQuota、LimitRange、HorizontalPodAutoscaler、PodDisruptionBudget、Namespace、metrics.k8s.io 的 Pods/Nodes 等;
  • 刻意排除了secrets资源:清单注释明确写明 “View all resources EXCEPT secrets”,避免扫描器触达敏感凭据;
  • 通过 ClusterRoleBinding 将checkovServiceAccount 绑定到该只读角色,Job 的 Pod 通过serviceAccountName: checkov显式使用这一身份(见 checkov-job.yaml)。

Job 的安全基线

清单中的 Job 本身也贯彻了安全加固,这与 Checkov 自身的 Kubernetes 策略(CKV_K8S 系列)理念一致:

  • securityContext.runAsNonRoot: truerunAsUser: 12000(与 Dockerfile 中创建的checkov系统用户 UID 12000 对应,见 kubernetes/Dockerfile);
  • 容器级securityContext设置allowPrivilegeEscalation: falsedrop: [ALL]全部 Linux capabilities;
  • Pod 级seccompProfile.type: RuntimeDefault
  • restartPolicy: Never,保证 Job 失败后不会无限重启污染日志;
  • 资源配额requests/limits均为内存 256Mi、CPU 500m,防止扫描失控占用集群资源。

关于跳过注释的说明

清单的 Job 与 Pod 模板注解中声明了四个checkov.io/skip*跳过项,这是“用 Checkov 扫描 Checkov 自身”时产生的豁免,值得逐个理解(对应实现位于 checkov/kubernetes/checks/resource/k8s/):

  • CKV_K8S_22=Checkov requires filesystem write access to dump resource definitions:该检查对应 ReadOnlyFilesystem.py,要求容器只读文件系统。而扫描器需要把导出的资源定义写入/data目录,因此豁免;
  • CKV_K8S_38=Service Account is required for read-only API access:该检查对应 ServiceAccountTokens.py,要求关闭automountServiceAccountToken。但本 Job 恰恰需要 ServiceAccount 令牌来完成只读 API 访问,因此豁免;
  • CKV_K8S_14=Preferring latest rules every run - image pull always:对应 ImageTagFixed.py,该检查要求镜像 tag 固定、不得使用latest。而镜像bridgecrew/checkov-k8s:latest配合imagePullPolicy: Always是为了每次运行都拉取最新规则,属于有意为之;
  • CKV_K8S_43=Preferring latest rules every run - image pull always:对应 ImageDigest.py,同样是对“镜像未使用 digest 固定版本”的豁免。

从源码看,注解形式的跳过机制在 kubernetes_utils.py 的get_skipped_checks中实现:它遍历资源metadata.annotations,识别以checkov.io/skipbridgecrew.io/skipcortex.io/skip开头的注解键,解析检查ID=原因格式并返回为跳过项列表。这意味着你在集群中扫描到的任何资源,也可以就地添加同样的注解来声明豁免原因。

运行原理:从集群枚举到静态扫描

文档只给出了部署与查看日志的命令,但其背后是一条完整的“导出 → 落盘 → 扫描 → 上报”流水线,由 kubernetes/run_checkov.sh 承载,该脚本也是镜像 kubernetes/Dockerfile 的 ENTRYPOINT。

第一步:枚举并导出资源

脚本内置一个资源类型列表,涵盖 ClusterRole、ClusterRoleBinding、ConfigMap、CronJob、DaemonSet、Deployment、Endpoint、HPA、Ingress、Job、LimitRange、NetworkPolicy、PodDisruptionBudget、Pod、PodSecurityPolicy、ReplicaSet、ReplicationController、ResourceQuota、Role、RoleBinding、ServiceAccount、Service、StatefulSet 等 23 类资源,随后循环执行:

kubectl get $resource --all-namespaces -oyaml | yq eval 'del(.items[] | select(.metadata.ownerReferences)) ' - > /data/runtime.${resource}.yaml

其中两个细节值得注意:

  • --all-namespaces:枚举全集群资源而非单个命名空间;
  • del(.items[] | select(.metadata.ownerReferences)):借助 yq 删除带有ownerReferences的子资源(例如 Deployment 自动衍生的 ReplicaSet、ReplicaSet 衍生的 Pod),避免重复扫描由上层控制器管理的对象。

导出的 YAML 统一写入/data目录,这也是 Job 注解中声明“需要文件系统写权限”的原因。

第二步:执行 Checkov 扫描

导出完成后,脚本根据是否存在 API Key 选择两种模式:

模式一:本地扫描(无 API Key)

checkov -s -d /data --framework kubernetes "$@"

参数含义:

  • -s:soft-fail 软失败模式,扫描发现的违规不会导致进程以非零退出码结束,适合只读审计场景;
  • -d /data:扫描目录指向导出的资源文件;
  • --framework kubernetes:仅启用 Kubernetes 框架,避免对导出的 YAML 做其他框架的误判;
  • "$@":透传用户在命令中附加的任意 Checkov 参数(例如--skip-check--compact等)。

模式二:平台上报(存在 API Key)

checkov -s -d /data --bc-api-key "$apikey" --repo-id "$repoid" --branch runtime --framework kubernetes "$@"

当挂载了/etc/checkov/apikey与可选的/etc/checkov/repoid(可通过 Secret 卷挂载实现)时,会将扫描结果上报到 Bridgecrew/Checkov 平台,--repo-id缺省为runtime/unknown--branch固定为runtime,用于在平台上区分“运行时扫描”与“构建期扫描”。

第三步:镜像内容

kubernetes/Dockerfile 揭示了运行环境的关键构成:

  • 基础镜像python:3.11-slim,通过 kubernetes/requirements.txt 安装固定版本checkov==3.3.14(锁版本保证了行为可复现);
  • 安装kubectl客户端(从官方 release 通道下载 stable 版本);
  • 安装yq(v4.16.2)用于 YAML 处理;
  • 创建 UID 12000 的非 root 用户checkov,并设置/data/app/home/checkov的属主,配合清单中的runAsUser: 12000以非 root 身份运行。

与构建期扫描的关系:同一套引擎

运行时扫描并没有引入新的检测逻辑,而是复用构建期的 Kubernetes Runner。从 checkov/kubernetes/runner.py 的源码结构看:

  • Runner 的check_type = CheckType.KUBERNETES,与 CLI 中--framework kubernetes对应;
  • 扫描前会构建 Kubernetes 局部图(KubernetesLocalGraph,见 runner 中build_graph_from_definitions的调用),支持跨资源的图查询类检查;
  • check_definitions对每个文件中的每个实体调用注册表扫描,并通过get_skipped_checks消费注解形式的跳过项;
  • 扫描结果以Record形式写入Report,资源标识采用{Kind}.{namespace}.{name}格式,例如Deployment.default.checkov
  • 同时支持镜像引用检测(KubernetesImageReferencerManager),可以对资源中引用的容器镜像做额外检查。

文件类型支持方面,kubernetes_utils.py 定义了K8_POSSIBLE_ENDINGS = {".yaml", ".yml", ".json"},同时排除package.json/package-lock.json,避免把 Node 项目文件误当 Kubernetes 资源。

实战要点与常见问题

1. 查看扫描结果

kubectl get jobs -n checkov kubectl logs job/checkov -n checkov

kubectl get jobs用于确认 Job 是否进入Complete状态;kubectl logs job/checkov输出 Checkov 的完整报告(PASSED/FAILED/SKIPPED 列表与汇总统计)。Job 的restartPolicy: Never意味着一次运行结束即终止,日志会保留供复查。

2. 追加自定义参数

由于脚本会透传"$@",你可以直接在容器命令中追加参数,例如:

kubectl create job checkov-custom --from=cronjob/checkov -- \ --skip-check CKV_K8S_20 --compact

或在本地基于镜像手动执行:docker run --rm bridgecrew/checkov-k8s:latest --compact

3. 接入平台上报

将 API Key 以 Secret 形式挂载到/etc/checkov/apikey(可选/etc/checkov/repoid),脚本会自动切换到平台上报模式:

kubectl create secret generic checkov-api \ --namespace checkov \ --from-file=apikey=./apikey \ --from-file=repoid=./repoid

4. 理解资源标识与报告差异

运行时报告的resource字段是Deployment.default.nginx这类“集群坐标”而非文件路径,这是运行时模式与构建期模式最大的感官差异——同一份违规,构建期指向nginx.yaml第 N 行,运行时指向集群里具体的资源对象。

5. 权限边界确认

若你的集群启用了额外的 CRD 或需要扫描 Secret,默认的checkov-viewClusterRole 并不包含它们。此时需要在 kubernetes/checkov-job.yaml 的rules中按需补充apiGroups/resources/verbs。请务必权衡:加入secretslist/get权限意味着扫描器可以触达集群全部敏感凭据,需谨慎评估合规与安全风险。

总结

Checkov 的 Kubernetes 集成提供了一种“构建期扫描 + 运行时审计”的双轨合规方案:构建期守住 IaC 仓库的入口质量,运行时则通过 kubernetes/checkov-job.yaml 部署的只读 Job 持续校验集群的实际状态。整个方案建立在“Kubernetes 资源即代码”这一核心事实上——run_checkov.sh 负责把运行时资源还原成 Checkov 熟悉的 YAML 形态,checkov/kubernetes/runner.py 则复用与构建期完全一致的检测引擎,从而保证两套环境下策略语义一致、报告口径统一。对于需要在生产集群中建立持续合规基线、又不想引入集群内常驻 Agent 的团队而言,这是一个低侵入、可审计、随取随用的务实选择。

【免费下载链接】checkovPrevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.项目地址: https://gitcode.com/GitHub_Trending/ch/checkov

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 23:13:11

FunASR安卓端侧2pass离线语音识别部署指南

简介:FunASR安卓端侧离线版本2pass全模式是一套面向移动开发者与语音技术实践者的轻量级本地化语音识别解决方案,专为无网或弱网环境下的实时ASR需求设计,支持双遍处理(2pass)以兼顾响应速度与识别精度。资源包共2000个…

作者头像 李华
网站建设 2026/9/16 23:08:43

网盘直链下载助手使用指南:5 分钟本地解析八大网盘真实下载地址

网盘直链下载助手使用指南:5 分钟本地解析八大网盘真实下载地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云…

作者头像 李华
网站建设 2026/9/16 23:07:45

OpenMontage:专业天文图像拼接系统原理与实战指南

1. 项目概述:OpenMontage不是“视频剪辑软件”,而是专业级天文图像拼接系统OpenMontage这个名字,乍一听容易让人联想到“开源版的Adobe Premiere”或者“免费的Final Cut Pro”——毕竟“montage”在影视领域就是“蒙太奇”“剪辑”的意思。但…

作者头像 李华
网站建设 2026/9/16 23:07:12

Win10无外网热点搭建全指南:纯局域网通信与设备互联

前两天出差,房间里只有墙上甩出来的一根网线,路由器没带,手机和笔记本之间想传几个大文件,微信传输反复中断。这时候我突然想起来Win10笔记本其实可以自己开一个热点,让手机、平板、另外一台电脑直接连过来组个小局域网…

作者头像 李华
网站建设 2026/9/16 23:06:27

Android短信转发与消息网关搭建:监听、规则匹配到Webhook推送全解析

简介:这是一套面向Android开发者的短信转发工具完整项目源码,适合有Kotlin基础、希望搭建手机消息中转或远程控制服务的开发者。其功能覆盖短信、来电、App通知的监控与转发,支持钉钉、企业微信、飞书、邮箱、Bark、Webhook、Server酱、PushP…

作者头像 李华