前言
我跟这个话题接触的契机,源于我之前在架构组的相关工作,很多企业刚起步的时候会进行一些cicd的建设工作,之前我对这块是一无所知的,如果说要进行一些云原生的改造,或者服务改造就会比较困难。
再者,我也会在一些招聘网上去看,近几个月也是有在招聘架构师的,对于k8s的知识也会有所要求,还有我之前面支付宝的架构组,他们是管sofa-rpc、mosn之类的,也会涉及到对这些知识的了解。
我可以感受到在19年往后1-2年吧,当时是中间件的天下,什么dubbo、网关、rpc等等,大家卷框架的性能,往后几年k8s 开始发展起来,渐渐的这种服务上云变得流行起来,到现在可以说基本大部分企业都会进行容器化服务部署,不得不要求我们对这块有大概或者深入的理解。
k8s 一些概念
调度过程
我想从调度过程来描绘,外部一般会用kubectl工具进行api调用,进入k8s内部,会分一个master、node,master是负责管理、调度,node才是节点,pod环境、运行状态等等。
当我们调用api的时候,会进入到master的api-server,这里会汇集接口,里面会有调度器,用于调度pod容器。还有etcd,储存一些数据,配置到内容。
另一边node节点的情况,首先调度过来的时候,会有kube-proxy来路由,然后到service进行服务发现过程,里面这个pod 它会有一个kubelet,通过deployment来创建容器,yaml格式配置方式。还有容器环境,比如说我们java应用需要jdk、操作系统上配置。
基础概念
1、构建容器:deployment 文件,用于配置应用版本、环境、相关参数
其中里面RS,用于构建无状态的服务,会有副本数,健康检查;如果有状态的服务,像redis、mysql,需要采用statefulSet,它会按照顺序的进行构建,比如说你节点挂了,恢复之后是不是要保持原本的序号;还有另外一个是守护线程,用于一些共有的配置,比如说日志的收集,如果我每个节点都配置挺麻烦的。
2、服务发现:server,也会简称svc,相当于我们微服务里面的nacos,它会监听服务起来的信息,然后将他们的数据注册上去,当kube-proxy调用的时候,会将server的数据转到cors-dns进行负载
3、网关:ingress,本质跟gatewy相似的,用于流量转发
4、服务网格:istio,它将流量进行拦截负载转发,也可以进行灰度功能实现
5、监控体系:普罗米修斯+grafana,前者会收集k8s 容器的数据,然后后者会提供对应的页面以及api
6、数据库:ectd,key-value数据库,采用raft一致性算法来保证数据的可靠
工作相关内容
- 健康检查
这个会涉及到,比如说deplyment里面会有三个比较关键的探针,第一个是startup探针,就是容器起来之后会给出对应的状态,这个一般是监听服务端口。第二个是存活探针,如果说节点宕机,需要进行重启,依靠就是存活探针进行类似心跳收集。第三种是readness 探针,容器起来了不代表可以访问,可能里面一些资源还是初始化,或者说需要预热,这个在很多开源中间件会做文章,比如说我执行一条查询sql,如果说有结果证明服务跟mysql这种连接已经预热完毕,因为java是边运行虚拟机边解释过程,需要我们进行中间件预热操作。
- cicd devops
非常常见的需求,比如说一开始会使用jenkins进行构建服务,但是它对于流程的卡点不是很友好,还有多服务的项目也不友好,如果其中一个服务挂了,整体就需要回滚,不然流量一进来就产生脏数据。还有如果说需要一些领导审批,需要流程上的卡点。
整个流程:研发阶段-提交代码到gitlab,测试阶段-完成之后,部署阶段-首先是编译,会执行mvn clean package,来进行初步的编译,可以排除一些低级异常,然后进行java -jar 打包生成对应jar包,进入构建阶段,它会进行通过dockerfile制作镜像,然后推到harbor仓库里面,最后是cd构建到k8s上面。
这整个链条可以加上一些插件,比如说代码漏洞扫描,单元测试附加插件。包括蓝绿环境的切换,这里面涉及改ingress 转发。
- 本地联调问题
这个一开始很困扰我们的点,因为本地跟k8s 环境服务发现没有打通的,比如说我本地服务依赖其他服务,那么我启动的时候本地就需要将这些基础服务一并启动,非常蛋疼。
解决方案:
第一个可以用kt-connect,阿里开源的框架,可以打通本地跟k8s网络;
第二个仿照前者来实现,比如说本地需要调用k8s服务发现,我们可以用kubectl将远程的对应命名空间service数据拉下来,然后放到本地对于dns缓存里面。如果k8s服务需要访问本地服务,又分两种情况,第一种是流量完全转发,这时我们需要将服务副本数改为0。第二种如果是部分流量转发,需要结合istio进行流量的匹配再转发,这个我们可以放下一个点就是灰度流量,或者特定流量联调方案上。
- 全链路灰度实现、压测方案、多涌道实现
全链路灰度是其他技术方案的底座,它包括流量染色、流量负载、流量规则、数据隔离等等,当我们实现完这个底座的时候,其他技术方案只不过是一个变种。
我们当时项目是有三个版本去迭代完成这个技术方案,首先是进行rpc框架、注册中心统一,然后一期是南北流量改造,就网关到服务那一层。二期是东西流量改造,就是服务到服务改造。最后第三期是灰度规则细化,主要是参考阿里opensergo规范来设计。
里面存在一个问题,就是我们技术方案没有跟cicd整合起来,对发布流程不太友好的。接下来我们来实现k8s相关的全链路灰度方案。
首先构建的时候,我们的服务都有一个版本号,或者说打上对应的标签,然后网关层主要是ingress转发规则,东西流量依靠istio 里面配置,比如说a供应商走v1版本,b供应商走v2版本,它也可以实现百分比、区域规则负载。
好处:我们不需要改造中间件代码,因为底层流量已经被istio 通过envoy sidecar进行拦截转发,相当中间人去处理这些规则,服务只需要关注自身业务即可。
缺点:规则管理,这里面都是配置在k8s文件里面,我认为需要自研一套服务来管理,比如金丝雀发布,灰度流量规则,AB TEST。