生产环境部署指北

写在开头

这本是一篇供我团队内部使用的文档,但是最近我的好哥们F在他的项目上由于操作疏忽而导致数据丢失。因此打算将文档整理一下发表出来,供各位参考。

BTW,最近喜欢在每一段落的开头使用祈使句,来减少用户阅读时间,帮助筛选重要信息。

操作总则

有限,备份,灰度,审批,预防

  • production环境仅安装有限的软件,分配有限权限
  • 任何操作之前都需要备份
  • 发布到production前先进行灰度
  • 手工操作数据,命令执行前进行审批
  • 进行流量,脏数据,注入等预防措施

部署前/开发时

明确你所使用的技术框架、部署难度、部署方案。其中还需要考虑部署服务器是否私有还是需要交付到客户端进行使用。在上机前,需要检查环境变量、运行模式是否已经切换至production等类似的模式,使用如npm run dev的命令来运行服务应当被严厉禁止。若服务需交付至客户服务器上使用,建议使用Docker或k8s的方案来减少部署难度,避免因客户机环境不可控而导致的兼容性问题。

对来访流量做估计,以一个普通的博客举例。在使用Cloudflare的CDN控制缓存之后,回源之后的流量大约在50Kbps~100Kbps/Visit左右,这样可以有一个较为准确的估计以此采购合适的服务器。对于流量方面,可能遇到流量突增,如新功能发布,热点活动等。在技术允许的情况下,设置等待室,懒加载,提前预载等方式缓解服务器压力。

设置每站点私有空间,如果项目既不使用Docker,也不使用独立服务器,至少拥有一个文件夹。这个文件夹必须是具有版本控制功能的,以方便在出现问题时及时回档到上一个提交。在此附上一篇文章如何规范你的Git提交信息,如果你的提交里只有Update、日期等无意义提交内容,那我也只能祝你好运了。

使用Feature Flag。为每一项独立的功能设置开关,像插件一样开发你的系统,并在技术与合规允许的情况下对产品设置云控器。在问题出现时,可以绕过服务本身直接禁用出现问题的功能,以让整个平台降级但可以运行。

对每一次提交进行审核与CI测试。下图是一张来自Cloudflare的部署流程图,可以看到在每一次提交之后都会采取Pull RequestCI/CD的方式进行审核,以确保最终交付至客户的版本不存在问题。不仅如此,在本图中,我们不难发现,在部署到客户之前还会有DogfoodCanary的内部测试环境,再次加以测试。

Cloudflare开发规范

部署时

使用Nginx等反向代理工具,根据先前计算的预估流量设置连接池与负载均衡。在条件允许的情况下应当配置n+1台服务器,一台作为反向代理,不运行任何生产程序,拥有大带宽资源,小计算资源。另外n台运行生产程序,拥有小带宽资源,大计算资源。在流量突增时,可以通过增加n的方式来增加服务器数量,以应对流量突增。但是需要尤其注意:在拥有多台应用服务器时,应当确保数据一致性,中间件事务的幂等,轮询等问题。

在进行灰度发布时,应当选择合适自己的发布方案,如:AB测试、蓝绿部署、金丝雀发布等。在Nginxupstream中设置合适的流量比例。除此之外还应当设置合适的回滚方案,如:自动回滚(如在触发大于阈值的HTTP错误时)、手动回滚。若对Nginx配置文件编写不够熟练,可以使用NGINXConfig - DigitalOcean以快速生成合适的配置。

配置本机防火墙,若使用Cloudflare等CDN,应当获取其IP段并设置白名单。在配置防火墙时,应当设置合适的规则,如:仅开放80、443端口。以此避免ip扫描导致的源站IP泄露。此外,随着Tailsclae等SD-WAN产品成熟,应当对SSH等管理端口设置仅允许VPN访问的方式。

对数据库进行审计,应当开发一个用于链接生产应用与数据库的中间件。来避免无WHERE查询DELETEUPDATE等危险操作。并对每一个接口应当设置合适的权限。在人工执行的时候,需要Tech Lead或PM进行审批后才可执行命令,对每一次语句执行做留档。

对可执行文件的权限进行管控。在生产环境中,应当杜绝使用root权限执行程序。若不适用Docker,为每一个项目设置一个独立的、不可登录的、不属于sudoers的用户。这样即使被反弹shell,攻击者也需要一定的时间进行提权。

部署后

如同做完卷子要检查一样,部署完成之后也不代表万事大吉。还有以下几点需要做。

我发现我最近说话越来越像AI了…

部署分析网站,如:Sentry用于监控前端错误,Prometheus用于监控后端错误。此外通过如Google Analytics等工具来监控用户行为,分析网页热力图,找到用户体验缓慢的地方,及时做出调整。

配置告警,使用Uptime Robot来及时监控网站是否宕机,关键Ping&Pong节点是否正常。在出现问题时,及时通知SRE,进行处理。在处理宕机/大量错误问题的时候,建议遵循以下顺序

  1. 从CDN/反代层面打开维护模式,阻止用户访问,避免错误报到前端
  2. 保存当前状态快照,以便问题分析与回滚
  3. 备份数据,关闭数据库,阻止脏数据写入
  4. 重启服务,查看日志,定位问题
  5. 回滚内容到上一可用版本

定期备份网站,对前后端分离的应用来说,除非发生前端网页被挂马的情况,否则前端可完全依赖版本控制软件。但是对于后端,数据库等数据,应当定期备份。在备份时,应当使用mysqldump等工具,而不是直接复制数据库文件。以避免数据不一致的问题。在条件允许的情况下,使用增量备份避免文件大小不可控,并将备份文件上传至对象存储等第三方存储,避免服务器被挂马而导致备份文件被污染。

总结

没啥好总结的,祝各位在部署的时候仔细仔细再仔细。引用Disk Genius的开屏语:数据无价,谨慎操作