kubernetes在Bravikods的落地实践

【编者的话】随着Kubernetes的遍地开花,Kubernetes的优点能够说是深刻人心,因此,咱们也掀起了一场改革,目的就是改变咱们以往的运维模式,利用Kubernetes,来实现更高效的交付和更好地提升咱们的资源使用率,推进标准化,适应云原生。本次内容主要是:基于团队实践的Kubernetes落地实战经验分享。前端

整体状况介绍

Bravokids业务范围介绍,业务特性

Bravokids(百思童年)是上海百思童年母婴用品有限公司旗下的婴童新零售品牌公司。node

近几年教育机器人这个概念一直炒得比较火,市场上各类产品层出不穷,可是十年树木百年树人,教育类产品最为难作,要思考的东西更多。科技的不断发展,孩子的玩具愈来愈智能,支持编程,支持对战,支持云台智能设计,手柄操控,从小玩具变成大玩具。你们都知道大疆(DJI)发布了自家的教育机器人“机甲大师”,Bravokids也发布了旗下的教育机器人“爆风主义遥控互动机甲 X1”,目前在小米有品App众筹。编程

广告就打到这里,下面来讲技术方面

为了更好的支撑业务的高速迭代,咱们在2018年末上线了基于Kubernetes和Docker的容器云平台。截止到目前,已经超过有430多个应用采用了容器部署,总实例超过4000,总共维护了8套Kubernetes集群。本文主要介绍Kubernetes在百思落地的一些经验和思考。后端

基于Kubernetes持续交付方案:如何一键实现容器编排

对接Kubernetes集群的部署,最麻烦的地方是一堆yaml文件的编写和管理。在这件事情的处理上咱们当时有两个方案,一个是本身开发一个Operator来简化配置,并作一个配置管理中心作版本管理;另外一个是寻找外部的开源方案。最终,咱们选择了开源的Helm。由于Helm已经作好了yaml配置的简化和版本管理,是一个极好的包管理工具。缓存

这里大概介绍一下咱们改造后的持续交付流程,首先是GitLab收到一个push event,自动触发Jenkins Job的Webhook进行构建。Jenkins Job中,集成了咱们的应用构建和部署相关的脚本,包括先后端代码的build——>单元测试、代码扫描等——>基于Dockerfile的镜像构建——>从chart museum中拉取已写好的helm chart template到本地进行修改,而后再推送至chartmuseum——>使用Kubeconfig与目标集群进行交互,经过Helm Upgrade将应用部署至Kubernetes集群。服务器

在这里尤为要提到,持续交付不止于提高业务交付的效率。由于曾经管理过一个应用一个Jenkins Job,深知这里边的痛苦。因此咱们对整个持续交付流程,作了进一步的抽象化。把构建脚本、镜像构建、Helm Chart配置这几个地方进行模块化后,把全部应用的部署交付统一成一致的脚本进行部署,实现经过几个简单配置就能够把一个应用对接到咱们的持续交付平台中。这在效率提高上,相比之前真的实现了一次质的飞越。网络

最后提一下如何对接多集群的部署。最直接的方式,确定是经过命令行切换Context,但这种方式会相对原始一些,并且在Jenkins Slave动态生成的状况下,还要作一些定制化配置。咱们选择了Jenkins的Kubernetes Cli Plugin,结合Jenkins的凭证管理,实如今任何Slave上均可以一键进行容器编排。架构

关于Kubernetes落地的一些细节

关于集群网络方案的选择

最先咱们实际上是尝试过自建Kubernetes集群的,基于开源的方案基本上能知足绝大部分需求,可是若是涉及到集群外、跨集群的服务间调用,咱们就必须从新开发CNI插件而且在私有网络中添加到Pod的相关路由,来打通Pod与集群外的网络。基于人力等方面的考虑,咱们最终选择了TKE,Pod已实现与Node节点在同一网络层面,促进了咱们后面的快速落地。框架

Kubernetes服务暴露方式

Kubernetes服务暴露的方式有三种,分别是Service的NodePort、LoadBalancer,和Ingress。咱们用的是Ingress。这个主要是由于Ingress更符合咱们利用Nginx作路由的现状。运维

Kubernetes监控

监控主要有三大块,分别是事件监控、资源监控和调用状况监控。前二者咱们目前尚未本身作,暂时用的是腾讯云的监控,资源监控上加了metrics-server作加强。调用状况监控方面沿用了之前的监控方案,在容器中集成了pinpoint-agent作APM监控。

日志收集

由于本来咱们的应用日志就有固定的目录,固然,这得益于咱们的标准化。因此咱们的方案是使用Pod反亲和性来让同一应用部署在不一样的Node节点上,并经过日志落盘,在集群中部署Filebeat DaemonSet,给日志打上相关fields,利用Logstash切割后收集至ES集群中,经过Kibana进行展现。

Kubernetes为咱们带来了什么变化

变化仍是挺多的,包括资源利用率的提升,部署上效率的提高,多环境一致性,秒级扩缩容、Jenkins Slave动态生成等等。另外,利用Kubernetes在部署上的优点,咱们在持续交付上作了相对深刻的挖掘,实现了泳道环境、平滑发布和灰度发布。下面分别简单介绍下实现方式。

泳道环境——实现一个需求一个环境,在开发和测试中使用,互不影响

泳道环境,其实也叫需求环境,主要是服务于开发和测试同窗,容许他们为某个需求建立一个相对独立的环境。它的原理是,咱们会有一个相对稳定的环境,里面包含了全部的服务,这个称为主泳道。当某个需求提出时,改动只涉及到服务A和服务B,这个时候,咱们会基于这个需求分支建立服务A和服务B,做为泳道-01,而后结合主泳道其余泳道-01没有的服务,联动起来行成一个独立环境。

作泳道环境主要两个难点,一个是如何实现快速部署一堆的服务,另外一个是由于咱们的业务是基于Dubbo框架的,因此须要另外实现底层Dubbo服务按需路由。第一个点在有了Kubernetes以后,快速部署已经不是难事了,结合持续交付平台能够快速把咱们须要的全部服务一次性deploy到集群中。Dubbo服务路由方面,咱们利用了Dubbo的分组来实现的。最终实现后的效果以下:

平滑发布——对随时发布线上很是有用,能够大大提高迭代效率

平滑发布咱们利用了deployment的的滚动更新配合Pod的Liveness和Readness探针实现的。这里除了滚动更新的控制还须要注意两个点,一个是旧版本Pod必须确保收到SIGTERM信号后优先关闭监听端口从Endpoint列表中删除,另外一个是新版本Pod加入Endpoints列表前须要通过Liveness和Readness的检测。

灰度发布

之前要实现灰度发布,通常都要手动在发布的时候控制发布的节点,或者经过写一堆脚原本实现固定比例的灰度。这里,由于咱们的服务暴露方式用的是Ingress,因此直接利用Kubernetes的Service服务发现的能力来实现灰度发布。

使用Kubernetes过程当中遇到的一些问题

CPUset的使用,实现CPU独占性

总有部分应用在高峰期对CPU的要求比较高,可是CPU频繁的上下文切换会使当前应用的CPU使用没法获得保障,没法及时处理外部请求,致使客户端出现超时。而若是集群内服务调用没有加熔断机制的话,就有可能引起大量客户端线程池打满,进而引起雪崩效应。

这个时候,能够对应用进行横向扩容来缓解这种现象,但更好的方式,是使用CPUset。具体的使用方法就请你们自行查看Kubernetes相关文档啦。

注意:内存和CPU的limits和requests都必须相等。

Ingress Controller节点上的短链接问题

由于Ingress Controller是整个集群的流量入口,使用nodeSelector把Ingress Controller进行独立调度,只对外暴露这几台服务器做为流量入口。这里要特别注意客户端的短链接问题,由于短链接到达service所在服务器后,会再次向后端发起一次流量转发,不管是使用iptables实现的仍是IPVS的都同样,向后传递短链接后,外部一个短链接,到集群里就变成两个短链接了。因此要么增大nf_conntrack相关参数的容量,要么把短链接变成长链接,避免出现连接跟踪表溢出的问题。

使用podAntiAffinity的必要性

使用podAntiAffinity主要是为了不单点故障。由于即便在集群中部署了多个实例,若是全部实例都在一台服务器上,由于服务器故障或者某些缘由触发驱逐策略的时候,依旧会引起短时间的服务不可用。

将来的方向

两个方向吧,一个是平台化,另外一个是资源进行精细化调配。

先说平台化,由于目前绝大部分业务都已经容器化了,内部已经有了多个线上集群,急需一个集中的平台来把多个集群管起来、各个流程串起来。平台化的内容主要是监控、日志、发布和集群管理这些。资源的精细化调配方面,是由于目前咱们的调度策略主要仍是利用原生的调度策略,小部分利用CPUset作绑核操做。可是整个集群的内存利用率和CPU使用率并非在一个水平线上,这方面还有比较大的可压缩空间。

Q&A

Q:请问LNMP网站架构容器化上Kubernetes、Nginx和PHP,是各设Pod吧?MySQL采用一主多从架构?用什么作存储?
A:LNMP建议是Nginx和PHP放在同一个Pod中,而后外层再加一个Nginx,作Upstream。MySQL应用上Kubernetes要用StatefulSet。不过咱们目前内部这一块是尚未迁移到Kubernetes集群中的。

Q:Pod的滚动更新(优雅重启)怎么作的?
A:滚动更新Kubernetes的deployment中有相关的rollingUpdate策略,优雅停机有两个注意的点,一个是咱们要确保应用发的SIGTERM信号,另外一个是代码要确保收到SIGTERM信号后优先关闭端口或者取消服务注册。

Q:Harbor的使用版本?镜像的后端存储是什么?Harbor的部署形态?
A:Harbor使用版本这里不方便说。很差意思哈。镜像后端存储咱们目前用的是腾讯云的CFS,性能上目前够用。Harbor部署形态,我大概描述一下:ng/lb反向代理到后端Harbor,Harbor存储用腾讯云的CFS。

Q:除开Kubernetes自身的监控,容器内部服务监控是如何作的?pinpoint-agent嵌入到Container里面有没有须要优化的地方?
A:容器内部服务监控咱们是用Pinpoint作APM监控。pp-agent嵌入到Container里边有没有须要优化的地方,这个还好,由于咱们目前这一块都是作在基础镜像里边的,启动的时候加启动参数就好,步骤也挺简单的。

Q:请问前端是怎么暴露在外面的,SSL证书怎么才能作到自动签发?
A:前端静态资源暴露咱们有两种吧。一种是直接放在ng静态资源目录里边而后加上CDN,另一种是放在Kubernetes集群中,前面Nginx作反向代理,配上静态资源相关的缓存策略。SSL证书自动签发,Kubernetes集群内咱们目前用的是托管类型的,因此这一块未涉及。集群外其余SSL证书未作自动签发的证书。

Q:GitLab接收一个push event触发构建,这个是监控全部的分支吗,分支模型是怎么样的?
A:不是的,按需。咱们内部分支模型大概有四种,dev——>test——>release——>master。master之外的为了效率都会作自动触发。

Q:请问规模是?大概多少Node,会跨不少集群吗?
A:咱们内部的集群规模,生产集群数量是4个,不过是有大有小,是按业务来划分的。最大的一个集群是2700G内存,Node节点将近50个。Node节点数量要根据每一个节点配置来看,配置高,节点数量就少。

Q:为何不直接用GitLab-Runner而接Jenkins?
A:GitLab-Runner须要每一个仓库都配置构建信息,当须要统一修改构建的时候很麻烦。

Q:“Pod已实现与Node节点在同一网络层面,促进了咱们后面的快速落地。”这个是什么需求?
A:原生的Kubernetes集群跨集群调用网络上默认是不通的。

Q:请问Dubbo在转向Kubernetes或Istio网格化改造过程当中,传统环境与容器化环境共存互相调用时,是否遇到什么坑?如何化解的?
A:网段冲突吧。咱们曾经作过一段时间的Docker单机,可是当时没有配置Docker的网段,致使后面冲突的时候出现网络不通。解决方案:指定Docker单机的网段。

Q:在CD的过程当中 ,版本管理是怎么作的 ?是基于镜像的tag仍是Helm的版本?包括回滚的策略与方式?
A:用的是Helm的版本管理,回滚策略和方式都是用Helm的。

Q:HPA具体是咋作的,根据什么指标扩缩容的?集群升级咋作的?
A:HPA是根据CPU作的。集群升级是先升级Master再升级Node节点,这个仍是按照TKE的来作。

Q:Ingress Controller节点上的短链接问题,短链接变长链接这个是怎么处理的?能提示一下吗? A:这个不是指通Ingress Controller去作短链接变长链接,是说客户端发起的链接要用长链接的意思。

相关文章
相关标签/搜索