本文发布已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已不再准确。

京东从 OpenStack 转向 Kubernetes 的内部故事

编者按:今天的文章由京东基础设施平台部团队撰写,内容关于他们从 OpenStack 转向 Kubernetes 的历程。京东是中国最大的公司之一,也是首家登上《财富》全球 500 强榜单的中国互联网公司。

集群构建历史

物理机时代 (2004-2014)

2014 年之前,我们公司的应用全部部署在物理机上。在物理机时代,应用上线申请资源平均需要等待一周。由于缺乏隔离性,应用之间会相互影响,导致很多潜在风险。那时,每台物理机上的 tomcat 实例平均不超过 9 个。物理机资源严重浪费,调度不灵活。由于物理机故障,应用迁移需要数小时。并且无法实现自动伸缩。为了提高应用部署效率,我们开发了编译打包、自动化部署、日志收集、资源监控等系统。

容器化时代 (2014-2016)

由京东首席架构师刘海峰领导的基础设施平台部 (IPD) 在 2014 年秋天寻找新的解决方案。Docker 进入了我们的视野。那时,docker 刚刚兴起,尚显稚嫩,缺乏在生产环境的应用经验。我们对 docker 进行了反复测试。此外,我们还定制了 docker 来修复一些问题,例如 device mapper 导致的系统崩溃和一些 Linux 内核 bug。我们还在 docker 中添加了许多新特性,包括磁盘限速、容量管理、镜像构建中的分层合并等等。

为了恰当地管理容器集群,我们选择了 OpenStack + Novadocker 驱动的架构。容器被作为虚拟机来管理。这被称为第一代京东容器引擎平台——JDOS1.0 (JD Datacenter Operating System)。JDOS 1.0 的主要目的是基础设施容器化。自那时起,所有应用都在容器而非物理机中运行。至于应用的运维,我们充分利用了现有工具。开发者在生产环境中申请计算资源的时间从一周缩短到几分钟。计算资源池化后,即使伸缩 1,000 个容器也能在几秒内完成。应用实例彼此隔离。应用平均部署密度和物理机利用率都提高了三倍,带来了巨大的经济效益。

我们在每个数据中心 (IDC) 部署了集群,并提供统一的全局 API 来支持跨数据中心的部署。在我们的生产环境中,单个 OpenStack 分布式容器集群最多有 10,000 个计算节点,最少有 4,000 个。第一代容器引擎平台 (JDOS 1.0) 成功支撑了 2015 年和 2016 年的“6.18”和“11.11”促销活动。到 2016 年 11 月,线上运行的容器数量已达 150,000 个。

“6.18”和“11.11”是京东最受欢迎的两次线上促销活动,类似于黑色星期五促销。2016 年 11 月 11 日完成的订单量达到 3000 万单。 

在 JDOS 1.0 的开发和推广实践中,应用直接从物理机迁移到容器。本质上,JDOS 1.0 是 IaaS 的一种实现。因此,应用的部署仍然严重依赖编译打包和自动化部署工具。然而,JDOS1.0 的实践非常有意义。首先,我们成功地将业务迁移到了容器中。其次,我们对容器网络和存储有了深入的理解,并知道如何将其打磨到最佳状态。最后,所有的经验为我们开发全新的应用容器平台奠定了坚实的基础。

新一代容器引擎平台 (JDOS 2.0)

平台架构

当 JDOS 1.0 从 2,000 个容器增长到 100,000 个时,我们启动了新一代容器引擎平台 (JDOS 2.0)。JDOS 2.0 的目标不仅仅是一个基础设施管理平台,更是一个面向应用的容器引擎平台。在 JDOS 1.0 和 Kubernetes 的基础上,JDOS 2.0 集成了 JDOS 1.0 的存储和网络,打通了从源码到镜像再到部署的 CI/CD 流程。此外,JDOS 2.0 还提供日志、监控、故障排查、终端和编排等一站式服务。JDOS 2.0 的平台架构如下图所示。

D:\\百度云同步盘\\徐新坤-新人培训计划\\docker\\MAE\\分享\\arc.png

功能产品
源码管理Gitlab
容器工具Docker
容器网络Cane
容器引擎Kubernetes
镜像仓库Harbor
CI 工具Jenkins
日志管理Logstash + Elastic Search
监控Prometheus

在 JDOS 2.0 中,我们定义了系统和应用两个级别。一个系统由多个应用组成,一个应用由多个提供相同服务的 Pod 组成。通常,一个部门可以申请一个或多个系统,这直接对应于 Kubernetes 的 Namespace。这意味着同一系统的 Pod 将位于同一 Namespace 下。

JDOS 2.0 的大部分组件 (GitLab / Jenkins / Harbor / Logstash / Elastic Search / Prometheus) 也都容器化并部署在 Kubernetes 平台上。

一站式解决方案

D:\\百度云同步盘\\徐新坤-新人培训计划\\docker\\MAE\\分享\\cicd.png

  1. 1. JDOS 2.0 以 docker 镜像为核心实现持续集成和持续部署。
  2. 2. 开发者将代码推送到 git。
  3. 3. Git 触发 jenkins master 生成构建任务。
  4. 4. Jenkins master 调用 Kubernetes 创建 jenkins slave Pod。
  5. 5. Jenkins slave 拉取源码,进行编译打包。
  6. 6. Jenkins slave 将打包后的文件和 Dockerfile 发送给具备 docker 环境的镜像构建节点。
  7. 7. 镜像构建节点构建镜像。
  8. 8. 镜像构建节点将镜像推送到镜像仓库 Harbor。
  9. 9. 用户在不同区域创建或更新应用 Pod。

JDOS 1.0 中的 docker 镜像主要包含操作系统和应用运行时软件栈。因此,应用的部署仍然依赖于自动化部署等工具。而在 JDOS 2.0 中,应用部署是在镜像构建过程中完成的。镜像包含完整的软件栈,包括应用本身。通过这种方式,我们可以在任何环境中实现应用按设计运行的目标。

D:\\百度云同步盘\\徐新坤-新人培训计划\\docker\\MAE\\分享\\image.png

网络与外部服务负载均衡

JDOS 2.0 沿用了 JDOS 1.0 的网络方案,该方案基于 OpenStack Neutron 的 VLAN 模型实现。这个方案实现了容器间的高效通信,非常适合公司内部的集群环境。每个 Pod 在 Neutron 中占用一个端口,并拥有独立的 IP。基于容器网络接口 (CNI) 标准,我们开发了一个新项目 Cane,用于集成 kubelet 和 Neutron。

D:\\百度云同步盘\\徐新坤-新人培训计划\\docker\\MAE\\分享\\network.png

同时,Cane 还负责 Kubernetes service 中 LoadBalancer 的管理。当创建/删除/修改 LoadBalancer 时,Cane 会调用 Neutron 中 lbaas 服务的创建/删除/修改接口。此外,Cane 项目中的 Hades 组件为 Pod 提供了内部 DNS 解析服务。

Cane 项目的源代码目前正在整理完善中,即将发布到 GitHub。

灵活调度

D:\\百度云同步盘\\徐新坤-新人培训计划\\docker\\MAE\\分享\\schedule.pngJDOS 2.0 支持接入大数据、Web 应用、深度学习等多种类型的应用,并采取更灵活多样的调度方式。在一些数据中心 (IDC) 中,我们尝试了在线任务和离线任务的混合部署。相比 JDOS 1.0,整体资源利用率提升了约 30%。

总结

Kubernetes 丰富的功能特性使我们可以更专注于平台生态系统的整体优化,例如网络性能,而不是平台本身。特别是,SREs 高度赞赏副本控制器 (Replication Controller) 的功能。借助它,应用的伸缩可以在几秒内完成。JDOS 2.0 目前已接入约 20% 的应用,并部署了 2 个集群,日均运行约 20,000 个 Pod。我们计划接入公司更多应用,逐步替换现有的 JDOS 1.0。我们也乐于将在此过程中的经验与社区分享。

感谢 Kubernetes 及其他开源项目的所有贡献者。

——京东基础设施平台部团队