62

DockOne微信分享(二零零):龙腾出行基于Kubernetes的DevOps流水线实战

 5 years ago
source link: http://dockone.io/article/8485?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【编者的话】伴随着微服务架构的普及,龙腾内部很多业务线从单体架构转向微服务架构,在根据业务边界进行拆分时,带来的服务实例数目成倍数增长,这给开发、运维、测试增加了不少复杂度和工作量,此时我们利用Kubernetes来搭建容器云平台,并实现DevOps简易流水线,来减轻开发和运维工作,提升整体工作效率,下面将分享一下我们的实践过程,希望可以给大家在构建整体平台时带来一点思路。

龙腾出行的IT系统架构演变历程

RBrQVfR.png!web

2016年之前,我们有3种开发平台,Java、.NET、PHP,Java和.NET所占业务系统几乎各占一半,但.NET平台在服务端架构方案比较欠缺,虽早已使用WCF进行分布式开发,但并不能跨平台,微软的闭源政策导致很多新技术不能友好兼容,在15年虽已实行开源政策,但时间还是太晚,且国内市场主流还是Java系,因此决定全部转型Java。

在Dubbo时代,虽然开发业务效率有一定提升,但跟WCF一样,服务对平台敏感,难以简单复用,在提供对外服务时,都会以REST的方式提供出去,另外框架对服务侵入性较大,不能很好的支撑后续技术发展,期间我们也有根据Thrift + ZooKeeper自研rpc框架,并且考虑支持多语言平台,但难度较高,团队规模也不允许,所以早早放弃,尽量使用开源平台,此时我们对Docker、Kubernetes进行调研,因此打开了另一扇大门,Kubernetes的功能足够炫!

利用Kubernetes搭建容器云平台

Kubernetes——容器编排的王者,容器云的首选方案,对虚拟化平台的革新功能:

  • 资源调度
  • 弹性伸缩、自动扩展
  • 资源高利用率
  • 负载均衡
  • 资源基本监控
  • 容灾备份
  • 滚动更新
  • 日志访问
  • 自检和自愈

等等,以上功能是在虚拟化平台中缺失或需要花时间实现的功能,但作为Kubernetes平台的基础功能,大大简化了构建工作,提升开发运维效率,Kubernetes各组件功能如图:

M3YbeeE.png!web

2017-2018年间IaaS/PaaS、Docker、微服务、互联网架构等等各种概念侵袭,收到一波波的洗礼,我们完成了Kubernetes从无到有并应用至生产,SOA/微服务的业务边界划分,并推行了前后端分离开发,奠定业务与人员架构基础,使前后端可并行开发,更好的支撑后续业务、技术发展,人员更精于自身专业方向。

目前我们的服务器在IDC环境中,已有VMware虚拟化平台,因此在虚拟机上搭建私有容器云是首选方案。

Kubernetes高可用采用官方推荐方案,整体搭建采用Keepalived + Nginx + Kubernetes + Calico,基于Kubeadm方式安装1.11.1版本,3 Master + 3 etcd + 12 Node节点,整体流程图:

rYV3ymR.png!web

高可用集群采用1主2热备,将Keepalived的VIP绑定到VM网卡上,当Master因故障宕机,另外两个Master会根据Keepalived配置的优先级接管VIP,从而起到灾备作用,另外将kube-proxy的serverIP换成Keepalived生成的VIP和自定义端口号,通过Nginx转发至3个kube-apiserver,实现3 Master参与负载。

kubeadm-ha已经完全可以在生产环境使用,当Master故障无法恢复时,可以快速加入一个新Master节点,保障集群可靠性。

etcd采用集群内3节点方案,Kubeadm新版本可以友好支持etcd-SSL的操作,当etcd故障时,通过Kubeadm可以快速将新节点加入集群。

平台经过多次灾备演练,目前稳定可靠,如图大家应该比较熟悉:

aQBnqmr.png!web

我们采用ingress-nginx来取代VM上面的Nginx,服务内部通讯采用Kubernetes推荐的CoreDNS,通过ConfigMap方式配置DNS域名解析,取代原来挂载宿主机/etc/hosts方式。

外网访问,内网集群将Service以NodePort方式暴露端口,通过负载均衡器进行转发。

开发框架的变迁

根据Kubernetes优秀的设计思想,开发也有相应的调整,新业务统一采用React+Spring Boot进行开发,因此我们的开发平台如下:

  1. node.js负责Web/H5前端
  2. Android 、iOS移动端
  3. Java/Spring Boot负责后端业务开发

一张图看懂开发架构:

Q7jUZzE.png!web

在应用Spring Cloud Netflix套件时,Eureka安装在集群外的VM上,服务注册Eureka默认读取的是hostIP,在Kubernetes上Pod被分配的虚拟IP在集群外部无法访问,我们尝试过多种解决方案,例如挂载Volume方式,写入宿主机IP到容器内的env变量,最终还是统一将注册Eureka Clinet方法重写,将注册服务地址改为Ingress配置的CoreDNS域名,集群外部访问成功。

在分布式微服务中,各服务都有一套独立的配置,Spring框架尤以面向接口编程思想贯穿整个项目工程,配置项众多,我们选用携程Apollo配置中心来替代Properties,多个服务可共享一个namespace配置,解决复杂而繁琐的配置问题,配置中心已经上升到整个架构层面的作用

API统一接口文档采用去哪儿开源的Yapi,可私有部署,功能齐全,QA也可做接口自动化测试,测试集脚本语言支持Pre-Script,遵循JavaScript语法,如图:

32iamqM.png!web

DevOps流水线设计

根据上面的介绍,经过一定积累和沉淀后,我们开始设计CI(持续集成)、CD(自动化部署),CI/CD的优势显而易见:

  • 解放了重复性劳动:自动化部署工作可以解放集成、测试、部署等重复性劳动,而机器集成的频率明显比手工高很多。
  • 更快地修复问题:持续集成更早的获取变更,更早的进入测试,更早的发现问题,解决问题的成本显著下降。
  • 更快的交付成果:更早发现错误减少解决错误所需的工作量。集成服务器在构建环节发现错误可以及时通知开发人员修复。集成服务器在部署环节发现错误可以回退到上一版本,服务器始终有一个可用的版本。
  • 减少手工的错误:在重复性动作上,人容易犯错,而机器犯错的几率几乎为零。
  • 减少了等待时间:缩短了从开发、集成、测试、部署各个环节的时间,从而也就缩短了中间可以出现的等待时机。持续集成,意味着开发、集成、测试、部署也得以持续。

代码管理工具我们一直在用GitLab,经过研究,GitLab在8.0+版本就已经集成了CI/CD,可以帮助我们快速实施自动化,相比Jenkins,GitLab-CI更加轻便,只需要在项目工程根目录创建.gitlab-ci.yml文件,写好Job脚本即可,在服务器安装gitlab-runner工具,帮助执行Job,一张图看懂我们基于Kubernetes的CI/CD Pipeline:

IFrMNvm.png!web

借助gitlab-runner,我们已实现多个DevOps流程,包括NodeJs、Spring MVC,以及在VM虚拟机上的CI/CD:

QN7VJbA.png!web

如部署遇到问题,可快速手工触发CI/CD,回滚上一个版本,保障线上始终有一个版本可用。

CI/CD流程代码示例:

stages :

- build_test   #测试CI

- deploy_k8s_test #测试CD

- build_prod   #生产CI

- deploy_k8s_prod #生产CD



#测试CI

build_test_job:

stage : build_test

script:

 - mvn clean install

 - cd target

 - docker build -f classes/app.dockerfile -t registry/maven-project:$CI_COMMIT_SHA .

artifacts :

paths :

  - target/classes/deploy.k8s.yaml

tags :

 - runnerHost

only :

 - master



#测试CD

deploy_k8s_test_job:

stage : deploy_k8s_test

before_script :

- docker push registry/maven-project:$CI_COMMIT_SHA

script: |

  kubectl apply -f deploy.k8s.yaml

  kubectl describe -f  deploy.k8s.yaml

after_script :

- pwd

tags :

 - runnerHost

only :

 - master

运维监控平台

Kubernetes在1.13+版本中已经剔除了Heapster + InfluxDB作为默认监控工具,主推Prometheus,Prometheus可以做到代码级的监控,我们在各虚机、中间件、应用程序中使用工具收集资源消耗信息。

Grafana可作为大数据展示平台,实时查看各项资源运营情况:

bqMneqF.png!web

Prometheus也提供Java开发包,可以做到代码级统计,当服务响应报错或时间过长,可触发告警,通知相关开发人员查看原因:

qeemUfy.png!web

平台整体架构

私有容器云和DevOps主流程已经实现,配合Prometheus监控,基础设施层形成闭环,这是从无到有的过程,整体架构一张图可以看懂:

YFrumuB.png!web

总结:目前的框架都是原生应用,利用了各家的优秀特性,我们并没有针对性改造框架,原生功能足够满足团队业务需求;有许多地方还需要深入研究和应用,完善基础设施层,例如监控目标、告警规则、Service Mesh如何将服务间请求下放到基础设施层、CI/CD的持续完善,金丝雀发布等等。

Q&A

Q:Kubernetes本身技术框架带来的问题在生产环境中有碰到没,请举几个例子。

A:Kubernetes如果出问题带来的都是雪崩效应,例如网络Calico、存储etcd出现故障是灾难性的,我们也踩过不少这方面的坑,所以要做到高可用才能稳定生产。

Q:一个开发人员想在开发环境部署一个服务,他必须要懂Kubernetes,去写那些yaml吗,有什么易用的可视化平台?

A;yaml有一套语法体系,非常简单,可以搜一下相关资料,主要是理解Kubernetes的相关原理,根据服务要求编写配置文件,可视化平台如Kubernetes Dashboard上就有,不过基本没用,如果运维体系比较成熟,这些yaml可以交给他们来编写。

Q:公司环境较复杂:包含Java项目、PHP项目,Java项目目前大多是Spring Boot框架,PHP是ThinkPHP框架,项目架构并不复杂,有少许Java项目需要用Redis到Memcached、缓存机制。最大问题的是多,项目应该如何较好的依托Kubernetes顺利架构,将项目可持续集成?

A:我们的Redis这一类中间件还放在VM上,目前尚未打算搬移到Kubernetes上,Kubernetes + Docker天然是跨平台的,PHP也可以支持,并且对容器集群(既应用集群)管理非常出色,包含部分自动化运维,并不会因多种开发语言而增加负担,持续集成是另外一块,目前各大CI工具厂商也都支持Kubernetes,比较友好,我们采用的是GitLab-CI。

Q:Calico网络你们如何解决跨中心的网络通信,BGP只能在同一个交换机才行。

A:我们目前还没跨机房通讯,不过etcd需要高速网络才能数据同步,跨机房拉专线比较合适,BGP协议还没用到,小规模部署可以考虑添加静态路由的方式打通Kubernetes集群内外的网络。

Q:应用有是否有状虑使用,用的什么存储解决方案?

A:我们提倡无状态部署,目前所有应用服务都是无状态,有状态服务存储可以考虑NFS。

Q:用二进制安装可以不,Kubeadm会有升级些问题,默认的Iptables不太好吧。现在是IPVS。

A:二进制也可以,比较稳定,Kubeadm滚动升级我们还在踩坑中,升级策略目前我们是另外搭集群,一键部署所有应用(每次部署都会统一存储最新部署yml),对外网关可选择性切换应用,Iptables被Kubernetes捡起来又放弃了,未来的趋势是IPVS,目前我们也在测试环境中试验。

Q:服务监控和服务器监控这块的取舍,现在监控都是用Prometheus?

A:Prometheus是CNCF旗下仅次于Kubernetes的项目,对应用程序比较友好,做服务监控非常棒,配合Grafana图形展示体验非常好,跟Zabbix相比各有特色。

Q:请问你们是创业问团队还是大规模团队?考虑Kubernetes机缘是?对于Kubernetes来说生态所存在的不足,如安全问题是怎么考虑的?

A:不管创业还是大规模团队,适合自己业务,技术可持续演进、完善并提升效率就是好的方向,考虑Kubernetes是因为它的优秀功能,让技术团队可以站在更高的起点,看得更远;Kubernetes生态已经非常强大,在内网运行,相对较为安全,另外也有启用RBAC权限访问控制,配合其他持续集成工具,安全控制都可以个性化定制。

Q:Kubernetes集群你们为什么没有部实体机在署上?

A:虚拟机和实体机都行,我们实体机数量有限,包括中间件那些,做高可用会用占用比较多的Node机。

以上内容根据2019年1月15日晚微信群分享内容整理。分享人 周伟,现龙腾出行IT架构师,负责Kubernetes运维,DevOps流程设计,Java应用开发 。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesd,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK