“中国-东盟信息港”是按照国家“一带一路”倡议总体布局要求、建设更为紧密的中国—东盟命运共同体、21世纪海上丝绸之路的一个信息平台:http://www.caih.com。东信基于Rancher Kubernetes架构和建设了他们的容器云PaaS平台,在云原生、容器化、微服务、CICD、DevOps等方面的都有了相关实践和应用。
6月28日,负责中国东信容器云PaaS 平台的研发和建设、中国-东盟信息港的研发总监王志雄出席了Rancher Labs举办的Container Day 2018容器技术大会,并做了题为《中国东信基于Kubernetes的容器云PaaS平台》的主题演讲,本文根据演讲内容整理而成。各位来宾,各位朋友,大家上午好,我是来自中国-东盟信息港的王志雄,在中国东信负责容器云PaaS 平台的研发和建设。今天我从技术角度、就如下四个方面,给大家分享中国东信基于Kubernetes建设容器云PaaS平台的经验。
第一个是PaaS平台,PaaS平台在云计算刚出现的时候就已经和IaaS、SaaS已经共存了,但是刚开始只是不温不火,为什么到这几年PaaS平台才这么火了呢?如何来建设一个PaaS台?PaaS平台需要哪些技术内容来承载?我会在这里做一个分享。
第二个是微服务,微服务我们说有两条路线,第一条是SpringCloud,第二条是Kubernetes,我们来看一看怎么使用Kubernetes来构建一个微服务的平台。
第三个是CICD ,第四个是DevOps。我们会看到有些场合说的CICD,有的场合说的DevOps,这二者有什么关系,有什么区别,如何来构建CICD 和DevOps,我会在这里做一个揭晓。
Kubernetes与容器云PaaS平台
我们首先来看一下Kubernetes与容器云平台。Kubernetes这个PaaS平台要解决三个方面的IT架构方面的问题。第一,耦合,我们做研发的知道,除了应用程序之外,不管Java,还是Go,还是Python,都需要大量的应用配置,这些配置和我们的系统环境——Windows也好,Linux也好——都是耦合的,所以会经常出现我们在交付产品的时候,明明在研发的环境可用的,到了测试不可用,到了最后的生产发布也不可用,从而出现这样的神秘的BUG、神秘的配置。之前有人提出一个比较好的方法是写一个很好的文档以供参考,但是文档通常还是会遗漏,而且这还要依赖于我们人员写文档的能力,以及理解的能力。第二个,繁杂,现在不论是技术、工具还是语言都非常繁杂,例如语言有Java、有Go、有Python、有PHP。第三个,不灵活,我们现在互联网时代是需要从按周发布,提升为按天发布,甚至一天几次、十几次甚至上百次发布,这在以前的物理机或者虚拟机时代是不可能的。
所以如何来解决这些问题?Cloud Native是这个答案。Cloud Native能做到什么呢?第一是容器化,把应用以及它的配置打包,保证开发、测试和运维的环境一致,从而避免神秘的配置、神秘的错误、神秘的文档、还有可能是神秘的人。第二是面向微服务,把以前的一体的区域式服务给分解为微服务,从而更灵活,并可以独立更新。第三方面是动态编排管理,如果容器很多,则需要大量的配置文件,需要部署很多容器则必然要用到编排管理,也就是我们在此选择的Kubernetes。
下图是中国东信基于Kubernetes、Docker研发的四大场景。第一是企业应用平台,企业应用平台可以将应用在平台上做到一键部署,利用pod auto-scaling进行弹性自动伸缩,如果出现故障则可以通过health check实现故障自愈,另外还有强大的灰度发布功能。之前的互联网公司可能需要一个非常大的团队来做灰度发布,如今使用Kubernetes,Kubernetes已经自带灰度发布功能了。第二个是我们的微服务,用Kubernetes来构建我们的微服务平台,构建之后我们就可以组件化、松耦合、去中心,而且是灵活独立的。第三个我们做了这样一套CICD的系统,CICD的系统从我们的开发、从代码提交、从编译到构建到自动化测试、到容器化发布。第四个是DevOps ,DevOps是可以做到开发运维的协同。
这是我们中国东信的PaaS 平台,我们从最底层看起,最底层是容器云的Infra,我们说Infra不是IaaS产品吗?其实不管是IaaS还是PaaS 都需要Infrastructure,当然它们是有区别的。我们不管做Iass做PaaS ,其中的难点归到最后其实都是存储和网络,我在后面会分享存储网络我们是怎么做的。再上来是容器资源管理,以及容器集群编排与调度,需要把这个Pod调度到众多集群节点中的哪一个?根据什么策略来调度?根据CPU调度还是根据内存调度?根据亲和策略还是反亲和策略?再上来是我们容器云应用Service,我们说PaaS 平台是以应用为中心,所以肯定需要这样一个强大的应用Service,PaaS平台应用的Service有服务发现、配置中心、负载均衡、弹性伸缩、服务编排这样一些强大的功能,那么就用我们的PaaS平台,上面我们会提供中间件、数据库、负载均衡、文件存储等等。如果需要哪一个,比如需要一个MySQL ,把一个MySQL容器拿过去用就可以了。再去用我们的中间件,PaaS平台上面就承载我们庞大的、灵活的企业应用。
如果研发过Kubernetes应该对这个图很熟悉,这是个典型的Kubernetes集群,我们分两个层面来看。第一个层面一个是我们自己内部的管理,部署Service,Service都是通过Master进行来管理,通过API Server来和各个组件进行交互,用Controller Mananger来控制我们各个组件获得的调度,Scheduler是具体的应用策略,etcd是一个数据库。那么会调度到我们的Node上,Node上存在我们的Pod ,一个Pod里可以有可以有多个Container,这是我们的内部的管理提供Service。第二个层面是我们从外部的访问,外部的访问一般就是通过Internet经过防火墙来访问我们对外提供一个ingress ,ingress是Kubernetes提供的一个非常强大的功能,有了ingress 之后,我们可以对外提供一个统一的域名系统,外部只要访问我们的统一域名,就可以访问我们内部的不同的应用,通过此域名就可以进行智能的分发。
上面我们说的叫物理架构,而下面我会讲讲逻辑架构,这两个的关注面不一样。逻辑架构从我们研发内部看,最底层是容器基础设施层,包括我们的Runtime、Volume Plugin、Network Plugin;再上来是核心层,核心层对外提供API,对内提供Plugin环境;第三层是应用层,可以进行部署,可以进行ingress智能路由;再上来是管理层,可以进行智能化以及Network policy;接口层是对外提供我们的命令行管理工具;Ecosystem是我们的生态。
刚才说PaaS的基础架构的终极难题是网络和存储。我们先来看一下中国东信是怎么解决网络问题的。网络的方案非常多,我们看到有单组区域的,开始是单组区域有bridge、host、container、NAT,也有原生的iptables;再上来有主机集群,有OVS,有IPSec;现在最主流的就是最上面一行,一个是Flannel,一个是calico,还有将这两个折在一起的Canal。这里我可以提一下我们的SDN(软件定义网络)。SDN起源于Openflow,什么是Openflow?Openflow是有强大的报文解析能力,可以对报文进行任意的更改,这个强大的能力刚问世时取得了瞩目的关注,并且在当年被评为未来10大创新技术的排名第二位,第一位是云计算,第二位是SDN。但最初Openflow在问世后的广大的应用中碰到了一些问题,因为它和以前传统的不兼容,所以实际上最后被应用最多的是VXLAN。VXLAN是一个overlay的技术。SDN在应用最多的是什么?是VXLAN overlay。第三个是BGP,BGP在网络中应该有二三十年的历史,经过不断地打磨、沉淀、优化,实际上BGP已经开始统一我们的SDN领域了,现在BGP已经可以取代我们的软件定义网络,虚拟化的网络。
SDN网络通用的两个方向,第一个是Flannel,Flannel其实本质上是一个Overlay的方案,所以在主机的容器内是自动分布的IP,只是在主机之外,做了一个Overlay叠加的封装,但这个Overlay和我们传统的IaaS的overlay相比其实是不一样的,传统的IaaS的VXLAN除了Overlay的功能,还有多租户的功能,但是这里因为它只在出口做了个封装,所以没有多租户的功能。所以Flannel有什么缺点?它没有安全隔离的功能。第二个它封包解包必然带来开销,所以这个是我们要解决的问题。Flannel官方也表示如果用户想对数据中心做更好的网络安全隔离,推荐用Calico。
Calico的核心是基于BGP,如果是小网络可以用BGP的client进行IP路由的自动分发以及路由互联。Calico的好处是什么?简单!若是使用Overlay网络出现故障,用户难以排查故障是来自overlay还是underlay;但用BGP,用户直接定位路由就好了。此外,Calico还带了一个很好的特性就是和network policy结合在一起,可以提供网络的微分段,若一个主机上有多个容器、有多个应用,可以提供很好的安全隔离。Calico的不足是什么?它需要取决于数据中心对于BGP的支持力度,可能现在还不是所有数据中心都是BGP。但我还是推荐BGP的,从最初的的Facebook到现在国内的大公司,很多都已经开使用BGP来取代所有的内部的路由协议,包括二层协议。这是一个很好的方案,可以简化运维工作,数据中心只有一种路由协议多好。
图片描述谈完网络,另一个难题就是存储。Kubernetes和Docker相比除了普通的volume之外,还提供了persistent volume和storage class,通过PV和PVC来抽象存储细节。这有什么好处?可以做到管理控制与转化分离。管理员关注PV的存储细节,用户只要关注PVC使用存储就好了。通用的存储ceph、NFS、Gluster都没问题。
容器云微服务
下面我们来看一下怎样用Kubernetes来构建一个微服务。下图是我们很熟悉的微服务架构的特性,把一个单体的应用来分解拆分为多个灵活的微服务。微服务的特性是服务的组件化。怎样拆分一个微服务?不是按代码的行数,不是按函数,而是按功能、按产品模式来拆分。有了微服务就可以去中心化的管理。
构建微服务,必然要有如下这些功能:有这么多的服务,怎样发现这个服务?所以要服务发现。多个服务如何做到负载均衡?多个应用service怎么样进行智能的路由分发?怎样管理成千上万个服务的配置?怎样弹性伸缩?怎样容错?怎样自动升级?访问控制怎么做?
下图就是我们使用Kubernetes来构建的微服务。怎样来构建?把上述问题的答案汇聚在一起就是最终答案了。第一个服务发现,使用我们的service,包括我们Kubernetes内置的DNS就可以来做这样一个服务发现。第二个负载均衡,有node上的kube-proxy加上我们的service分发是负载均衡。第三个智能路由,通过ingress可以智能地将不同的应用通过统一的入口分发到后端的服务。配置中心通过我们的Kubernetes的config-map,可以在一个统一的服务器上进行远端多个微服务的配置的统一管理、统一更新。明文用config-map,如果重要的机密的配置可以secret。
再接下来是我们的服务编排,deployment是实际使用过程中用户非常欢迎的一个特性。因为deployment把这个yaml文件写好之后,大家去自动部署了,需要几个副本,它会自动的去扩容以及缩容deployment。如果需要开发一个应用商店,可以去Helm开发。
再下来是我们的弹性伸缩,通过RS写好副本数,再通过auto-scaling指定需要自动伸缩的条件,比如说可以基于CPU伸缩,可以基于我们的内存访问伸缩。再下来是我们的容错,使用我们的liveness来监控我们的容器以及应用的健康状况,如果容器挂掉了,可以把它重启,如果这个节点挂掉了,那就把容器调度到另一个节点。熔断怎么做?可以用我们的readiness,readiness不但可以监控我们的容器的存活,还可以监控我们的service是否是健康的。
限流,限流可以通过我们的quota限额,可以通过我们的namespace限额,也可以对我们的pod限额,也可以对容器限额。
升级,rolling updates是自动升级,有问题可以一键回滚。那RBAC是可以提供基于角色的安全访问。Network policy在BGP Calico基础上提供微分段,可以很好的安全隔离,包括日志监控EFK和Prometheus。
容器云CI/CD
如何来做容器云的CI/CD,自然使用我们的容器云三剑客,Jenkins+Docker+Kubernetes。其实在容器云出现之前,其实已经有CI/CD了,那时CI/CD用Jenkins做,Jenkins可以提供编译、构件、测试、任务调度的流水线;那Docker有什么作用?可以让我们的环境标准化,可以隔离;Kubernetes可以提供一个大的平台,可以让资源共享、弹性伸缩。
图片描述CI/CD也就是需要把开发、测试流水线做一个自动化,从开发、编译、构件、测试、打包到部署,所以在我们的测试报告出来之后,如果是通过了就把镜像上传到镜像仓库,然后再发布到Kubernetes的发布平台。
DevOps
谈完CI/CD我们来看一下很火的DevOps。通过这张图我们其实就可以看出CI/CD和DevOps有什么区别,有什么联系,什么场合该用CI/CD,什么场合该用DevOps。CI/CD在左边,CI/CD最关注的是开发和测试,关注的具体的序数是什么?是Jenkins来做个流水线,是Git来做一个源代码的仓库、源代码的拉取,Maven来做构建,SonarQube来做静态的代码分析,Robotframework来做自动化的测试。SonarQube这样一个代码分析工具对我们的编译通过之外的一个保证把它良好的代码是有非常好的好处。因为我记得还是在十年前,当时在一个国内特大公司入职培训的时候,一般的导师对每位员工都会培训一个案例:代码规范。好的代码并不是通过编译就行了,而且需要好的编程规范,避免通过了编译但却其实会出现神秘的故障,而且很难定位。
看完CI/CD,我们来看看DevOps关注什么。DevOps的关注的是我们发布的环境要自动伸缩,要A/B Test,要灰度发布,要自动的升级,或者要滚动升级,滚动升级就是指不是一次性升级完所有的pod,还是可以选择性的升级一部分,比如升级20%,或者升级50%。有什么好处?可以使我们的应用服务不中断。它们两者的共同点,当然都需要基于Docker和Kubernetes来做这样的一个容器化封装和自动化。右边的这个DevOps其实是DevOps刚出现的时候,我们叫标准的DevOps。它和CI/CD有区别,但是其实有很大的联系,CI/CD和这样的标准DevOps组合起来就叫做我们的大DevOps,所以这两者是可以结合起来,CI/CD解决我们开发、测试、自动化、标准化的问题,标准DevOps解决我们的开发运维,主要是运维方面的问题,只有这两者结合起来就可以一键式解决我们的开发、测试、运维问题,并且可以形成一个闭环。
下图就是滚动升级这一功能,可以通过逐个容器替代,升级其中的25%的容器,然后再确认一下,如果工作正常,我们再可以升级其中的下一批容器。
下面是灰度发布。这在我们日新月异的频繁发布的互联网场景特别有用。因为我们有大量的互联网应用。所以有一个特别好的新功能,像看看它的这个功能,看看用户的反馈,用户的使用情况怎么样,我们的灰度发布。用Kubernetes的pod非常方便。开始可以给一个灰度版本1,内部用户使用的没问题,再给一个版本2,给我们的用户群,用户群A,再逐渐的扩大到所有的用户,这是互联网非常好的应用。
总结
这里来回顾一下中国东信基于Kubernetes开发的这样四大场景。第一个是PaaS企业应用平台。第二个是Kubernetes的微服务,SpringCloud也是微服务,但SpringCloud微服务是主要关注在应用层面,而且它只是针对Java有效,对别的语言是没有的。Kubernetes是语言无关的,而且是比SpringCloud使用面更广的,但最佳的实践是可以把我们的SpringCloud的每个微服务通过容器化的方式进行封装,再通过Kubernetes进行平台的集群资源调度和自动伸缩。第三个就是我们CICD,第四个是我们的DevOps。