把工具换到文化时踩过的坑
那阵子我见过的项目, README 第一行基本都是 “开箱即用,一条命令启动”,然后第二条就是 “需要先安装 Docker、Docker Compose、Redis、MySQL、RabbitMQ,还要注意端口冲突”。
后来 Kubernetes 火起来,HPA 配置写错一次,生产自动扩容把账单干爆,老板脸色比运维代码里的 console.log 还难看。DevOps 圈子里有个常见现象:我们总是先搞定工具,再想文化——工具看得见摸得着,文化太虚。
这篇不写「DevOps 实施标准手册」,只聊我们团队转型里踩过的坑,以及那些比工具难啃得多的东西。
工具不是文化,但工具能暴露问题
我们团队刚开始搞 DevOps 的时候,思路挺简单:先搞套 CI/CD,能自动构建部署,就算 DevOps 落地了。
当时选的方案是 GitLab CI,原因无他:公司已经在用 GitLab 代码托管,不用再折腾权限。写了几个 .gitlab-ci.yml 配置文件,跑了几次 pipeline,算是完成了"从 0 到 1"。
stages:
- build
- test
- deploy
build:
stage: build
script:
- npm install
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- npm run test
dependencies:
- build
deploy:
stage: deploy
script:
- scp -r dist/ user@server:/var/www/html/
only:
- main
这套配置看着挺标准,但跑了几周就发现问题了。
pipeline 失败率偏高:本地 node 版本和 CI 不一致、依赖安装超时、部署脚本里硬编码的密码失效——每次失败都得有人盯着修,然后重新跑。
然后是"谁负责"的问题。代码提交后 pipeline 红了,前端说后端接口改了没打招呼,后端说前端依赖升级导致测试失败,运维说脚本没问题是环境问题。甩锅链路比代码调用链还长。
这时候我们才意识到一个挺残酷的现实:工具自动化了流程,但没解决协作的问题。相反,正因为自动化了,原来手动操作时还能私下商量的事,现在全变成了 pipeline 里的报错,谁的责任一目了然,矛盾反而更暴露了。
这里有个挺有意思的矛盾:你越自动化,原来靠人情和口头沟通能模糊过去的问题,越变成必须要解决的硬约束。这就像家里没人的时候,垃圾多堆几天也行;但住了一对爱干净的室友,每天都要倒垃圾,谁的垃圾没倒就很清楚。
第一个坑:我们以为只要工具对,流程就会顺
我们团队有个很典型的坑:把 DevOps 当成了工具选型,而不是协作模式。
当时花了两个月搞了一套"完整方案":代码管理用 GitLab,CI 用 GitLab CI,CD 用 Ansible,监控用 Prometheus + Grafana,日志用 ELK。技术栈挺标准,POC 环境也跑通了,但真的推广到业务团队时,卡住了。
卡在什么地方?很多问题想起来挺荒谬:
- 开发人员不愿意写单元测试,说"项目太急,没时间",结果 CI pipeline 里的测试环节形同虚设
- 测试人员觉得自动化测试不够可靠,还是要手动回归,浪费了做测试自动化的时间
- 产品经理想快速迭代,但开发说"现在发版要走 CI/CD,要等 pipeline",就把锅甩给工具
- 运维嫌 Ansible 的 playbook 太复杂,有时候还是手动 SSH 上去改配置
最后结果是:工具都上了,但真正使用的是其中 30%。剩下的 70% 还是靠手动、靠口头、靠人情、靠"这次特殊情况先这样"。
后来复盘时我们才明白,问题不在工具本身,而在于我们根本没有解决"为什么要自动化"这个问题。自动化是为了什么?是为了更快的交付?还是为了更少的错误?还是为了降低依赖某个人的风险?
不同的目标,对应不同的自动化策略。如果你是为了更快交付,那应该优先做那些重复性高、标准化程度高的工作;如果你是为了减少错误,那应该优先做质量门禁和环境一致性。
但我们的问题在于:我们搞自动化,是因为"别的团队都在搞"和"DevOps 就是要自动化"。这就像健身,你买了健身卡、买了装备、找了私教,但你不知道为什么要健身,是为了健康还是为了好看,还是为了发朋友圈。结果就是,健身去了几次,然后不了了之。
文化不是宣讲出来的,是实践出来的
我们团队后来意识到,文化这东西,靠宣讲、靠培训、靠墙上的标语,基本没用。文化是实践出来的,是日常工作中一次又一次的小选择累积起来的。
有一次,我们团队遇到了一个生产环境事故。某个后端服务突然内存泄漏,导致整个服务不可用。
按照以前的流程,这个事情会这样处理:运维发现服务挂了,重启服务;开发接到通知,查日志,定位问题;测试人员检查回归;最后写个事故报告,开个复盘会。
但在我们的 DevOps 转型过程中,这个事情暴露了很多问题:
- 服务监控告警延迟了 10 分钟才发出来,运维说"告警阈值设置得比较保守,怕误报"
- 开发查日志时发现日志级别不对,关键信息没打出来,开发说"当时赶时间,没来得及调"
- 测试说"我们测试环境没测出内存问题,生产环境数据和测试环境不一样"
- 最后复盘会上,大家都说"以后要更注意",但没人具体说"明天要做什么改变"
这就是典型的"文化断层":我们嘴上说 DevOps,但实际行动还是老一套。
后来我们做了几个改变,没开大会拍板,是在具体事故里被迫调整的:
第一,把告警阈值调得更敏感,哪怕有误报也要优先发现。
原来运维怕误报,把 CPU 使用率阈值设到 90%,内存使用率设到 85%。改成 70% 和 60% 后,误报确实多了,但我们也早发现了几次潜在问题。后来慢慢优化了告警规则,找到平衡点。
第二,把日志级别调到 debug,在预发环境复现问题。
原来开发怕日志影响性能,在生产环境只打 info 级别。后来发现,出了问题还是要调日志再重启才能复现,还不如平时就打详细日志,反正磁盘够用,日志轮转也配好了。
第三,测试环境尽量贴近生产环境的数据和配置。
原来测试环境用的是假数据,后来想办法脱敏了一部分生产数据放进去,虽然增加了成本,但问题复现率明显提高了。
这些改变谈不上什么「最佳实践」,就是我们在具体痛点上摸出来的。靠一次培训学不会,得在一次次「为什么又出问题了」的追问里慢慢形成共识。
第二个坑:我们以为 DevOps 是开发的事,跟运维关系不大
我们团队刚开始搞 DevOps 的时候,参与的主要是开发人员。运维偶尔参与一下,比如配置服务器权限,或者帮忙看一下部署脚本。
后来我们意识到这个问题的严重性,是因为一次"部署事故"。
某个新功能上线后,生产环境的数据库连接数突然暴增,导致数据库响应变慢,整个系统的性能都受到了影响。开发说"我们测试环境没测出来",运维说"你们代码里开了太多连接,数据库配置没问题",测试说"我们没测高并发场景"。
甩了半天锅,才发现问题的根源:开发在测试环境使用的数据库连接池配置,和生产环境不一样。因为运维和生产环境的配置是分开管理的,开发也不知道生产环境的实际配置是啥。
这暴露了 DevOps 的一个关键点:开发、测试、运维的边界不能太硬。开发要懂一点运维,要能看懂日志、能理解配置、能意识到某个代码修改对生产环境的影响;运维要懂一点开发,要能看懂代码、能理解业务逻辑、能参与到架构设计里。
但现实是:很多团队的边界还是很硬。开发只管写代码,不管部署;运维只管部署,不管代码;测试只管测试,不管上线。这种分工在瀑布时代可能还行,但在快速迭代的环境里,问题就暴露出来了。
我们后来做了几个调整:
第一,让开发也参与值班。
原来运维负责 7×24 小时值班,出了问题找运维。现在改成开发轮流值班,每人负责一周。值班期间要负责处理线上问题,哪怕半夜也得起来看日志。这个调整一开始很痛苦,开发抱怨"这不是我的工作",但慢慢地,开发开始意识到"我的代码在生产环境到底是怎么跑的"。
第二,让运维参与代码评审。
原来代码评审只有开发参与,现在也邀请运维来看。运维主要看配置、资源占用和潜在风险,不评审业务逻辑。比如看到某个定时任务没配并发控制,运维就会提醒「这个可能会把数据库打挂」。
第三,建立"共同目标"而不是"各自KPI"。
原来开发的 KPI 是"功能按时上线",运维的 KPI 是"服务稳定性",测试的 KPI 是"Bug 数量"。这三个目标有时候是冲突的:开发为了赶时间可能不充分测试,运维为了稳定性可能不愿意频繁发布。
后来我们把目标改成"交付价值的速度和质量",让大家有共同的利益绑定。功能上线了但很快出了事故,不算成功;服务很稳但功能总是推不出来,也不算成功。
实践中的一些具体经验
上面说的这些,听起来有点抽象。我想分享几个具体的小经验,都是我们在实践中摸出来的。
经验一:工具选型要看团队的实际情况
我们团队一开始选的监控方案是 Prometheus + Grafana,这套方案在技术圈子里很火,也有很多成功案例。但我们用了几个月后发现,这套方案对我们来说太重了。
Prometheus 的配置有一定复杂度,Grafana 的仪表盘要自己去设计。我们团队里真正熟悉这套方案的只有两个人,其他人都不会。这导致每次要新增监控项,都得依赖这两个人,形成了新的瓶颈。
后来我们换了个轻量级的方案:Uptime Kuma。界面简单,配置也直观,基本 5 分钟就能上手。虽然功能没有 Prometheus 那么强大,但对我们团队来说够用了,而且大家都能自己配。
这个教训很简单:工具是为人服务的,不是人迁就工具。你的团队是什么水平、什么规模、什么需求,就选什么样的工具。不要因为某个方案在技术圈子里火,就非要上。别人的答案不一定是你的答案。
经验二:文档比代码还重要,但文档不是越多越好
我们团队刚开始搞 DevOps 的时候,写了不少文档:开发流程、部署手册、故障处理指南。但后来发现,这些文档要么没人看,要么过时了没人更新,要么写得不清不楚。
比如部署手册,里面写了很多命令、很多配置项,但没有说明"为什么要这样配置"。等到要改的时候,没人敢动,怕改出问题。
后来我们调整了文档策略:只写那些"必须记录下来才能避免重复踩坑"的东西,而且尽量写得简洁、实用。
比如我们写了个「故障处理 checklist」,不写逐步命令,只写「遇到这类问题,先看什么、再看什么、要注意什么」。细节留给当时处理的人去查。
## 服务突然变慢 checklist
- 先看 Grafana 的系统监控,CPU、内存、磁盘、网络有没有异常
- 再看应用日志,有没有大量错误日志或者慢日志
- 检查最近有没有代码发布,回滚一下看看是否恢复
- 检查数据库连接数、慢查询日志
- 如果以上都正常,联系业务方,问下最近流量有没有异常
这个 checklist 没写具体命令,没有写每个工具怎么用,只是给了个思路。但实际用起来,比写了几十页的详细手册更有效。
经验三:文化转型要有耐心,不要指望一次就成
我们团队搞 DevOps 转型,前后用了差不多两年。没一直在开会培训,是在日常工作里一点点调整。
比如让开发参与值班,刚开始大家都很抵触,说"这不是我的工作"。但坚持了几个月后,开始有人说"原来我的代码在生产环境是这样跑的",开始有人主动在代码里加日志、优化配置。
再比如代码评审邀请运维参与,刚开始运维说"我看不懂你们的代码",开发也说"运维评审啥"。但坚持了几个月后,开始有人说"运维提的这个配置问题确实要考虑",开发也开始主动在代码里写注释说明配置影响。
文化转型不像工具升级,装个新版本就完成了。它更像改掉一个坏习惯,需要时间、需要耐心、需要一点压力。不要指望一次培训就能让团队突然焕然一新,也不要指望某个人突然变成 DevOps 专家。
实践中踩过的一些坑
我们团队在 DevOps 转型中踩过不少坑,挑几个比较典型的说下。
坑一:过度自动化,反而降低了效率
有段时间我们团队特别迷恋自动化,恨不得把所有手工操作都自动化掉。
比如代码发布,我们写了个很复杂的 Ansible playbook,支持灰度发布、支持回滚、支持配置热更新。看起来很牛,但实际用起来问题很多:
- playbook 写得很长,每次要发布都要先看半天配置
- 出了问题很难调试,playbook 的报错信息不太友好
- 每次有新需求,比如要支持某个特殊的部署场景,都要改 playbook
后来我们才意识到,自动化是为了提高效率,不是为了自动化而自动化。如果自动化本身变成了负担,那就得不偿失了。
我们现在更倾向于"自动化那些重复性高、标准化程度高的工作",剩下的保持灵活。比如代码发布,我们用了个相对简单的脚本,能做基本的部署和回滚就够了。一些特殊的部署场景,还是手动操作更靠谱。
坑二:追求"完美工具",忽略"团队实际"
我们团队在工具选型上,有个比较典型的毛病:总想找"最佳方案"。
比如 CI/CD 工具,我们试过 Jenkins、试过 GitLab CI、试过 GitHub Actions,每个都用了一段时间,然后总觉得"还有更好的"。结果团队里熟悉各个工具的人不多,配置也不统一,最后还是要花时间去统一。
后来我们明白,“最佳方案"不一定适合你的团队。你的团队用什么、熟悉什么、业务是什么样子,这些因素比"哪个方案更火"更重要。
我们现在选工具时,会先问几个问题:
- 团队里有没有人熟悉这个工具?
- 学习成本有多高?
- 维护成本有多高?
- 这个工具的社区和生态怎么样?
- 它能解决我们当前的主要问题吗?
这些问题比"这个工具在技术圈子里有多火"更有意义。
坑三:只关注工具,忽略沟通
我们团队刚开始搞 DevOps 时,把精力都放在工具上:CI/CD、监控、日志、自动化,但忽略了团队沟通。
后来发现,很多问题的根源在沟通:开发不知道运维的痛点,运维不理解开发的压力,产品经理不清楚技术风险。
举个具体的例子:有一次产品经理想快速上一个新功能,开发说"这个功能有点复杂,需要两周”,产品经理说"一周能不能搞定",开发最后答应了,但为了赶时间没做充分的测试,上线后出了问题。
事后复盘时,大家才意识到,问题不在于开发写代码的能力,而在于沟通不到位。产品经理不知道这个功能的复杂度,开发也不知道为什么产品经理急着要上。
后来我们做了一个调整:每次开发前,先开个短会,产品经理讲清楚为什么需要这个功能、什么时候要上,开发讲清楚实现难度、需要多久、有什么风险。这样大家都心里有数,避免了"为了赶时间牺牲质量"的情况。
结语
DevOps 说简单也简单,说复杂也复杂。核心就几条:打破边界、持续交付、快速反馈、持续改进。这些东西靠工具搞不定,得靠时间、耐心,还有一次次实践。
我们团队搞了两年,现在也不敢说「成功了」。但确实比以前更了解自己的系统,更能应对突发问题,更能在快速迭代里保持质量。
如果你也在搞 DevOps,我有几条亲身体会:
- 工具是手段,别为了上工具而上工具
- 文化靠日常小选择堆出来,比搞一次大活动管用
- 要有耐心,文化转型比工具升级难得多
- 关注人,比关注某个工具的版本号重要
DevOps 没有终点,只有下一个版本。这篇文章写的是我们的实践,不一定适合你的团队;能捞到一两个有用的点,就不算白写。
参考
- The Phoenix Project: A Novel about IT, DevOps, and Helping Your Business Win
- The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations
- Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations
版权声明: 本文首发于 指尖魔法屋-把工具换到文化时踩过的坑(https://blog.thinkmoon.cn/post/128-devops-culture-practice-tool-to-culture/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。