在 Kubernetes 环境中使用 Signoz 做分布式追踪和指标监控时,常常需要验证采集器对特定业务镜像的识别能力。然而真实镜像往往因为安全策略无法从外部 registry 拉取,或者构建流水线尚未产出可用版本。利用 Node.js 编写一套 Mock2Image 工具,可以在不依赖真实容器镜像的前提下,向集群注入伪装的镜像元数据,让 Signoz 的 agent 正常捕获对应的服务实例信息,从而完成管道连通性测试。

Mock2Image 的核心原理与 K8s 对象映射
Mock2Image 的本质并不是生成一个真正的容器镜像文件,而是通过 Kubernetes 的声明式 API 伪造出“某个 Pod 正在运行某个镜像”的集群状态。Signoz 的 k8s-infra 采集器主要依赖 kubelet 的元数据接口与集群的 Pod 列表来发现服务,因此只要我们在指定命名空间下创建一个带特定 label 和 annotation 的 Pod,并把容器字段写成目标镜像名,采集器就会将其纳入监控对象。
具体映射关系上,Node.js 脚本需要使用 @kubernetes/client-node 库实例化 KubeConfig,然后构造 V1Pod 对象。其中的 spec.containers[0].image 字段可以直接填写想要 mock 的镜像全名,例如 my-registry/app:mock。为了让 Signoz 区分这些 mock 实例,我们通常还会打上 signoz.io/mock=true 这样的自定义标签,后续在 Signoz 的 dashboard 中用过滤器排除或高亮。
除了 Pod 本身,我们还需要用 ConfigMap 承载一些假的启动参数或环境变量,使得 Signoz 在抓取日志时不会因缺少字段而报错。这种对象映射方式比修改节点上的 containerd 存储层要安全得多,因为它完全在控制面生效,随时可以通过删除 Pod 来清理现场,不会影响真实工作负载。
基于 Node.js 的客户端实现步骤
在代码层面,第一步是加载集群配置。如果脚本运行在集群内的 Job 中,可以直接读取 /var/run/secrets/kubernetes.io/serviceaccount 下的 token;如果在外部运行,则使用本地的 kubeconfig 文件。下面示例展示如何用 Node.js 创建一个 mock Pod 并关联 ConfigMap。
const k8s = require('@kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
async function createMockPod(namespace, mockImage, podName) {
const cmName = podName + '-cfg';
const cm = {
metadata: { name: cmName },
data: {
'APP_ENV': 'mock',
'MOCK_TRACE': 'true'
}
};
await k8sApi.createNamespacedConfigMap(namespace, cm);
const pod = {
metadata: {
name: podName,
labels: { 'signoz.io/mock': 'true' }
},
spec: {
containers: [{
name: 'mock-container',
image: mockImage,
envFrom: [{ configMapRef: { name: cmName } }],
command: ['sleep', 'infinity']
}]
}
};
const res = await k8sApi.createNamespacedPod(namespace, pod);
return res.body;
}
createMockPod('signoz-test', 'my-registry/app:mock', 'mock-pod-01')
.then(() => console.log('mock pod created'))
.catch(err => console.error(err));
上述代码首先建立了 ConfigMap,再创建 Pod,并将 ConfigMap 通过 envFrom 挂载进容器。由于命令是 sleep infinity,该 Pod 不会真正执行业务逻辑,仅维持运行状态。Signoz 的 k8s-infra 会周期性 list Pod,一旦发现 label 匹配且镜像字段为目标值,就会生成对应的 receiver 配置。
在实际项目中,我们往往要批量 mock 多个服务,因此可以封装一个循环,结合并发限制避免触发 K8s API 限流。同时建议给 mock Pod 加上 ownerReferences,指向一个由脚本创建的 Job,这样 Job 删除时 mock 资源能自动级联清理,降低运维负担。
在 Signoz 管道中的验证与权限边界分析
当 mock Pod 就绪后,打开 Signoz 的 Services 页面,应该能看到对应镜像名对应的服务条目,并且能模拟产生 trace 数据(如果配合一个独立的小流量 generator)。此时可检查 OpenTelemetry collector 的日志,确认没有因镜像拉取失败而报 ImagePullBackOff 相关错误,因为我们的 Pod 实际并未触发真实拉取。
权限方面,运行 Node.js 脚本的 ServiceAccount 必须拥有对应命名空间的 Pod 与 ConfigMap 的 create、delete 权限。若集群启用了 Kyverno 或 OPA 等策略引擎,需要放行 signoz.io/mock 标签的 Pod 创建请求,否则会被拦截。多租户场景下,应将 mock 操作限制在独立的测试命名空间,避免污染其他团队的监控视图。
从稳定性角度看,Mock2Image 方案在离线环境优势明显:不需要配置任何 registry 镜像仓库,也不依赖节点上的容器运行时缓存。但它的局限在于无法验证真实镜像的启动行为或资源占用,仅适合做 Signoz 采集链路和功能开关的预检。如果后续要对接 CI,可以把 Node.js 脚本打包成最小镜像,在流水线中作为临时 Job 运行,实现一键注入与回收。
Node.jsSignozk8s_Mock2Image修改时间:2026-08-16 08:28:30