京东从OpenStack切换到Kubernetes的经验之谈

NatishaPinc 8年前
   <h2>背景介绍</h2>    <p>2016年底,京东新一代容器引擎平台JDOS2.0上线,京东从OpenStack切换到Kubernetes。到目前为止,JDOS2.0集群2w+Pod稳定运行,业务按IDC分布分批迁移到新平台,目前已迁移20%,计划Q2全部切换到Kubernetes上,业务研发人员逐渐适应从基于自动部署上线切换到以镜像为中心的上线方式。JDOS2.0统一提供京东业务,大数据实时离线,机器学习(GPU)计算集群。从OpenStack切换到Kubernetes,这中间又有哪些经验值得借鉴呢?</p>    <p>本文将为读者介绍京东商城研发基础平台部如何从0到JDOS1.0再到JDOS2.0的发展历程和经验总结,主要包括:</p>    <ul>     <li>如何找准痛点作为基础平台系统业务切入点;</li>     <li>如何一边实践一边保持技术视野;</li>     <li>如何运维大规模容器平台;</li>     <li>如何把容器技术与软件定义数据中心结合。</li>    </ul>    <h2>集群建设历史</h2>    <h3>物理机时代(2004-2014)</h3>    <p>在2014年之前,公司的应用直接部署在物理机上。在物理机时代,应用上线从申请资源到最终分配物理机时间平均为一周。应用混合部署在一起,没有隔离的应用混部难免互相影响。为减少负面影响,在混部的比例平均每台物理机低于9个不同应用的Tomcat实例,因此造成了物理机资源浪费严重,而且调度极不灵活。物理机失效导致的应用实例迁移时间以小时计,自动化的弹性伸缩也难于实现。为提升应用部署效率,公司开发了诸如编译打包、自动部署、日志收集、资源监控等多个配套工具系统。</p>    <h3>容器化时代(2014-2016)</h3>    <p>2014年第三季度,公司首席架构师刘海锋带领基础平台团队对于集群建设进行重新设计规划,Docker容器是主要的选型方案。当时Docker虽然已经逐渐兴起,但是功能略显单薄,而且缺乏生产环境,特别是大规模生产环境的实践。团队对于Docker进行了反复测试,特别是进行了大规模长时间的压力和稳定性测试。根据测试结果,对于Docker进行了定制开发,修复了Device Mapper导致crash、Linux内核等问题,并增加了外挂盘限速、容量管理、镜像构建层级合并等功能。</p>    <p>对于容器的集群管理,团队选择了OpenStack+nova-docker的架构,用管理虚拟机的方式管理容器,并定义为京东第一代容器引擎平台JDOS1.0(JD DataCenter OS)。JDOS1.0的主要工作是实现了基础设施容器化,应用上线统一使用容器代替原来的物理机。在应用的运维方面,兼用了之前的配套工具系统。研发上线申请计算资源由之前的一周缩短到分钟级,不管是1台容器还是1千台容器,在经过计算资源池化后可实现秒级供应。同时,应用容器之间的资源使用也得到了有效的隔离,平均部署应用密度提升3倍,物理机使用率提升3倍,带来极大的经济收益。</p>    <p>我们采用多IDC部署方式,使用统一的全局API开放对接到上线系统,支撑业务跨IDC部署。单个OpenStack集群最大是1万台物理计算节点,最小是4K台计算节点,第一代容器引擎平台成功地支撑了2015和2016年的618和双十一的促销活动。至2016年11月,已经有15W+的容器在稳定运行。</p>    <p>在完成的第一代容器引擎落地实践中,团队推动了业务从物理机上迁移到容器中来。在JDOS1.0中,我们使用的IaaS的方式,即使用管理虚拟机的方式来管理容器,因此应用的部署仍然严重依赖于物理机时代的编译打包、自动部署等工具系统。但是JDOS1.0的实践是非常有意义的,其意义在于完成了业务应用的容器化,将容器的网络、存储都逐渐磨合成熟,而这些都为我们后面基于1.0的经验,开发一个全新的应用容器引擎打下了坚实的基础。</p>    <h2>新一代应用容器引擎(JDOS 2.0)</h2>    <h3>1.0的痛点</h3>    <p>JDOS1.0解决了应用容器化的问题,但是依然存在很多不足。</p>    <p>首先是编译打包、自动部署等工具脱胎于物理机时代,与容器的开箱即用理念格格不入,容器启动之后仍然需要配套工具系统为其分发配置、部署应用等等,应用启动的速度受到了制约。</p>    <p>其次,线上线下环境仍然存在不一致的情况,应用运行的操作环境,依赖的软件栈在线下自测时仍然需要进行单独搭建。线上线下环境不一致也造成了一些线上问题难于在线下复现,更无法达到镜像的“一次构建,随处运行”的理想状态。</p>    <p>再次,容器的体量太重,应用需要依赖工具系统进行部署,导致业务的迁移仍然需要工具系统人工运维去实现,难以在通用的平台层实现灵活的扩容缩容与高可用。</p>    <p>另外,容器的调度方式较为单一,只能简单根据物理机剩余资源是否满足要求来进行筛选调度,在提升应用的性能和平台的使用率方面存在天花板,无法做更进一步提升。</p>    <h3>平台架构</h3>    <p>鉴于以上不足,在当JDOS1.0从一千、两千的容器规模,逐渐增长到六万、十万的规模时,我们就已经启动了新一代容器引擎平台(JDOS 2.0)研发。JDOS 2.0的目标不仅仅是一个基础设施的管理平台,更是一个直面应用的容器引擎。JDOS 2.0在原1.0的基础上,围绕Kubernetes,整合了JDOS 1.0的存储、网络,打通了从源码到镜像,再到上线部署的CI/CD全流程,提供从日志、监控、排障、终端、编排等一站式的功能。JDOS 2.0的平台架构如下图所示。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/c851974432080ddb97d7f9de0fc994b0.png"></p>    <table align="center">     <tbody>      <tr>       <td> <p>功能</p> </td>       <td> <p>选型</p> </td>      </tr>      <tr>       <td> <p>容器工具</p> </td>       <td> <p>Docker</p> </td>      </tr>      <tr>       <td> <p>容器网络</p> </td>       <td> <p>Cane</p> </td>      </tr>      <tr>       <td> <p>容器引擎</p> </td>       <td> <p>Kubernetes</p> </td>      </tr>      <tr>       <td> <p>镜像中心</p> </td>       <td> <p>Harbor</p> </td>      </tr>      <tr>       <td> <p>持续集成工具</p> </td>       <td> <p>Jenkins</p> </td>      </tr>      <tr>       <td> <p>日志管理</p> </td>       <td> <p>Logstash + Elastic Search</p> </td>      </tr>      <tr>       <td> <p>监控管理</p> </td>       <td> <p>Prometheus</p> </td>      </tr>     </tbody>    </table>    <p>在JDOS 2.0中,我们定义了系统与应用两个级别。一个系统包含若干个应用,一个应用包含若干个提供相同服务的容器实例。一般来说,一个大的部门可以申请一个或者多个系统,系统级别直接对应于Kubernetes中的namespace,同一个系统下的所有容器实例会在同一个Kubernetes的namespace中。应用不仅仅提供了容器实例数量的管理,还包括版本管理、域名解析、负载均衡、配置文件等服务。</p>    <p>不仅仅是公司各个业务的应用,大部分的JDOS 2.0组件(Gitlab/Jenkins/Harbor/Logstash/Elastic Search/Prometheus)也实现了容器化,在Kubernetes平台上进行部署。</p>    <h3>开发者一站式解决方案</h3>    <p>JDOS 2.0实现了以镜像为核心的持续集成和持续部署。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/97f0e3075064c4cc5b7687b122fc5ad3.png"></p>    <ol>     <li>开发者提交代码到源码管理库</li>     <li>触发Jenkins Master生成构建任务</li>     <li>Jenkins Master使用Kubernetes生成Jenkins Slave Pod</li>     <li>Jenkins Slave拉取源码进行编译打包</li>     <li>将打包好的文件和Dockerfile发送到构建节点</li>     <li>在构建节点中构建生成镜像</li>     <li>将镜像推送到镜像中心Harbor</li>     <li>根据需要在不同环境生产/更新应用容器</li>    </ol>    <p>在JDOS 1.0,容器的镜像主要包含了操作系统和应用的运行时软件栈。APP的部署仍然依赖于以往运维的自动部署等工具。在2.0中,我们将应用的部署在镜像的构建过程中完成,镜像包含了APP在内的完整软件栈,真正实现了开箱即用。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/64dd50a691d71a42361eb4127219de00.png"></p>    <h3>网络与外部服务负载均衡</h3>    <p>JDOS 2.0继承了JDOS 1.0的方案,采用OpenStack-Neutron的VLAN模式,该方案实现了容器之间的高效通信,非常适合公司内部的集群环境。每个Pod占用Neutron中的一个port,拥有独立的IP。基于CNI标准,我们开发了新的项目Cane,用于将Kubelet和Neutron集成起来。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/284f77f426f80b39a03894395f280f71.png"></p>    <p>同时,Cane负责Kubernetes中service中的LoadBalancer的创建。当有LoadBalancer类型的service创建/删除/修改时,Cane将对应的调用Neutron中创建/删除/修改LBaaS的服务接口,从而实现外部服务负载均衡的管理。另外,Cane项目中的Hades( <a href="/misc/goto?guid=4959738996219279314" rel="nofollow,noindex">https://github.com/ipdcode/hades</a> 京东开源在GitHub上)组件为容器提供了内部的DNS解析服务。</p>    <h3>灵活调度</h3>    <p>JDOS 2.0接入了包括大数据、Web应用、深度学习等多种类型的应用,并为每种应用根据类型采用了不同的资源限制方式,并打上了Kubernetes的不同标签。基于多样的标签,我们实现了更为多样和灵活的调度方式,并在部分IDC实验性地混合部署了在线任务和离线任务。相较于1.0,整体资源利用率提升了约30%。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/3ad58d9e064c377ec4f8bed1188e399a.png"></p>    <h3>推广与展望</h3>    <p>有了1.0的大规模稳定运营作为基础,业务对于使用容器已经给予了相当的信任和支持,但是平台化的容器和基础设施化的容器对于应用的要求也不尽相同。比如,平台化的应用容器IP并不是固定的,因为当一个容器失效,平台会自动启动另一个容器来替代,新的容器IP可能与原IP不同。这就要求服务发现不能再以容器IP作为主要标识,而是需要采用域名,负载均衡或者服务自注册等方式。因此,在JDOS2.0推广过程中,我们也推动了业务方主要关注应用服务,减少对单个容器等细节的操作,以此自研了全新智能域名解析服务和基于DPDK高性能负载均衡服务,与Kubernetes有效地配合支持。</p>    <p>近两年,随着大数据、人工智能等研发规模的扩大,消耗的计算资源也随之增大。因此,我们将大数据、深度学习等离线计算服务也迁移进入JDOS2.0。目前是主要采用单独划分区域的方式,各自的服务仍然使用相对独立的计算资源,但是已经纳入JDOS2.0平台进行统一管理,并通过机器学习方法,提升计算资源使用效率。</p>    <p>灵活的标签给予了集群调度无限的可能。未来我们将丰富调度算法,并配以节能的相关技术,提高集群整体的ROI,从而为打造一个低能耗、高性能的绿色数据中心打下基础。</p>    <h2>回望与总结</h2>    <p>Kubernetes方案与OpenStack方案相比,架构更为简洁。OpenStack整体运营成本较高,因为牵涉多个项目,每个项目各自有多个不同的组件,组件之间通过RPC(一般使用MQ)进行通讯。为提高可用性和性能,还需要考虑各个组件的扩展和备份等。这些都加剧了整体方案的复杂性,问题的排查和定位难度也相应提升,对于运维人员的要求也相应提高。</p>    <p>与之相比,Kubernetes的组件较少,功能清晰。其核心理念(对于资源和任务的理解)、灵活的设计(标签)和声明式的API是对Google多年来Borg系统的最好总结,而其提供的丰富的功能,使得我们可以投入更多精力在平台的整个生态上,比如网络性能的提升、容器的精准调度上,而不是平台本身。尤其是,副本控制的功能受到了业务线上应用运维工程师的追捧,应用的扩容缩容和高可用实现了秒级完成。JDOS 2.0目前已经接入了约20%的应用,部署有2个集群,目前日常运行的容器有20000个,仍在逐步推广中。</p>    <p>真诚感谢Kubernetes社区和相关开源项目的贡献者,目前京东已经加入CNCF组织,并在社区排名达到TOP30。</p>    <h2> </h2>    <p>来自:http://www.infoq.com/cn/articles/jingdong-from-openstack-to-kubernetes</p>    <p> </p>