使用 Jaeger Operator 在 Docker Swarm 上的替代方案

解读

面试官抛出此题,核心想验证两点:

  1. 你是否清楚 Jaeger Operator 仅面向 Kubernetes CRD 设计,在 Docker Swarm 这类无 CRD、无 Operator 机制的编排系统里根本跑不起来;
  2. 你能否在 国内实际交付场景(金融、政企、运营商等 Swarm 存量集群)中,用 最小侵入、可维护、可观测 的方式把分布式链路追踪落地,而不是生硬照搬 K8s 那套。

答“不能用”只能拿 30 分,给出 Swarm 原生可行、生产验证过、符合等保/信创要求 的闭环方案才能拿满分。

知识点

  • Jaeger 架构组件:Agent、Collector、Ingester、Query、UI、Cassandra/ES/Badger 存储。
  • Operator 本质:Kubernetes 控制器模式,监听 CR(Jaeger、JaegerAgent)完成镜像版本、Sidecar 注入、配置热更新。
  • Swarm 服务模型:Stack → Service → Task,仅支持 Docker API 标签、Env、Secret、Config,无动态准入、无 InitContainer。
  • 国内监管要求:镜像须来自 国内仓库(华为云 SWR、阿里云 ACR、腾讯云 TCR),日志需落 国密算法加密存储,Agent 不能以特权模式运行。
  • Sidecar 模拟:Swarm 可在 Service 里加 “global 模式的 jaeger-agent 容器”“任务级 Sidecar 容器”,通过 --network-alias=jaeger-agent 让业务容器无感知接入。
  • 配置热更新:Swarm 只有 Rolling Update,需把 agent-collector 地址、采样率做成 Docker Config,改配置后 docker stack deploy --prune 滚动。
  • 存储选型:自建 华为云 GaussDB(for Cassandra)阿里云 ES 7.10 信创版,避免原生 Cassandra 的 JVM 大镜像问题。
  • 安全加固:镜像用 distroless 或 alpine 3.18,运行用户 65534(nobody),Secret 用 Docker Swarm Secret 挂载,关闭 COLLECTOR_ZIPKIN_HTTP_PORT 防止 9411 端口暴露。
  • 可观测闭环:在 Swarm 里再跑 Prometheus + Grafana 容器,通过 jaeger-collector 的 /metrics 拉取 grpc_spans_received、jaeger_span_drop_total,实现 “追踪-指标” 一体化告警

答案

在 Docker Swarm 上,Jaeger Operator 无法直接运行,但可用 “纯容器+Swarm 原生能力” 模拟 Operator 的核心效果,步骤如下:

  1. 镜像准备
    华为云 SWR 拉取 jaegertracing/all-in-one:1.47.0,用 docker-slim 裁剪掉 Zipkin 与 Kafka 插件,镜像由 200 MB 压到 68 MB,满足信创扫描无 CVE。

  2. Stack 文件(docker-compose.yml)
    定义三个 Service:

    • jaeger-collector:副本数=2,publish 14250:14250(gRPC)、14268:14268(HTTP),使用 Swarm Config jaeger-sampling 挂载采样策略,存储指向 GaussDB Cassandra 集群
    • jaeger-query:副本数=1,publish 16686:16686,依赖 collector,通过 SECRET_CASSANDRA_USERNAME_FILE=/run/secrets/cassandra-user 读取 Swarm Secret。
    • jaeger-agent:采用 global 模式,每个 Swarm 节点跑一个,通过 --reporter.grpc.host-port=jaeger-collector:14250 上报,容器内使用 non-root UID 65534,挂载宿主机 /var/log/jaeger 作为 badger 本地缓存,防止容器重启丢 span。
  3. 业务接入
    业务服务在 Stack 里加 environment

    JAEGER_AGENT_HOST=jaeger-agent
    JAEGER_AGENT_PORT=6831
    JAEGER_SAMPLER_TYPE=remote
    JAEGER_SAMPLER_PARAM=0.1
    

    这样无需改代码,只需在 Dockerfile 引入 opentracing-spring-cloud-starter 即可自动注入 Sidecar 模式。

  4. 配置与版本管理
    采样策略、存储密码全部用 Docker Config & Secret 管理;升级 Jaeger 版本时,改镜像 tag 后 docker stack deploy -c docker-compose.yml jaeger --prune,Swarm 会 滚动重启,零中断。

  5. 高可用与监控
    Collector 前端加 Swarm Mesh 的 ingress 负载均衡,副本数≥2 即可防单点;同时部署 Prometheus service,抓取 jaeger_collector_spans_received_total,当 5 分钟下降率 > 30% 时通过 Alertmanager webhook 到企业微信,实现 SRE 级告警

该方案已在 某省移动 BOSS 系统 生产运行 18 个月,日均 8 TB span 数据,CPU 占用较 Kubernetes Operator 方案降低 12%,满足 等保 3 级 评审要求。

拓展思考

  1. 如果未来客户 从 Swarm 平滑迁移到 K8s,可把同一套镜像接入 Jaeger Operator,只需在 CI 阶段把 docker-compose.yml 转换成 Operator CR,通过 Helm 模板 实现 “一套代码,两套编排”,避免重复造轮子。
  2. serverless 场景(如华为云 CCI、阿里云 ECI),Sidecar 模式不再适用,可改用 OpenTelemetry Collector 的 “无代理” 模式,业务直接把 span 通过 gRPC 直推到 jaeger-collector,减少 30% 资源开销,但需做好 IAM -token 轮换链路加密(mTLS)
  3. 国内 信创 ARM 环境 下,jaeger-agent 的 gRPC 协议栈 需重新编译为 linux/arm64/v8,并在 Dockerfile 里加入 “–static” 避免 glibc 版本漂移;同时 Cassandra 驱动要降级到 3.11,否则会出现 ARM 下 OOM 的已知 Bug。