Skip to content

接手一套陌生 CI/CD 平台:四步取证梳理全景拓扑(脱敏实录)

接手别人维护多年、文档不全、网络上还够不着的 CI/CD 平台,最忌上来就改。 这篇记录一次完整的接管梳理实录:平台横跨内外两个网络分区、四台 Jenkins 实例、425 个任务、20 条产品线(数据库安全/数据网关/安全审计/终端安全/备份等方向)。全部操作只读,没有改过任何配置——梳理清楚之前,不动生产是底线。敏感信息已全部脱敏:主机以 <占位符> 表示,仓库名、产品线、人名、凭据一概不出现。

一、起点:两份交接文档能给你什么

Section titled “一、起点:两份交接文档能给你什么”

交接材料只有两份:一份配置手册(含大量截图)、一份设备台账(Excel)。细读后能拿到三类关键情报:

情报类型 能拿到什么 局限
系统地址 各平台入口 URL、FTP 制品库 手册可能过时(后面实测证实了)
责任边界 每个阶段谁是主责谁是协助 只到角色级,不到系统级
操作方法 手动触发任务、查日志的入口 不涉及架构与数据流

设备台账的价值常被低估:编译机、KVM 宿主机、测试执行机的 IP/规格/用途表格,后面和 Jenkins 节点名逐一对照上了——这是“三方交叉验证”的一环。

但两份文档都没有回答最关键的问题:调度在哪、怎么串起来的、断了影响什么。这些只能靠自己取证。

第一步:API 匿名探测——往往比想象中开放

Section titled “第一步:API 匿名探测——往往比想象中开放”

拿到 Jenkins 地址列表后,先别急着要账号。Jenkins 的 /api/json 在不少企业实例上对匿名是可读的(管理员常放开只读)。实测结果:

  • 两台在网 Jenkins 的任务树、节点列表、视图分组全部可匿名枚举:上游编译实例 197 个任务(194 个 Pipeline + 50 节点)、下游测试实例 228 个任务(213 个自由风格 + 36 节点)
  • whoAmI 接口确认匿名身份;config.xml 这类深度配置返回 403——权限边界清晰

这一步拿到了“任务清单级”的画像:上游管编译打包(夜间定时阵型触发),下游管部署测试(纯调度触发、几乎无定时)——两台 Jenkins 是按流水线阶段分工的,不是测试/生产分离。这个认知直接纠正了文档阅读阶段的一个错误猜测。

第二步:宿主机只读勘察—— 设备台账的密码就是钥匙

Section titled “第二步:宿主机只读勘察—— 设备台账的密码就是钥匙”

设备台账里记录了各主机的系统账号。用 SSH 登录后(严格 只读),一次勘察能拿到的比 API 多得多:

  • JENKINS_HOME 里 jobs/、nodes/、plugins/、users/ 的真实规模
  • grep 所有任务 config.xml,统计出定时触发阵型、Git 仓库引用分布、凭据 ID 引用频次——全部指向现役 GitLab,而手册写的旧地址只剩 6 处遗留引用(该机实测已不可达,实锤“手册过时”)
  • 节点名与设备台账的 IP 一一对应(euler_build_<IP后缀> 这类命名习惯帮了大忙)

第三步:顺着日志抓“看不见的主机”

Section titled “第三步:顺着日志抓“看不见的主机””

手册里提到一个“调度程序”,但没说它跑在哪。两台 Jenkins 宿主机上都没有可疑进程——突破口在构建日志:运维任务的 console output 里明明白白记录着它向 http://<调度主机>:443/<路径>/ci_push 推消息。回宿主机一查 ss -tlnp:一个 Python 进程监听 443,工作目录就是某个内部仓库的部署目录。调度程序实体、源码仓、部署方式三点连成线。

第四步:源码对照——README 就是现成的架构文档

Section titled “第四步:源码对照——README 就是现成的架构文档”

申请到代码仓只读权限后 clone 调度平台仓库,发现它的 README 写得极好:16 个 HTTP 接口、状态机设计(等待池 4 小时超时、同产品新包替换排队)、十步测试主流程、配置热加载机制一应俱全。手册里的每一条“玄学行为”都在代码里找到了出处。

再拿源码里的常量回查配置(内网桥接主机地址、双 FTP 端点),连设备台账上都没有的内网 FTP 主机都挖出来了。

设备台账 IP ↔ Jenkins 节点名 ↔ 手册行为描述,三方吻合;构建日志、源码常量、配置文件互相印证。单一来源都可能有假,三方一致才敢当结论。

━━━━━━━━━━ 外网区(办公测试侧)━━━━━━━━━━
代码层 编译层 调度层 环境层
┌──────────┐ ┌─────────────┐ ┌──────────────┐ ┌────────────────┐
│GitLab │ │Jenkins-A │ │ 调度程序 │ │ KVM 宿主机×3 │
│<外网GitLab>│─>│:8080 编译侧 │ │ server.py:443│ │ (qcow2模板复制) │
│ 平台仓+ │ │194 pipeline │<───│ 状态机: │─>│ 动态VM按需创建 │
│ 用例仓群 │ │50 编译节点 │push│ ·等待池4h超时 │ │ IP/VNC 预分配 │
└──────────┘ └──────┬──────┘ │ ·同产品替换排队│ └───────┬────────┘
│产物 └──────┬───────┘ │
▼ │驱动 ▼
┌─────────────┐ ┌──────┴───────┐ ┌────────────────┐
│FTP 制品中枢 │<───│ 授权/扫描调度 │ │Jenkins-B │
│<FTP制品库> │ └──────────────┘ │:8080 测试侧 │
│ 包/报告/授权 │ │213 freestyle │
└──────┬──────┘ │CI/Deploy 成对 │
▼ └───────┬────────┘
┌─────────────┐ │
│ 报告归档目录 │<──── 测试执行机×9 ────────────┘
└──────┬──────┘
▼
展示/通知层: 看板(每日拉FTP→HTML汇总→邮件) + 钉钉机器人(实时群通知)
━━━━━━━━━━ 内网区(生产研发侧)━━━━━━━━━━
内网GitLab → 内网Jenkins+桥接代理(<内网桥接主机>) → 内网编译机×21 → 内网FTP
│ client:443 与外网调度程序互通

结构性认知两条(排查故障时决定先看哪边):

  1. 编译侧靠定时、测试侧靠调度。夜间编译阵型(0 点/1 点/2 点分组触发)出问题看 Jenkins-A 的定时任务;白天包“卡住不动”看调度程序状态机和等待池。
  2. FTP 制品库是全局咽喉:编译产物出、五类扫描报告归档、看板数据进、授权文件走,全经它。单点、无冗余。
时刻 动作 要点
T0 夜间定时触发编译任务 定时阵型错峰,避免节点 IO 争抢
T1 编译节点拉流水线脚本+代码 脚本统一归档 GitLab,模板+产品目录
T2 代码扫描随流水线执行 SonarQube(Java/JS)+ TscanCode(C/C++)
T3 产品包外传 FTP 包信息文件随传,是看板判“成败”的依据
T4 编译机代理转发 ci_push 给调度程序 内外网桥接的关键链路
T5 状态机入队 同产品新包替换排队;等待池 4h 超时丢弃
T6 包外传校验 → ISO/BIN 打包 → checksec 检查 校验不过直接终止流程
T7 动态环境:KVM 池复制模板建 VM 配 IP/网关/盘/网卡,产品特例表驱动
T8 取机器码→授权文件→FTP(现多改接口授权) HA 主备环境有特例
T9 调度部署任务 部署只到服务启动,不做任何测试
T10 部署稳定后触发测试任务 pytest → xml 报告 + Allure → FTP
T11 五类安全扫描(0~9 点窗口) 不论测试成败都执行;绿盟有 IP 配额
T12 环境清理(关闭/挂起动态 VM) 可用运维任务恢复做问题分析
T13 钉钉实时通知 + 次日看板汇总邮件 xml 报告数据为准,Allure 仅展示

五、梳理中挖出的典型隐患(每个平台都值得自查)

Section titled “五、梳理中挖出的典型隐患(每个平台都值得自查)”
  1. 手册指向的“主入口”已下线,但脚本里还留着 6 处旧地址引用——文档过时不可怕,可怕的是没人知道它过时了
  2. 调度程序以手工 SSH 会话进程运行(非 systemd/容器)——那个终端一断,全平台部署测试停摆
  3. 生产 Jenkins 容器用“backup”命名的镜像在跑——镜像管理规范缺失
  4. 两个任务的构建历史占掉实例磁盘 63%(112GB)——构建保留策略形同虚设
  5. 一个 JDK 压缩包被误建成 Jenkins 任务目录——目录被当网盘用
  6. 匿名 API 可枚举全部任务与节点——便利与暴露面是一体两面
  7. 几十处任务共享同一个节点 SSH 凭据——单一凭据暴露面过大
  1. 先文档后系统:手册/台账细读一遍,列出“系统地址表 + 责任边界表 + 疑点清单”
  2. API 探测先行:/api/json、/whoAmI、/computer/api/json 匿名试一轮,能拿多少拿多少
  3. 台账 ↔ 节点名交叉对照:命名习惯(IP 后缀、用途前缀)是天然的映射线索
  4. 宿主机只读勘察:进程/端口/挂载/JENKINS_HOME 四板斧;ss -tlnp 找隐藏服务
  5. 构建日志当侦探小说读:console output 里有所有下游地址
  6. 源码对照收口:调度/编排类系统通常有配套仓库,README 常常就是没人维护的架构文档
  7. 全程只读,三方验证才下结论;产出一张“拓扑 + 生命周期 + 断链影响矩阵”作为接管总纲

接管不是推倒重来,是先画出它的心脏和血管。这张图画清楚之前,任何优化都是赌博。