分类 Docker 下的文章

京东从2016年底启动从OpenStack切换到Kubernetes的工作,截止目前(2017年2月)已迁移完成20%,预计Q2可以完成全部切换工作。Kubernetes方案与OpenStack方案相比,架构更为简洁。在这个过程中,有这些经验可供业界借鉴。

背景介绍

2016年底,京东新一代容器引擎平台JDOS2.0上线,京东从OpenStack切换到Kubernetes。到目前为止,JDOS2.0集群2w+Pod稳定运行,业务按IDC分布分批迁移到新平台,目前已迁移20%,计划Q2全部切换到Kubernetes上,业务研发人员逐渐适应从基于自动部署上线切换到以镜像为中心的上线方式。JDOS2.0统一提供京东业务,大数据实时离线,机器学习(GPU)计算集群。从OpenStack切换到Kubernetes,这中间又有哪些经验值得借鉴呢?

本文将为读者介绍京东商城研发基础平台部如何从0到JDOS1.0再到JDOS2.0的发展历程和经验总结,主要包括:

  • 如何找准痛点作为基础平台系统业务切入点;

  • 如何一边实践一边保持技术视野;

  • 如何运维大规模容器平台;

  • 如何把容器技术与软件定义数据中心结合。

集群建设历史

物理机时代(2004-2014)

在2014年之前,公司的应用直接部署在物理机上。在物理机时代,应用上线从申请资源到最终分配物理机时间平均为一周。应用混合部署在一起,没有隔离的应用混部难免互相影响。为减少负面影响,在混部的比例平均每台物理机低于9个不同应用的Tomcat实例,因此造成了物理机资源浪费严重,而且调度极不灵活。物理机失效导致的应用实例迁移时间以小时计,自动化的弹性伸缩也难于实现。为提升应用部署效率,公司开发了诸如编译打包、自动部署、日志收集、资源监控等多个配套工具系统。

容器化时代(2014-2016)

2014年第三季度,公司首席架构师刘海锋带领基础平台团队对于集群建设进行重新设计规划,Docker容器是主要的选型方案。当时Docker虽然已经逐渐兴起,但是功能略显单薄,而且缺乏生产环境,特别是大规模生产环境的实践。团队对于Docker进行了反复测试,特别是进行了大规模长时间的压力和稳定性测试。根据测试结果,对于Docker进行了定制开发,修复了Device Mapper导致crash、Linux内核等问题,并增加了外挂盘限速、容量管理、镜像构建层级合并等功能。

对于容器的集群管理,团队选择了OpenStack+nova-docker的架构,用管理虚拟机的方式管理容器,并定义为京东第一代容器引擎平台JDOS1.0(JD DataCenter OS)。JDOS1.0的主要工作是实现了基础设施容器化,应用上线统一使用容器代替原来的物理机。

在应用的运维方面,兼用了之前的配套工具系统。研发上线申请计算资源由之前的一周缩短到分钟级,不管是1台容器还是1千台容器,在经过计算资源池化后可实现秒级供应。同时,应用容器之间的资源使用也得到了有效的隔离,平均部署应用密度提升3倍,物理机使用率提升3倍,带来极大的经济收益。

我们采用多IDC部署方式,使用统一的全局API开放对接到上线系统,支撑业务跨IDC部署。单个OpenStack集群最大是1万台物理计算节点,最小是4K台计算节点,第一代容器引擎平台成功地支撑了2015和2016年的618和双十一的促销活动。至2016年11月,已经有15W+的容器在稳定运行。

在完成的第一代容器引擎落地实践中,团队推动了业务从物理机上迁移到容器中来。在JDOS1.0中,我们使用的IaaS的方式,即使用管理虚拟机的方式来管理容器,因此应用的部署仍然严重依赖于物理机时代的编译打包、自动部署等工具系统。但是JDOS1.0的实践是非常有意义的,其意义在于完成了业务应用的容器化,将容器的网络、存储都逐渐磨合成熟,而这些都为我们后面基于1.0的经验,开发一个全新的应用容器引擎打下了坚实的基础。

新一代应用容器引擎(JDOS 2.0)

1.0的痛点

JDOS1.0解决了应用容器化的问题,但是依然存在很多不足。

首先是编译打包、自动部署等工具脱胎于物理机时代,与容器的开箱即用理念格格不入,容器启动之后仍然需要配套工具系统为其分发配置、部署应用等等,应用启动的速度受到了制约。

其次,线上线下环境仍然存在不一致的情况,应用运行的操作环境,依赖的软件栈在线下自测时仍然需要进行单独搭建。线上线下环境不一致也造成了一些线上问题难于在线下复现,更无法达到镜像的“一次构建,随处运行”的理想状态。

再次,容器的体量太重,应用需要依赖工具系统进行部署,导致业务的迁移仍然需要工具系统人工运维去实现,难以在通用的平台层实现灵活的扩容缩容与高可用。

另外,容器的调度方式较为单一,只能简单根据物理机剩余资源是否满足要求来进行筛选调度,在提升应用的性能和平台的使用率方面存在天花板,无法做更进一步提升。

平台架构

鉴于以上不足,在当JDOS1.0从一千、两千的容器规模,逐渐增长到六万、十万的规模时,我们就已经启动了新一代容器引擎平台(JDOS 2.0)研发。JDOS 2.0的目标不仅仅是一个基础设施的管理平台,更是一个直面应用的容器引擎。JDOS 2.0在原1.0的基础上,围绕Kubernetes,整合了JDOS 1.0的存储、网络,打通了从源码到镜像,再到上线部署的CI/CD全流程,提供从日志、监控、排障、终端、编排等一站式的功能。JDOS 2.0的平台架构如下图所示。

jd_arch

jd_feature

在JDOS 2.0中,我们定义了系统与应用两个级别。一个系统包含若干个应用,一个应用包含若干个提供相同服务的容器实例。一般来说,一个大的部门可以申请一个或者多个系统,系统级别直接对应于Kubernetes中的namespace,同一个系统下的所有容器实例会在同一个Kubernetes的namespace中。应用不仅仅提供了容器实例数量的管理,还包括版本管理、域名解析、负载均衡、配置文件等服务。

不仅仅是公司各个业务的应用,大部分的JDOS 2.0组件(Gitlab/Jenkins/Harbor/Logstash/Elastic Search/Prometheus)也实现了容器化,在Kubernetes平台上进行部署。

开发者一站式解决方案

JDOS 2.0实现了以镜像为核心的持续集成和持续部署。

jd_deploy

  1. 开发者提交代码到源码管理库

  2. 触发Jenkins Master生成构建任务

  3. Jenkins Master使用Kubernetes生成Jenkins Slave Pod

  4. Jenkins Slave拉取源码进行编译打包

  5. 将打包好的文件和Dockerfile发送到构建节点

  6. 在构建节点中构建生成镜像

  7. 将镜像推送到镜像中心Harbor

  8. 根据需要在不同环境生产/更新应用容器

在JDOS 1.0,容器的镜像主要包含了操作系统和应用的运行时软件栈。APP的部署仍然依赖于以往运维的自动部署等工具。在2.0中,我们将应用的部署在镜像的构建过程中完成,镜像包含了APP在内的完整软件栈,真正实现了开箱即用。

jd_app

网络与外部服务负载均衡

JDOS 2.0继承了JDOS 1.0的方案,采用OpenStack-Neutron的VLAN模式,该方案实现了容器之间的高效通信,非常适合公司内部的集群环境。每个Pod占用Neutron中的一个port,拥有独立的IP。基于CNI标准,我们开发了新的项目Cane,用于将Kubelet和Neutron集成起来。

jd_tor

同时,Cane负责Kubernetes中service中的LoadBalancer的创建。当有LoadBalancer类型的service创建/删除/修改时,Cane将对应的调用Neutron中创建/删除/修改LBaaS的服务接口,从而实现外部服务负载均衡的管理。另外,Cane项目中的Hades京东开源在GitHub上组件为容器提供了内部的DNS解析服务。

灵活调度

JDOS 2.0接入了包括大数据、Web应用、深度学习等多种类型的应用,并为每种应用根据类型采用了不同的资源限制方式,并打上了Kubernetes的不同标签。基于多样的标签,我们实现了更为多样和灵活的调度方式,并在部分IDC实验性地混合部署了在线任务和离线任务。相较于1.0,整体资源利用率提升了约30%。

jd_schedule

推广与展望

有了1.0的大规模稳定运营作为基础,业务对于使用容器已经给予了相当的信任和支持,但是平台化的容器和基础设施化的容器对于应用的要求也不尽相同。比如,平台化的应用容器IP并不是固定的,因为当一个容器失效,平台会自动启动另一个容器来替代,新的容器IP可能与原IP不同。这就要求服务发现不能再以容器IP作为主要标识,而是需要采用域名,负载均衡或者服务自注册等方式。

因此,在JDOS2.0推广过程中,我们也推动了业务方主要关注应用服务,减少对单个容器等细节的操作,以此自研了全新智能域名解析服务和基于DPDK高性能负载均衡服务,与Kubernetes有效地配合支持。

近两年,随着大数据、人工智能等研发规模的扩大,消耗的计算资源也随之增大。因此,我们将大数据、深度学习等离线计算服务也迁移进入JDOS2.0。目前是主要采用单独划分区域的方式,各自的服务仍然使用相对独立的计算资源,但是已经纳入JDOS2.0平台进行统一管理,并通过机器学习方法,提升计算资源使用效率。

灵活的标签给予了集群调度无限的可能。未来我们将丰富调度算法,并配以节能的相关技术,提高集群整体的ROI,从而为打造一个低能耗、高性能的绿色数据中心打下基础。

回望与总结

Kubernetes方案与OpenStack方案相比,架构更为简洁。OpenStack整体运营成本较高,因为牵涉多个项目,每个项目各自有多个不同的组件,组件之间通过RPC(一般使用MQ)进行通讯。为提高可用性和性能,还需要考虑各个组件的扩展和备份等。这些都加剧了整体方案的复杂性,问题的排查和定位难度也相应提升,对于运维人员的要求也相应提高。

与之相比,Kubernetes的组件较少,功能清晰。其核心理念(对于资源和任务的理解)、灵活的设计(标签)和声明式的API是对Google多年来Borg系统的最好总结,而其提供的丰富的功能,使得我们可以投入更多精力在平台的整个生态上,比如网络性能的提升、容器的精准调度上,而不是平台本身。尤其是,副本控制的功能受到了业务线上应用运维工程师的追捧,应用的扩容缩容和高可用实现了秒级完成。JDOS 2.0目前已经接入了约20%的应用,部署有2个集群,目前日常运行的容器有20000个,仍在逐步推广中。

真诚感谢Kubernetes社区和相关开源项目的贡献者,目前京东已经加入CNCF组织,并在社区排名达到TOP30。

作者简介

鲍永成,京东基础平台部技术总监,带领基础平台部集群技术团队从2014年上线京东容器引擎平台JDOS1.0到现在的JDOS2.0,作为坚实的统一计算运行平台承载京东全部业务稳定运行。目前主要工作方向是JDOS2.0研发和京东第一代软件定义数据中心建设。


作为一名程序员,设计程序架构、优化算法已经是一件很头疼的事了,然而,还有更让人烦躁的,那就是环境配置,想必各位同学们都深有体会。每个人的电脑都不一样,不管是软件还是硬件,或者是要依赖的环境,因此同样的安装流程在别人那里是好使的,在你这就处处 bug,在电脑 A 上能顺利安装,在电脑 B 上就遇到问题了。于是有人就想出了一个办法,大家何不把自己配置好的环境打包成镜像呢?当需要配置同样的环境时,就把别人的镜像拿过来,进入镜像之后,就进入了别人搭建好的环境,而我们只需要提供硬件支持即可,而这个镜像就是 docker 容器。什么是镜像呢?简单来说,镜像就类似操作系统光盘介质,docker 容器相当于通过光盘安装后的系统。通过光盘(镜像),我们能在不同机器上部署系统(容器),系统内的操作只会保留限制在当前的系统(容器)中。需要了解的是,像 docker 这样的容器有很多种,而 docker 只是其中之一,但它是最受欢迎的,也因此占据了大半的市场份额。其他容器还有 CoreOS rkt、Mesos、lxc 等。

OpenStack 的诞生

我们都知道,全球云市场被三大巨头垄断,分别是亚马逊(Amazon)、微软(MicroSoft)和 阿里巴巴(Alibaba),而亚马逊正是云计算的开山鼻祖。

早在 2003 年,Amazon 向客户推出了一项全新的业务——包括存储空间、计算能力等资源服务的 Web Service,这就是大名鼎鼎的 AWS(Amazon Web Service)。说白了,就是给大家提供了远程电脑,上面配置了各种满足你需求的服务,你可以远程使用它,这就是云计算最早的形式。到了 2006 年,亚马逊又推出了一种配置更简单、方便的弹性计算云(Elastic Compute Cloud),又称 EC2 。而在同年的 8月9日,Google首席执行官埃里克·施密特在搜索引擎大会上首次提出“云计算”(Cloud Computing)的概念。从此,云计算进入了高速发展阶段。时间转到了 2010 年,一家名叫 Rackspace 的公司,同样在做云主机和云储存服务,和 Amazon PK 了多年,但是在竞争中一直处于下风。最终,他们把云服务代码给开源了。随后,NASA 也步后尘,开放了其在云领域多年的研究成果,并与 Rackspace 联手共同成立了一个开源项目。这个项目,就是 OpenStack,也是云计算发展的里程碑。

OpenStack 是什么

现在的云上资源(计算、存储、网络等)都是以集群的形式存在,这些集群里的物理机(Host)可以放在一个机房里,也可以分布式放在各个地方,而一个 host 上又可以虚拟出多个虚拟机(VM)。而 OpenStack 从一开始,就是为了云计算服务的,它就是一套软件,一套 IaaS 软件,用来管理集群里所有 Host(物理机)上的所有 VM(虚拟机)。什么是 IaaS?Infrastructure as a Service,基础设施即服务。这里的关键字是“基础设施”,也就是物理机。各大公司在 OpenStack 上进行了二次开发,形成了自己的 Iaas 软件,比如华为的 FusionSphere平台 和中兴的 TECS 平台。OpenStack 的安装部署非常快速,兼容性和适用性极强,而且便宜,一直很受市场欢迎。

Docker 的出现

按理说,Host 虚拟化出来了许多 VM,云上资源粒度划分已经很细了,也已经能做到资源的充分利用。然而,虚拟机的性能开销很严重。主要由于两点原因:一是虚拟层的引入;其二是因为 VM 的操作系统和 Host 的操作系统不一致,导致与操作系统有关的性能优化手段不能应用到所有的 VM 上。如果说虚拟机技术开启了云计算时代,那么 Docker 容器作为下一代虚拟化技术,将云计算推向了高潮。

  • 虚拟机和 Docker 的区别

首先,你要明确一点:Docker 容器不是虚拟机,但你可以把它近似看成一种轻量级的虚拟机。

一个 VM 里可以创建多个 Docker 容器。

Docker 比虚拟机更节省内存,启动更快,数量级上”虚拟机需要数分钟启动,而 Docker 只需要50毫秒”,这是因为 Docker 是利用宿主(VM)的系统内核。

K8S - 为 Docker 而生

当只需要一个容器时,你可以手工部署,没有问题。然而在集群里要部署海量的 Docker,还要管理它们时,手工显然不现实了,于是 Kubernetes 这种更高维度的容器编排工具应运而生。Kubernetes 简称 K8S, 它抽象了所有物理机资源,将所有云主机抽象成一个资源池,而这个池子里装的就是一个个容器。容器就是孩子,而 K8S 就是这些孩子们的亲妈,为啥这么说呢?比如,应用程序发现 CPU 不够用时,K8S 就将其调度到另一台 CPU 足够用的机器上,内存不满足要求时,K8S就会帮忙寻找一台有足够内存的机器,并在上面创建对应的容器。更重要的是,一旦应用程序由于某些原因挂掉了, K8S 还会帮它自动迁移重启, 照顾得简直无微不至。而开发者只关心自己的代码,容灾备份、服务资源扩充则由 K8S 保证。

说到这里,你可能认为”K8S“的调度单位是一个容器(container)。事实上,K8S 调度的基本单位为 pod, 一个 pod 表示一个或多个容器。引用一本书里所说“之所以没有使用容器作为调度单位,是因为单一的容器没有构成服务的概念;例如 Web 应用做了前后端分离,需要一个 NodeJS 与 Tomcat 才能组成一个完整的服务,这样就需要部署两个容器来实现一个完整的服务,虽然也可以把他们都放到一个容器里,但这显然违反了一个容器即一个进程的核心思想 --《Service Mesh实战 - 用 istio软负载实现服务网格》”


一.Cockpit简介

1.1基本介绍

Cockpit是一个免费且开源的基于web的管理工具,系统管理员可以执行诸如存储管理、网络配置、检查日志、管理容器等任务。通过Cockpit提供的友好的 Web 前端界面可以轻松地管理我们的 GNU/Linux 服务器,非常轻量级,Web 界面也非常简单易用。更重要的是通过Cockpit可以实现集中式管理。

1.2 功能特点

下面是 Cockpit的一些功能和特点:

Cockpit使用systemd完成从运行守护进程到服务几乎所有的功能
集中式管理,通过一个会话窗口管理网络中的所有Linux服务器
创建和管理Docker容器
创建和管理KVM、oVirt虚拟机
包括 LVM 在内的存储配置
基本的网络配置管理
用户user account管理
基于web的 终端
图形化的系统性能展示
使用sosreport收集系统配置和诊断信息
支持Debian, Redhat, CentOS, Fedora, Atomic, Arch Linux, and Ubuntu.
1.3 模块

以下是Cockpit的一些软件模块,可以根据自己的需要选择性的安装

Package Name Purpose
cockpit-docker Managing Docker Containers
cockpit-kubernetes Visualizing and Configuring Kubernetes Cluster
cockpit-machines Manage KVM Virtual Machines
cockpit-sosreport Create diagnostic report with the sosreport tool
cockpit-selinux Troubleshoot SELinux Issues
cockpit-kdump Configure Kernel Crash Dumps
cockpit-subscriptions Manage System subscription
cockpit-machines-ovirt Manage oVirt Virtual Machines
cockpit-pcp Reading PCP metrics and Loading PCP archives
二. 安装Cockpit

2.1 确认YUM源可用

这里是在CentOS7中进行安装,CentOS的软件仓库中包含有cockpit安装包。

2.2 开始安装

执行以下命令,安装Cockpit和基本的模块

yum -y install cockpit cockpit-dashboard cockpit-storaged cockpit-packagekit

2.3启动cockpit服务

systemctl enable –now cockpit.socket

2.4 添加防火墙规则

执行以下命令

firewall-cmd –permanent –add-service=cockpit

firewall-cmd –reload

如果防火墙未开启,可忽略此步,到这里cockpit就安装完成了。安装过程非常简单。

三. 使用Cockpit

3.1 登录Cockpit

Cockpit使用9090端口,并且为SSL加密访问,通过浏览器登陆https://ip.add.re.ss:9090

登陆时浏览器会提示链接不安全,如果是Firfox浏览器,点击添加例外

添加例外后,就看到cockpit的登陆界面了

输入安装了cockpit的系统账号(用户名和密码和用于登录linux 服务器的用户名和密码相同)

3.2 主界面

主界面是当前主机的系统信息,可以看到CPU,内存,磁盘以及网络的使用情况

3.3 多主机监控

点击左侧上方的仪表板,然后点击右侧的“+”添加需要监控的主机

输入被监控主机的IP或域名进行添加

列表中为所有被管理的服务器

也可以通过主页右上方来切换查看服务器

3.4 功能选项

Cockpit功能选项中的内容取决于都当装有哪些功能模块。

四. 功能介绍

4.1系统页面

系统页面提供主机的硬件系统,负载概览等

点击硬件名称,可以查看系统硬件信息,可以查看系统的PCI设备

4.2 日志查看器Cockpit将日志信息分为错误、警告、注意等不同的分类,可以看出是按事件的级别来分类的

4.3 存储

Cockpit 可以方便地查看硬盘的读写速度。我们可以查看存储的 Journal 日志以便进行故障排除和修复。在页面中还有一个已用空间的可视化图。在存储页面可以卸载、格式化、删除一块硬盘的某个分区。它还有类似创建 RAID 设备、卷组等功能。

4.4 网络

在网络页面可以看到两个可视化发送和接收速度的图。还可以看到可用网卡的列表,可以对网卡进行绑定设置,桥接,以及配置VLAN。点击网卡就可以进行编辑操作。最下面是网络的 Journal 日志信息。

4.5 虚拟机

如果被监控的主机为KVM主机,那么其中运行的虚拟机也可以在cockpit中进行管理操作,在虚拟机页面中会列出当前主机中的所有KVM虚拟机。

4.6 账户

在账号页面中可以添加或删除系统账户

也可以对账号进行编辑

4.7服务

服务被分成了5个类别:目标、系统服务、套接字、计时器和路径

单击服务名称,可以对其进行更多的管理操作,列如重启,关闭,禁用等

4.8 实时终端

Cockpit界面提供实时终端执行任务,这使我们可以根据需求在Web界面和终端之间自由切换,可以快速执行任务,操作非常方便。这是集中式管理的一个具体体现

4.9 Diagnostic Report

通过cockpit的诊断报告功能,可以快速的生成系统的sosreport,并且可以下载到本地

五. 使用Cockpit部署虚拟机

5.1 说明

前面我们对Cockpit进行了整体的介绍,下面我们演示一下如何通过Cockpit进行KVM虚拟机的部署和管理等操作

5.2 创建虚拟机

5.2.1 进入“虚拟机“页面,点击右上方的”Create New VM“按钮创建虚拟机

5.2.2 填写名称,选择安装源,调整内存和硬盘的参数后,点击“Immediately Start VM”,点击“Create”开始创建虚拟机。

5.2.3 Cockpit中提供图形化的远程控制台,在这里可以直接对安装进行操作。同样对于正在运行的VM,也可以通过图形化的远程控制台进行管理操作。

部署完成,虚拟机已经可以正常使用

5.3 编辑虚拟机

在Cockpit中,可以对虚拟机进行简单的配置编辑,比如修改vCPU数量,移除或添加网卡等

5.4 查看虚拟机状态

5.5 总结

Cockpit中只能对虚拟机做简单的配置编辑
虚拟机创建完成后,不能对内存容量进行修改
新建虚拟机时,无法对网卡进行配置,它会自动使用KVM中的默认设置
新建虚拟机时,无法选择安装到哪个存储池,它会将VM自动安装到KVM中默认的存储池中。
对于虚拟机的管理,使用中发现如果安装了 oVirt Virtual Machines的模块,Cockpit中就无法对KVM虚拟机进行管理。 这一点后续会再做一些测试进行验证
在Cockpit中,被管主机可以是物理主机,也可以是虚拟主机,测试中对物理主机,KVM虚拟机和VMware机都进行了测试,都可以正常管理。
另外,在Fedora Server中,系统默认就已经安装了Cockpit

一、镜像导出 save
查看镜像
docker images1
导出镜像
docker save -o test.tar image_name1
或者

docker save image_name > /test.tar1
二、容器导出 export
导出容器,命令格式为:
docker export [-o|--output[=""]] CONTATINER1

docker export 容器id/name >文件名.tar1
例如:

docker export -o test.img test1
test.img : 这里可以导出tar文件 , 也可以导出二进制镜像文件img

test : 需要导出的容器名, 通过docker ps查看

三、导入压缩包(包括压缩的镜像和容器)
1.import
docker import [-c|--change[=[]]] [-m|--message[=MESSAGE]] file|URL|-[REPOSITORY[:YAG]]1
例如:

docker import test.img test1
test : 为镜像名

2.load
docker load --input /test.tar1
区别:
docker save保存的是镜像(image),docker export保存的是容器(container);

docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;

docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。

四、部署镜像
启动镜像
docker run -d --name container_test --privileged -it test:latest /usr/sbin/init