镜像来源约束是集群准入控制里最底层的一道闸门,它校验的不是“这个镜像能不能跑”,而是“这个镜像是谁、从哪来、有没有被篡改过”,生产环境里,只配一个可信仓库列表远远不够,需要仓库域名白名单、镜像签名校验、资源层面策略拦截三者配合,缺一个都可能被绕过。
镜像来源约束和准入控制到底有什么区别
这个疑问在很多运维群里被反复提起,打眼一看,准入控制(Admission Control)管的是“谁有资格让这个Pod进入集群”,来源约束管的是“镜像从哪里拉取”,像是两码事,但实际上,镜像来源校验是准入门控职责的一部分,只是在Kubernetes里它藏得比较深,不是默认开关。
准入控制的真实作用边界
Kubernetes的准入控制分两阶段:MutatingAdmissionWebhook先改请求(比如注入sidecar、加默认标签),ValidatingAdmissionWebhook再拦请求(比如限制资源配额、校验镜像策略),整个链路发生在API Server收到请求之后、etcd持久化之前。
镜像来源约束主要落在Validating阶段,业界常用的实现路径有三条:
- ImagePolicyWebhook:Kubernetes官方提供的准入门控插件,把镜像地址、拉取凭据信息发给外部策略服务,由外部服务决定放不放行。
- OPA Gatekeeper:用Rego策略语言写规则,拦截不符合策略的Pod创建请求。
- Kyverno:设计上更贴合K8s运维习惯,用YAML写策略,不用学一门新的策略语言。
仓库列表校验只是最外圈
很多人误以为加了一个“受信任镜像仓库列表”就等于做了来源约束,这个理解在2026年显然不够用,原因在于仓库域名校验只能保证镜像“出生地”,管不了镜像“内容”。
| 校验方式 | 能拦住什么 | 容易漏什么 |
|---|---|---|
| 仓库域名白名单 | 从非授权仓库拉取镜像 | 恶意镜像混进合法仓库 |
| 固定digest校验 | 镜像标签被漂移覆盖 | 本身被篡改 |
| 镜像签名验证 | 镜像被篡改或替换 | 私钥泄露后的伪造签名 |
| 策略引擎条件拦截 | 从不在允许列表的路径拉取 | 运行时动态加载的恶意容器 |
行业共识认为,来源约束必须从“仓库完全可信”假设转向“内容可验证”假设,一个来自私有仓库的镜像,不等于一个安全的镜像。
私有镜像仓库地址写死还会绕过白名单吗
这是实践中非常典型的一个疑问:镜像地址写死了固定全路径,并且只在Admission里做了字符串匹配,看上去万无一失,可真出问题时,往往不是白名单失效,而是“写死”这个词本身的理解有偏差。
绕过白名单的几种实操路径
- Tag漂移覆盖:镜像地址写死成
registry.internal/app:v1.2.3,但tag是可变的,运维重新推送同名tag,节点上如果配置了AlwaysPull,新镜像会被拉下来,旧镜像的验证就失效了。 - 上游镜像同步:攻击者先把恶意镜像推到一个被允许的公网仓库(比如某大厂的公开镜像仓库),然后利用集群拉取凭据的授权范围过大,直接把镜像拖进集群,域名白名单管不住这一层。
- 镜像仓库自身被攻破:私有仓库管理员账号被拿,或者仓库软件存在漏洞被写入恶意镜像,这种情况下,来源校验依然会放行。
固定digest是目前最容易被忽略的一步,把镜像地址写成registry.internal/app@sha256:xxxx,从技术上说才是真正写死,tag可以改,digest由镜像内容哈希决定,内容有一字节变化,digest就变了。
用Kyverno做一层完整的来源约束
以Kyverno为例,一个同时校验仓库前缀和digest存在性的策略,写起来不难:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-image-source
spec:
validationFailureAction: Enforce
rules:
- name: check-image-registry
match:
any:
- resources:
kinds:
- Pod
validate:
message: "镜像必须来自内部仓库且锁定digest"
pattern:
spec:
containers:
- image: "registry.internal/@sha256:"
operation小细节要留意:这个策略只对新建Pod生效,对已经存在的Pod不会做强制回收,需要配合pre-existing配置和巡检任务才能做到存量收敛。在Dev环境可以先用validationFailureAction: Audit观察有多少工作负载会触发红线,再切Enforce。
来源约束和准入控制的分工误区
很多团队把来源约束的期望放得太高,指望它把运行时的风险也一并解决,准入门控只在创建/更新时执行一次,运行时的镜像加载(比如通过ctr命令手动拉取镜像并启动容器)它管不到,runtime层面的约束要交给node侧的容器运行时配置和进程级安全策略来做。
镜像签名校验打断CICD流水线怎么办
这是部署环节最常见的矛盾:安全团队要求所有镜像必须做签名验证,否则不让进集群;开发团队嫌签名环节影响发布速度,CI一次构建往往就要多花几十秒。
镜像签名校验打断CICD流水线怎么办,本质上是信任模型和交付效率的取舍问题。
签名不是额外负担,是供应链链路的一部分
业内专家指出,镜像签名验证在生产环境的价值在于:它能把“镜像内容是否被篡改”这个信任判断从运行时提前到构建时,GitHub Actions和GitLab CI都已经内置了Cosign支持,执行一条cosign sign的时间在正常网络条件下不过几秒。
实操落地步骤
- 在CI构建完成后,立刻用Cosign私钥对镜像签名,并把签名产物推到仓库的
cosign目录下。 - 在集群侧部署验证服务(Kyverno的
verifyImages规则或Cosign的校验控制器)。 - 先切Audit模式跑一个发布周期,记录所有未签名镜像的列表,和开发团队逐条确认归属。
- 确认无遗漏后切Enforce模式,并在发布流程里增加“未签名禁止发布”的前置检查。
与仓库校验组合的最优策略
| 场景 | 推荐组合 | 原因 |
|---|---|---|
| 核心业务集群 | 仓库白名单 + 签名强制 + digest锁定 | 即使仓库被攻破,内容仍受签名保护 |
| 开发测试集群 | 仓库白名单 + Audit模式签名告警 | 保速度,同时积累可见性 |
| 边缘节点集群 | 签名强制为主,仓库白名单为辅 | 边缘节点网络不稳定,重试拉取,策略不应过度复杂 |
简米云集群不出网怎么配镜像白名单
国内使用简米云ACK的场景里,集群不出网是常见的安全基线要求。简米云集群不出网怎么配镜像白名单这个问题出现的频率很高,核心难点在于ACR(简米云容器镜像服务)比较多套环境混用,白名单粒度怎么控制,才能既不影响业务发布,又真正挡住来自公网的拉取行为。
明确一个前置条件:守好节点侧
Kubernetes的准入控制拦的是API Server,拦不住节点上的容器运行时直接拉镜像,真正不让集群从公网拉镜像,需要从三个位置同步下手:
- ACK集群的kube-apiserver开启ImagePolicyWebhook,在apiserver配置里挂一个策略服务。
- 节点侧的containerd配置只能访问ACR内网地址,通过
config.toml里配置镜像仓库地址的替换和认证信息。 - 安全组/网络ACL层面阻断出网流量,防止运行时异常拉取路径。
在ACK上配置的完整路径
先做的事:把ACR的域名加入专有网络路由,ACK集群内部访问ACR走内网域名,比如
registry.cn-hangzhou.aliyuncs.com对应的VPC内网地址是registry-vpc.cn-hangzhou.aliyuncs.com,需要在ACR控制台开启“专有网络访问”,并把对应网段加入白名单。
接着配置容器镜像仓库的PullSecret,应用在创建时指定imagePullSecrets,确保节点拉取镜像时使用的是具有该仓库拉取权限的凭据。
更关键的一步是apiserver层面的准入门控,ACK集群默认不开启ImagePolicyWebhook,需要自行部署策略服务,或者在ACK的可视化配置里启用OPA策略。
一个容易被忽略的坑:镜像加速器
很多简米云节点默认配置了公网镜像加速器,它会把Docker Hub的镜像缓存到国内节点,如果业务工作负载不小心引用了Docker Hub镜像地址,通过加速器是可以正常拉取的这直接绕过了你的“内网仓库白名单”意图。在容器运行时的配置文件里,需要显式移除公共镜像加速器地址,或限制镜像源只允许ACR域名。
镜像来源约束从来不是一道单一的闸门,而是从仓库可信到内容可信、从创建准入到运行限制的完整链路。把来源约束做好,相当于给集群装了一道“不认识的地方东西一口不吃”的保险丝,而保险丝烧断的成本,永远比被恶意镜像入侵后的排查成本低得多。
Q&A:集群准入镜像来源约束常见疑问
集群准入环节能完全禁止从公网拉取镜像吗?
不能只靠准入控制,Admission只拦截Pod创建时的API请求,节点上的容器运行时可以直接拉镜像,要实现完全禁止公网拉取,还需要在节点侧配置容器运行时的镜像仓库白名单,以及安全组级别的出网限制,三者配合才能形成闭环。
镜像来源约束除了仓库域名白名单还有哪些常用手段?
固定镜像digest、强制镜像签名验证、策略引擎按标签/命名空间/所属应用做条件放行、运行时层面的镜像执行白名单,在多数生产环境中,固定digest和签名验证是最有效的两个组合。
集群里有大量已存在的未校验镜像,审计和清理优先级怎么排?
先列出当前集群中所有工作负载使用的镜像地址,按其来源分类统计(内部仓库、公网仓库、未知来源)。清理顺序按风险排序:高权限工作负载使用的公网镜像优先替换,其次是未知来源镜像,最后是内部仓库里的未签名镜像,替换完成后把准入策略从Audit切到Enforce,阻断新建工作负载继续使用非白名单镜像,收敛过程的最终标准是:所有运行工作负载的镜像来源都可追溯,且新建工作负载无法绕过约束策略。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/641078.html





