深入理解开发流程:从简历上的“熟悉 CI/CD”到真正在产线上跑起来
大家好,我是 Claude Code 早期尝鲜用户,也是个重度命令行依赖症患者。说真的,我现在连新建文件夹都懒得点鼠标——mkdir -p ~/projects/new_feature && cd $_ 才是我的日常。在我们组干了快两年,日常工作就是一边用 ChatGPT/Claude 帮我生成测试脚本、解析日志,一边被产品经理疯狂 push “这个需求很简单,明天上线吧”。最近半年我对性能优化越来越上头,总觉得代码不仅要跑得对,还得跑得快、跑得稳。
今天这篇文章,其实是被“逼”出来的。上周五晚上十点半,我正准备关电脑去撸串(是的,程序员也有夜生活),突然收到 HR 的微信:“兄弟,你简历上写的‘熟悉 CI/CD 流程’,能具体讲讲吗?有个猎头在挖你。” 我当场愣住——简历上吹的牛,终究是要还的。
于是周末两天没出门,复盘了我们团队过去一年半的开发流程演进,从最初的手动部署、到 Jenkins 脚本满天飞,再到如今基于 GitLab CI + ArgoCD 的 GitOps 架构。这篇文章不讲大道理,只聊实战踩坑、技术选型、以及那些让我半夜惊醒的线上事故。如果你也正在写简历、准备跳槽,或者只是想搞清楚“开发流程”到底是个啥玩意儿,那这篇应该对你有点用。
一开始:手动部署,人肉运维,简历写“精通 DevOps”
刚入职那会儿(2023 年初),我们的开发流程堪称“原始社会”。每次发版,流程如下:
- 开发本地
git push - 找运维小哥要服务器权限
- 登录跳板机,
scp代码到生产服务器 - 手动执行
npm install、pm2 restart app - 祈祷别出错
有一次双11大促前夜,我改了个小功能,结果 package-lock.json 没提交,导致线上依赖版本不一致,服务直接 502。当时真的想砸电脑——不是因为 bug 多难修,而是因为整个过程完全不可追溯。更离谱的是,我简历上居然敢写“精通 DevOps”,现在想想脸都红了。
但那时候大家都这么干,产品说“敏捷开发”,其实意思是“快点给我上线”;测试说“自动化测试覆盖”,实际上就是点点页面看有没有报错。我们组甚至有个梗:“CI/CD = Copy & Deploy”。
第一次进化:Jenkins + Shell 脚本,简历升级为“熟悉持续集成”
被线上事故教育后,领导终于拍板:“搞 CI/CD!” 于是我们引入了 Jenkins。
说实话,初期体验并不美好。Jenkinsfile 写得像意大利面条,各种 sh 'bash deploy.sh' 嵌套,环境变量靠猜,日志输出全是乱码。最崩溃的是某次更新 Node.js 版本,Jenkins 节点没同步,构建成功但运行时报 Error: Cannot find module 'fs/promises' —— 因为用了旧版 Node 不支持的 API。
但好处也很明显:至少不用再手动 scp 了。而且 Jenkins 的 Blue Ocean 插件让 pipeline 可视化,新人也能看懂流程。
不过问题很快暴露:
- 配置分散:构建脚本、部署脚本、回滚逻辑散落在不同 repo
- 权限混乱:谁都能触发 prod pipeline
- 环境不一致:本地、测试、生产三套环境配置靠文档维护,三天就过期
这时候我的简历悄悄把“精通”改成了“熟悉”,心里却清楚:这玩意儿根本没到“理解”的程度。
关键转折:GitLab CI + Docker,开始真正“理解”流程
转机出现在去年 Q3。公司决定全面容器化,所有服务必须跑在 Docker 里。这逼着我们重新思考整个交付链路。
我们做了几件关键的事:
1. 统一构建环境
用 Dockerfile 定义构建上下文,确保本地 docker build 和 CI 构建行为一致。
# 示例:Node.js 应用 Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
注:
npm ci而不是npm install,确保依赖锁死;多阶段构建省空间。
2. GitLab CI 替代 Jenkins
为什么换?三点理由:
- 配置即代码:
.gitlab-ci.yml就在 repo 根目录,版本可控 - 内置 Runner:不用自己维护 Jenkins 节点
- 与 Git 深度集成:MR(Merge Request)自动触发 pipeline
一个典型的 .gitlab-ci.yml:
stages:
- test
- build
- deploy
test:
stage: test
image: node:18
script:
- npm ci
- npm test
build:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
only:
- main
deploy-staging:
stage: deploy
script:
- ./scripts/deploy.sh staging $CI_COMMIT_SHORT_SHA
environment:
name: staging
only:
- main
# prod 部署需手动审批
deploy-prod:
stage: deploy
script:
- ./scripts/deploy.sh production $CI_COMMIT_SHORT_SHA
environment:
name: production
when: manual
这套流程跑通后,最大的变化是:开发不再关心“怎么部署”,只关心“代码是否通过测试”。合并到 main 分支,自动构建镜像、部署到 staging;确认无误后,点一下“deploy to prod”,搞定。
这时候我才意识到:开发流程的本质,是降低认知负荷和操作风险。
技术选型对比:为什么我们最终选择了 GitLab CI + ArgoCD?
当然,中间我们也评估过其他方案。以下是几个主流选项的对比(结合我们业务场景):
| 方案 | 优点 | 缺点 | 是否适合我们 |
|---|---|---|---|
| Jenkins | 插件丰富,社区成熟 | 配置复杂,维护成本高 | ❌(已有 Jenkins 债务太多) |
| GitHub Actions | 免费,生态好 | 私有化部署弱,国内访问慢 | ❌(公司用 GitLab) |
| GitLab CI | 与代码仓库一体,配置简单 | 高级功能需付费 | ✅(已采购企业版) |
| CircleCI | 性能快,YAML 清晰 | 成本高,私有 runner 配置复杂 | ❌(预算有限) |
但光有 CI 不够。我们发现部署后,K8s 集群状态和 Git 仓库里的 manifest 文件经常不一致——有人手动 kubectl edit 了资源,导致“配置漂移”。
于是引入 ArgoCD,实现 GitOps:
- 所有 K8s manifest 存在独立 repo(如
infra-manifests) - ArgoCD 监听该 repo,自动同步集群状态
- 任何手动修改都会被自动覆盖(或报警)
这招叫“声明式基础设施”,听起来高大上,其实就是“以 Git 为准,不服 sync”。
现在我们的完整流程:
开发者提交 MR → GitLab CI 跑测试+构建镜像 → 合并到 main →
ArgoCD 检测到 manifest 更新(含新镜像 tag)→ 自动滚动更新 K8s Deployment
全程无需人工干预(prod 除外),且任何变更都有 Git 记录,回滚只需 git revert。
简历与求职:别再写“熟悉 CI/CD”了
回到开头那个 HR 的问题。现在如果再写简历,我会这么描述:
主导团队 DevOps 流程重构:从手动部署迁移至 GitLab CI + ArgoCD GitOps 架构,实现构建、测试、部署全自动化。关键成果:
- 发布频率从每周 1 次提升至每天 5+ 次
- 线上因部署导致的故障下降 90%
- 新人上手部署流程时间从 2 天缩短至 10 分钟
你看,用结果说话,而不是堆砌术语。
很多同学简历写“熟悉 CI/CD”、“了解 DevOps”,但面试一问细节就露馅。比如:
- “你们的 pipeline 有哪些 stage?”
- “如何保证 prod 部署安全?”
- “遇到构建缓存失效怎么处理?”
如果你没亲手调过 .gitlab-ci.yml 的 cache:key,没被 docker push 的权限问题折磨过,那这些答案都是空中楼阁。
所以建议:在自己的 GitHub 上搭一套 mini CI/CD 流程。哪怕只是用 GitHub Actions 跑个单元测试 + 自动部署到 Vercel,也比空写“熟悉”强一百倍。
踩过的坑 & 最佳实践
最后分享几个血泪教训:
1. 别把 secrets 写进 CI 配置
曾经有人把 AWS_ACCESS_KEY 直接写在 .gitlab-ci.yml 里,还好被 GitGuardian 扫出来拦住了。正确做法:用 GitLab 的 CI/CD Variables 或 HashiCorp Vault。
2. 测试必须快
我们早期跑 E2E 测试要 15 分钟,开发者等得睡着。后来拆成:
- Unit test(<1min)
- Integration test(3min)
- Nightly E2E(非阻塞)
快速反馈是 CI 的生命线。
3. Prod 部署必须手动审批 + 自动回滚
再信任自动化,也要留一手。我们在 ArgoCD 中配置了健康检查,若新版本 5 分钟内错误率 >1%,自动回滚到上一版本。
4. 日志 & 监控必须跟上
CI/CD 不是终点,可观测性才是。我们用 Loki + Grafana 看 pipeline 日志,Prometheus 监控部署后服务指标。
结语:开发流程不是工具链,而是协作方式
折腾这一圈下来,我最大的感悟是:开发流程的核心不是用了多少 fancy 工具,而是如何降低团队协作的认知成本和操作风险。
当你能在周五晚上安心关电脑去撸串,而不是担心“我刚 deploy 的代码会不会炸”,你就知道这套流程值了。
至于求职?别再盲目堆关键词了。真正打动面试官的,是你如何用技术解决实际问题的故事。比如:“我们曾因手动部署导致双11故障,后来通过 GitOps 实现零人为干预发布”——这种故事,比“精通 Kubernetes”有力得多。
好了,文章写完,我去更新简历了。这次,每个字都经得起拷问。
(P.S. 如果你也在搞 CI/CD,欢迎交流!但别问我 Jenkins 怎么配——我已经把它删干净了 😅)

评论 0