专栏名称: InfoQ
有内容的技术社区媒体。
目录
相关文章推荐
IT之家  ·  华为Mate 70,定档! ·  4 天前  
新浪科技  ·  【#新兴业态情绪消费要如何规范# ... ·  5 天前  
51好读  ›  专栏  ›  InfoQ

Kubernetes在企业中的场景运⽤及管理实践

InfoQ  · 公众号  · 科技媒体  · 2016-09-25 08:07

正文

本文根据时速云CTO王磊在InfoQ全球容器技术大会上的演讲内容整理而成。


1
为什么企业需要私有PaaS平台?

企业选择私有PaaS平台部署的四大原因:


第一,Hybrid cloud(混合云)。企业希望通过一个控制面板,就可以管理部署在私有数据中心和公有云上的所有应用;而基于容器的PaaS平台可以很好的对底层资源进行抽象,并简化应用的迁移。同时,企业也希望定义一些部署策略,这样可以保证应用在生命周期的不同阶段都能部署到不同的基础设施上。

第二,现有的和新的应用实现云化。将已有应用、要新开发的应用打造成云原生应用,发挥云平台的可扩展、弹性、高可用等特性,并借助PaaS层提供的API实现更高级的特性,比如自动恢复、定制化的弹性伸缩等。

第三,私有云计划。一些传统企业都有一些云的规划,比如公有云和私有云的混合部署,而私有云是其中非常重要的一个部分,企业希望利用私有PaaS平台实现DevOps的诉求,减少开发和内部IT部门之间的摩擦。

第四,微服务架构和API管理。现在很多企业在进行服务拆分,来抽象不同系统的权限控制和任务,以方便业务开发人员通过服务组合快速的创建企业应用。有的企业在没有对应的管理平台之前就已经将应用拆分成很多服务,而如何部署这些微服务和进行API权限控制,则成了需要解决的问题,而PaaS则是理想的选择。

再来看一下企业用户在部署私有PaaS平台时,主要关注哪些点?有哪些具体要求?


第一点,易部署和易管理性。PaaS 作为企业广泛采用的方案,IT部门考虑的主要因素是部署简单、平台管理的学习成本等问题(部署工具、调试方法等)。传统IT已经在基础设施上进行了很大的投入,如果平台能够利用、集成已有系统,比如负载均衡、网络设备、已有工单、资产管理等系统,会为企业节省很多成本,并更容易融入到企业IT的开发流程中。

第二点,数据层的分离问题。一些用户担心跟特定的PaaS平台绑定起来,而绑定一般有两种可能因素:一个是应用架构的绑定,对用户应用开发层面的限制。现在基于容器技术的PaaS平台,用户去做定制化的一些能力就比传统的PaaS平台好很多,这个层面的绑定风险就会很小。

另一个是数据层的绑定,这需要PaaS平台设计时就要考虑和数据层的松耦合,在企业里已经有了某些商业的存储,或者对某些开源存储有支撑能力,我们就同用户协商,选择风险最小、最适合用户,并能够同容器技术相结合的存储方式。

第三点,与遗留系统集成。有的企业说,我的企业里有比较复杂的组织架构和权限划分,你不可能说用了PaaS平台之后,成员可以减少几个。开始阶段,平台要在一定程度上去适应用户的组织架构和权限划分,所以用户提出要求说,传统的角色划分在你的平台上怎么去体现。另外有很多已有的硬件或者软件,比如原来的负载均衡,物理的防火墙设备等怎么和PaaS平台集成,一些工单、资产管理等原有系统怎么集成,都是用户关心的问题。

第四点,扩展能力。随着微服务的流行,我们慢慢进入了一个充满服务的世界,应用的开发慢慢向可组装的方向发展,这就对平台的扩展性有很高的要求。只有架构比较开放的平台才能更好的提供构建可组装应用所需要的扩展性。

第五,要有标准化的迁移策略,PaaS 需要考虑应用的可移植性,而容器逐渐成为保证应用可移植性的标准方式,未来随着OCI标准的完善,基于容器技术的PaaS平台在迁移性方面还是不错的。


2
企业部署私有PaaS平台有哪些方式?

了解了企业部署私有PaaS的主要原因及需求,那么接下来就进入架构、技术层面的相关细节,如存储、网络,CI/CD以及监控报警等主要方面。


Network – Flannel

原来基本很多大企业,在不同的zone里面会有三层架构,而且每个层里面的机器可能并不是太多,它为了简化管理,也不需要在每一层都去部署一个Kubernetes集群。平台组件之间通过哪些端口通信,就需要在防火墙上做对应的配置,这就要求我们清楚的知道系统中端口使用情况。

比如2379、2380是ETCD的,443是 apiserver的,8285/8742是flannel的。但是大家能够想到这里边有什么不符合企业规范的要求吗?如果把8285/8742端口打开以后,集群内部所有服务就可以通过flannel直接进行通信,相当于中间的防火墙失去作用了,这种实施就不符合企业规范了,但是能够满足一定场景下的需求。


Network - Docker Bridge

我们再看第二种方式,这种方式也是Kubernetes 支持的,在容器层面其实就是docker的默认网络模式。可以隔离同一主机的容器访问,通过自定义的代理,可以实现内网、或者外部访问的负载均衡。当然,如果考虑性能、不担心同一个节点的网络隔离的话,也可以使用host默认。在防火墙上打开代理的ip及服务端口即可。

Network - Calico

Kubernetes支持很多满足要求的网络工具,Calico也是其中一种。在这种网络模式下,我们可以控制服务之间的访问,粒度可以到端口层面,其ACL的控制能力相当于原来的防火墙。通过SDN本身的一些能力解决防火墙的问题,当然可以起到类似的效果。

但是如果你推到企业里,他们就担心运维出了问题之后是不是还得找我们,因为Calico还是一个比较新的东西,在修改规则时,难免碰到一些技术问题。所以,企业希望提供对应的可视化管理工具,使运维人员更容易理解、管理基于软件的网络控制。


Storage

再看存储,存储跟我们前面说的数据层绑定有一些关系,大家看这个列表就会发现, Kubernetes支持的商业存储很少,比如企业买了EMC或者IBM的存储设备,当然希望把这些存储和PaaS平台进行集成。一是商业存储比开源存储方案用户更放心,维护成本也更低;二是可以更好的利用现有资源,减少新的存储带来的成本。


在Kubernetes的存储设计上体现了的很好扩展能力,我们来看一下如何为Kubernetes添加自己的存储驱动。首先我们需要注册自己的代码插件,来声明支持某种类型的存储;然后按照特定的接口,实现其中的具体方法,比如初始化时的动作、当前环境是否支持、服务创建/删除时对应的动作等;最后修改API的声明,使其支持对应标签的存储声明。

这样,在我们创建一个Pod时,当其分配到某个节点,就会在初始化、启动和删除时执行对应的动作,用来支持不同的存储类型。

CI/CD

下图就是一个典型的DevOps流程,基于我们产品本身提供的CI/CD 服务可以实现整个流程的自动化。第一步,开发人员在GIT或者SVN上的代码提交会触发该流程,根据关联规则,会对某一分支的代码进行静态分析及测试覆盖率的检查,并将结果发送到SonarQube中,Team Lead或项目管理人员可以通过SonarQube查看代码质量和覆盖率情况。

第一步完成后根据配置会自动触发第二步,这里把第二步和第三步分开,大家想想为什么?大家在实施时有没有这种类似的方案?因为编译环节会包含很多依赖包、相关工具等,但这些并不是最后运行时环境所需要的,所以运行时的环境和你的编译环境会有较大的差别。

在第二步对应的编译镜像中将最终产出物,可能是war包或者二进制文件,分享给下面一个步骤(平台提供在不同CI步骤中进行文件共享的能力),那么第三步只需要基于运行时环境,并添加对应的war包就可以生成最终需要的应用版本了,镜像的大小也会小很多。

这个流程在我们平台可以很快的完成,如果用户已经有了基于Jenkins等工具的CI流程,那么可以直接对接我们的API,完成后续的部署流程。


前面的CI完成后,会先push到开发测试的镜像仓库中,可以看到我们建议把开发测试和产品的仓库进行分离,避免开发测试的频繁更新对镜像仓库的影响给产品仓库带来麻烦,也方便对开发测试的镜像仓库进行定期清理。Push到开发测试仓库后,会触发 CD的规则,对应的开发、测试环境就会被自动更新。

在上线之前需要有一个审批环节,如果你的镜像真的符合了测试标准,相关负责人同意了上线请求,则会开始线上环境的更新流程。

这里面有一个同步服务,会把指定的镜像版本同步到产品的镜像仓库中,进而触发线上服务的灰度升级。应用开发人员可以通过User Portal查看服务状态、日志、监控等信息,企业的运维人员可以通过Admin Console管理平台进行应用的运维、管理和监控。


这里看一下前三步的产出物,第一,把代码分析结果和UT测试结果推送到SonarQube上去,管理人员可以通过UI来看代码质量是不是下降了,测试的代码覆盖率够不够高;第二,编译生成所需要的war包;第三步就非常简单,把war包添加到运行时镜像的一个特定目录中。

Application Package and Deployment

刚才说了一下CI/CD的方案,现在我们看一下应用打包、部署方式。应用可能会涉及到多个容器、多个镜像的问题,打包的话会有不同的打包方式。在企业里,基础运行环境一般由运维人员提供,这样运维人员可以非常的清楚知道运行时环境的详细情况,在更新、升级时也比较容易管控。

下图中可以看到一般的应用打包方式和基于Pod编排的打包方式的区别,既可以减少构建次数和应用版本的数量,又可以提高应用发布时候的灵活性。从Kubernetes 1.3开始,可以把应用镜像定义为 init container,运行时环境为 app container,这样就很容易实现基于编排的应用发布。目前在企业里,根据接受程度,这两种方式都有应用场景。


在下图中我们看到采用Pod编排后的示例,主要区别在第三步,只需要基于200多k的busybox构建镜像即可。


Configuration Management

再来看一下配置管理,主要有三个作用:第一,可以把我的应用镜像和配置信息分离开来,做到应用配置的灵活修改;第二,支持通过环境变量、命令行参数或者volume的方式传递配置;第三,在配置信息更新时,同步到关联的所有应用节点上。

假如一个配置信息有100个应用节点对其进行了引用,当该配置更新后,会很快同步到这100个节点上。而何时重新加载这些配置文件,是需要应用层面去解决的问题,那就需要应用实现对应的watch机制,发现有更新后重新加载配置文件,并刷新内存中的配置信息。


Secret Data

下面这张图是Kubernetes对敏感信息的处理方式,主要有三种模式,最上边就是服务之间做交互时,我可能需要拿到另外一个服务的密码才能访问到另外一个服务,这就涉及到敏感信息的传送,可以通过Secret 来进行配置。

图的左边,在Kubernetes的每个namespace上会有一个ServiceAccount,通过它来控制一些访问权限,比如对API server的读写控制等。

图的右下角,对于私有仓库的访问,通过secret对象在不同的用户层面进行管控,使一个namespace只能访问通过secret授权的镜像。也可以在ServiceAccout 中创建对应的secret,这样避免了每次创建Pod时都要传入镜像仓库的访问信息,是一种推荐的配置方法。



3
企业私有SaaS平台该如何管理?

前面讲了一些企业比较关心的PaaS平台上的需求,那么如果企业真的去部署这样一个基于Kubernetes的PaaS平台,该怎么管理呢?

第一,要有很好的监控和报警机制。如果你本身的PaaS平台是多集群管理的话,你可能需要很多维度的监控报警,比如要监控平台本身、Kubernetes集群、 node节点、应用等各个维度的资源对象,也会涉及到 CPU、Memory、Disk、QPS等具体监控参数,也包括在这些维度和参数上的报警设置。

在某些情况下,一些原生的解决方案并不能提供很多一些必要的监控功能,这里介绍一个Node Problem Detector的工具,可以通过这个工具实现一些在节点上的自定义监控规则,比如进程死锁、OOM、Panic等错误,并把错误事件通过apiserver更新到Node的NodeCondition 或者 Event上。


第二,对于运维,需要对应的管理、调试工具。使用过Kubernetes的开发运维人员,会非常熟悉下图左边的kubectl工具,在我们的运维工作里面,能够满足大部分的调试需求,定位到服务的各种问题,但这个工具知识集群内部的管理工具。

而右边的KOPS可以在集外的维度进行操作,比如在AWS上通过一条命令创建一个适合产品环境的Kubernetes集群,以及更新集群的信息、删除集群等,如果多集群管理的时候,也可以帮大家快速解决一些相应的问题。


最后,是关于Kubernetes的升级。在开源组件快速发展的今天,尤其是异常活跃的Kubernetes社区,版本的升级是必不可少的环节。而且作为一个PaaS平台,升级中出现什么问题,造成的影响将是相当大的。

我们是从0.16的版本开始使用的,去年6月的公有云是基于0.17版本,从0.17逐步升级到现在的1.3版本。先来看一下Kubernetes的版本定义,版本号X.Y.Z,X是majar版本号,Y是minor,Z是patch,API版本一般按照 vXbetaY 的命名方式。

升级的时候,官方支持同一个major版本的rolling upgrade,也就是先升级master节点,在逐个升级node节点。

注意,官方这种方式,并不是在有服务运行的节点上直接升级,仍然是推荐先运行 kubectl drain 将该节点的服务驱赶走,然后再进行系统维护、升级,最后再把节点重新加入到集群中,如果直接对节点组件进行升级,有可能会对节点上的服务造成影响,社区也在改善这种不太合理的升级方式。


在升级上,推荐在升级到某一个大版本之前,小版本尽量跟随社区升级到最新patch版本。 

另外,跨超过两个minor版本以上的升级,比如从1.3升级到1.5,官方并不建议,你可以先升级到最新的版本,然后再升到下一个版本上。在我们从0.17到1.X的时候也不能直接升级,API发生了不兼容的改变,如果直接升级就会抛出很多错误,集群就会进入异常状态,运行的服务就会受到影响,所以要先升级到中间的一个版本。

0.19这个版本能同时支持0.17和1.x 的数据格式,在这个版本上运行一个升级命令,就可以把所有资源的API号和不兼容的对象进行转换,再从0.19升级到1.0,就可以平滑过渡了。    


喜欢我们的会点赞,爱我们的会分享!