09 · 运维与发布 · 可重复的制品
笔记本里打出来的包,下一周没人能再打一次
DevOps 工程师把构建、配置和发布做成可重复的流水线,生产不能依赖某台笔记本上的手工包。何时对哪些仓放开,交给发布经理。
开发:我这台机器刚才编译过,直接传上去最快。
DevOps:生产只收流水线的制品。本地包没有版本号,回退时不知道退到哪一版。
DevOps 工程师让同一次提交永远打出同一个包
环境不一致是上线故障的常见来源。DevOps 工程师的特点是把构建、测试、制品和配置分开管理。代码版本、依赖锁定、构建号、配置项,缺一个就不能上生产。他不在服务器上临时改一行再重启就算发布。那种改法没有记录,下一版部署会盖掉,故障还会回来。
流水线里至少有自动化守住的那几道门。门是红的,制品就不能进发布候选。他和发布经理的分工:DevOps 保证候选版本是可追溯的,发布经理决定何时对哪些仓库放开。没有候选版本,发布经理只能靠人肉传包。
配置不写进包里
数据库地址和密钥不进代码仓库。环境差异用配置注入。DevOps 保证测试环境和生产的构建步骤相同,不同的只是配置。步骤不同,测试通过不能说明生产能启动。密钥轮换有负责人,不把密钥贴在群公告里。
热修包的来历不明
有一次生产故障,同事用笔记本打了热修包直接替换。当天恢复了,三天后另一位同事用流水线发布,盖掉热修,故障复现。DevOps 工程师禁止继续传本地包,把那次热修补成提交,由流水线重新产出制品,再按发布窗口替换。回退按钮指向上一构建号,演练过一次回退。之后没有构建号的文件,服务器账号也上传不了。
这条限制会让紧急修复慢几分钟。慢的是找不到人再打一次包的那种慢。DevOps 工程师要求回退和前进用同一条流水线。回退如果是手工拷回某个目录,那个目录里的文件仍可能是笔记本打的。他演练时从构建号回退,再从构建号前进,两次都记录耗时。耗时超过窗口的,先改流水线,再谈紧急发布。紧急发布最容易把这条纪律冲掉,所以更要事先演练。配置项改名必须兼容旧候选版本,不能新服务认新名、旧服务回退后启动不了。回退启动不了,等于没有回退。他把依赖锁文件和构建缓存分开管理。缓存可以加速,不能改变制品内容。为了快而跳过锁定依赖,某次构建会悄悄升级一个库,行为变化却找不到提交。
找不到提交的变化最危险,因为回退代码也回不去。流水线因此宁可慢一点,也要让同一提交产出同一摘要。生产改环境变量必须回写配置仓库,否则下一次部署会把救命的那一行抹掉。制品摘要保留到版本下线之后。追查某一周生产跑了什么,摘要比口头回忆可靠。回退和前进用同一条流水线,从构建号回,再从构建号进。回退如果是手工拷目录,那个目录里仍可能是笔记本打的包。没有构建号的文件,服务器账号也上传不了。何时对哪些仓放开,仍由发布经理决定。
构建代理的时钟和制品仓库的时钟差超过两分钟,摘要对得上也可能让过期签名被当成有效。他要求流水线在打制品前校准时钟,并把代理主机名写进构建记录。没有主机名的制品,生产拒绝接收。