![](/images/k8s.png)
经过大约一周的时间,终于把几个项目迁移到 k8s,由于项目之前已经完全docker化,因此这次迁移还算顺利。但是其中的一些问题或者经验也想在这里总结一下:
- 首先,遇到的一个问题就是,每个服务可能启动多个实例;这看似一个简单的问题,其实不然,很多业务程序,在开发之初是没有考虑到程序会同时运行在多个实例当中的,特别是一些和程序依赖的JOB,就不能同时开启,因为大多读取的是同一资源,这会导致重复性计算灾难。要解决这种问题,一般有两种方案:
- 将JOB提取出来单独运行;这种方案有个问题就是,与JOB相关的所有依赖代码,也需要一并复制到新项目当中,如何处理这种代码的同步也是一个麻烦问题。
- 新建一个项目,将定时任务放到新项目中,原始项目提供服务接口,可以是 http ,也可以是队列服务;新项目中的定时任务执行时,直接调用这些服务;这样服务之间的交互就只依赖服务,而不依赖具体的代码实现。最后保证新项目在k8s当中只有一个实例运行即可。
在这次迁移过程中,我们选用的是第二种方案,目前感觉运行还算良好。
其次是服务之间架构改变带来的思维改变,这个怎么说呢?以前我们采用的是nginx作为静态服务器 + 代理服务器的架构,就是nginx冲锋陷阵在前面,它既处理静态资源请求,也处理后端API转发。k8s上来后,由于ingress冲在前面,nginx突然就失宠了,此时如何配置服务之间的路由一时有点没有反应过来。但是一旦思维转变过来后,nginx的角色从此变得异常简单,它不再是中心,从此变成和其他服务一样的单一角色,它只需要把静态资源处理好就是了,docker file 也变的极其简洁。 通过ingress做路由配置,我们就可以把 k8s 看成一个跨地域,跨机器的服务池,里面可以部署任何服务,通过路由将前端请求与各个服务连接。程序员再也不用担心如何部署服务了:)
最后是服务部署的区别,由于之前我们的服务也都是docker部署的,因此差异主要体现在,服务重启这块;之前,我们是用docker命令手动停掉服务,然后用docker-compose命令启动服务;k8s 上来后,就不需要这么干了,当 image push好后,我们目前采用命令:kubectl edit deploy xxx 直接修改其中image的版本号,即可完成服务的重启。 不过,这种方式有个弊端,就是edit的那个deploy文件是在k8s缓存中的,如果之前有人在本地下载过这个文件,他每次是采用先修改该文件,然后再 apply 该文件的方式,重启服务,如果没有事先保证版本一致,就会造成程序不一致的问题;或者 k8s缓存出问题,要用本地文件刷进去,也会导致该问题的发生。因此,这个地方务必要注意程序版本问题。