接下来讲下CICD,我们的服务容器化之后,CICD也很方便,围绕容器,围绕K8s,代码变成容器镜像、镜像发布到不同环境测试,最后再到线上,蓝绿、灰度等策略也很好做。
业务部署后,我们需要有一套问题发现、问题定位的手段,这样大家才能安心。常用的手段有监控、tracing以及日志系统。
对于监控,我们需要同时做好基础监控以及业务监控,容器的CPU、内存、网络、各种句柄等,业务层面,我们需要监控业务的服务质量,比较常见的就是业务的响应时间、错误率等。
通过tracing,我们可以找到具体某个请求在调用链路上的瓶颈,比如由于某个服务访问一个不重要的旁路服务,导致延时增加了50ms,如果没有tracing,很难发现这样的问题,同时还可以把数据库、缓存等中间件服务的访问信息上报到tracing系统,便于排查一些类似数据库慢查询、hot key、 big key引起的问题。
日志服务就更重要了,无论是性能问题、业务问题的排查都需要相应的日志,业务容器化后,日志查询会更加复杂一些,因为容器不会固定运行在某个主机上,需要把容器的日志采集到一个中心化的日志服务,采集容器日志时,有不同的方案,有的小伙伴选择使用SDK在业务容器里直接把日志打到日志服务,更多的是日志先落盘,然后再通过agent采集到后端存储,如果业务的log都统一输出到标准输出,建议部署daemonset的方式统一采集,如果容器的log输出到某个文件,建议使用sidecar的方式会更灵活。同时建议把进程的启动停止日志以及业务日志分开,在定位容器的启动失败等一些关键事件时更方便。关于日志平台,可以使用云服务商的日志服务,也可以自建,根据各自的需求而定。
在设计系统的时候,我们要时刻考虑到,故障是不可避免的,我们随时要做好故障的预案。
常见的故障有网络故障、硬件故障、系统故障、业务故障,其中网络故障需要考虑业务部署的时候是不是要做好分区的隔离,比如可以在多个区做容灾和流量切换的机制。对于硬件故障,需要考虑一台母机挂了以后,能够结合云服务商的能力来保证同一个用户下面的子机尽量打散;同时为避免单点故障,一个服务可以多一个副本,比如虚拟机挂了以后,可以做一定的冗余。系统软件建议提供云服务商提供的系统内核,因为他做了很多优化。业务的故障,我们平时在发布过程中不要一次性马上把业务发布上去,要流量一点一点逐步发到线上,同时要做好一个预案,假如新版本问题,能否马上回滚到之前的版本。
融合了上面的一些的设计理念之后,我们的业务系统首先要做一定的冗余,在多个可用区部署相同的服务,流量可能对外要提供两个不同的入口,在入口处对流量进行分配,当出现导致网络隔离的问题时,可以直接从前端进行流量切换,微服务和数据库也做了拆分,使得每个服务都可以单独做自动伸缩。整体看来,就是一个比较合理的分布式的业务系统。
关注业务而非基础设施。这里给大家讲一个发生在我们这里的一个真实的故事。
有一天一个客户联系到我们说他出十万块钱,让我们帮他们做一个事情,客户在腾讯上部署了一个K8s生产集群需要升级到更高版本,他们发现K8s集群升级时,集群的容器会重启一遍,但是对比腾讯云上提供的TKE集群,从一个版本升级到另外一个版本,容器不需要重启,对业务来说是无感知的、透明的。
接收到这个求助之后,我们跟客户介绍了TKE的技术方案,整个升级过程需要做大量前置校验工作,并且还要针对不同的K8s版本做patch、以及适配不同的Linux发行版等,这些工作在客户的环境里实现起来工作量太大,成本太高。K8s集群的维护是很复杂的,他介于IaaS跟PaaS之间,需要针对Linux内核、K8s内核以及依赖的网络、存储、计算资源做大量的优化,才能保证集群稳定、高效运行。对团队来说,需要招聘业界顶级专家,否则当集群功能异常无法解决,可能造成业务大面积受损。