转载

新东方利用容器技术在用户自服务方面的探索

如何减少运维团队的日常琐事?如何将服务平台化,赋予用户自我服务的能力?新东方云利用Rancher容器管理平台、Harbor镜像仓库和GitLab构建企业应用商店。赋能运维团队和用户,尝试破解用户自服务的难题。

开场先讲个小故事:

运维团队一线支持小哥接到某团队的工单,要求部署一套TiDB做功能测试。小哥在云平台上申请机器,按照内部标准的部署文档安装配置,最终交付给该团队。小哥回复邮件后已经是下午3点多了,小哥的一天就这么过去了。平淡无奇的运维工作似乎就应该是这样的。

我相信这是大多数运维团队都会面临的问题,运维团队面临着很多不断重复,事务性的工作。组织规模变大以后,像这样有的没的项目都会来运维团队寻求支持。运维团队招了很多人,忙了一年下来,发现好像也没做成什么事情,功劳似乎都是别人的,成本都是自己的。为什么会这样?因为运维团队的大量时间和精力在服务其他团队的琐事中消耗掉了。

这也是我们信管部王威老师提出建设新东方云的初衷之一。我们设想是否能把手中的资源和我们的服务平台化?通过定制和开发,最终我们交付出去的不是针对具体项目的劳务,而是一个服务的平台。让大部分重复性的日常部署和维护工作由用户自己完成。我们将运维能力直接赋予其他团队和用户,让运维团队能将精力集中在提高SLA和技术提升上。

这也是我今天分享的主题,今天主要分享一下新东方利用容器技术在用户自服务方面的一些探索。

首先简单介绍一下新东方云和容器云服务:

新东方云采用自建数据中心+IDC+公有云的混合云架构,提供包括:云服务器、对象存储、分布式文件系统等IaaS层面的服务,提供消息队列、缓存服务等中间件层面服务,以及运维大数据方案和视频服务等等。

新东方利用容器技术在用户自服务方面的探索 新东方利用容器技术在用户自服务方面的探索

" />

容器云服务是新东方云提供的最新服务,目前还在beta阶段。我们的容器云平台也是基于Docker、Harbor等主流技术作为后台,使用Rancher提供的Cattle作为编排引擎。

提到Rancher大家可能也听说过,简单介绍一下Rancher。

Rancher是一个轻量级的容器管理平台,CNI兼容的网络服务、存储服务、主机管理、负载均衡等功能。Rancher现在分为两个分支:

X:采用Rancher自己开发的Cattle编排引擎,已经有一套完整的平台和全球众多的粉丝。

X:目前已经进入beta阶段, 2.X分支则完全将Rancher建立在Kubernetes之上,提供对公有云或自建的各种Kubernetes平台的纳管。

我们选择Rancher的主要是出于以下考虑:

项目100%开源,可选的商业支持。

提供丰富的API,可供用户自行定制。

学习成本低,直接沿用了Docker生态,好上手。

内置的应用商店框架(Rancher Catalog)。

Rancher Catalog功能类似Kubernetes的Helm,提供对应用的打包定制,并提供一整套用户UI。用户只需要简单输入即可部署一套应用。这恰好也是我们比较看重的功能。我们尝试将日常常用的基础软件通过容器云平台打包,发布在企业应用商店中,这样团队内部在需要的时候只需要简单的通过界面设置一下就立刻获得这个服务。

说了这么多,应用商店是什么样的呢?下面就详细介绍一下应用商店的原理和实现。继续开场运维小哥的故事,同样的工作,他现在只需要打开应用商店:

填写一下表单:

大概等待3分钟左右, 一套完整的TiDB环境就出来了,期间小哥完全不用理会这边创建的过程,可以做其他事情去了。

创建好后根据暴露出来的端口和IP,直接连接即可。

这就是应用商店创建应用的流程,从图片中大家也看到,我们还在不断的增加企业内部应用。

比如图片中的SQL Server 2017 on Docker,定制这样一个应用的时间不会超过半天,复杂一些的应用两三天也能写完。

那么下面就简单说说应用商店的实现原理:

应用商店的组件

镜像仓库

我们选择的是业界广为使用的Harbor项目,我相信大家也很了解了。

简单介绍一下:Harbor是VMware中国团队开源的一套基于Docker Registry构建的镜像仓库项目。这个项目集成了CoreOS的Clair脆弱性检查工具和Notary镜像签名工具,配以LDAP集成,UI等企业应用必须的功能。可以说是目前企业镜像仓库的首选项目, 此项目为开源项目。用户可以下载下来自行定制。

我们对Harbor进行了简单的定制,我们的Harbor直接对接Ceph对象存储(通过Swift接口)。 这样后端存储在性能和可靠性上都有保障。同时前端也可以根据需要进行扩容,实际上Harbor中除了MySQL和Pg数据库外,其他服务都是无状态的,完全可以做到自动扩缩容,目前Harbor有基于Kubernetes和Rancher(社区Catalog中)的实现,大家可以参考。

我们目前的实践是通过docker-compose方式离线安装的独立部署的,后期会考虑以独立的environment方式纳入Rancher的管理中,后面有进一步的实践成果后再和大家分享。这里就不展开说了,有兴趣的朋友可以看一下我的工作笔记: http://jiangjiang.space/2017/11/15/harbor- 完全定制手册-制作一个更好用的registry/和 http://jiangjiang.space/2017/11/03/harborregistry 设置ceph对象存储/。

源码仓库

源码仓库是用来作为应用商店的载体,应用商店实际上是一个Git的项目。所有的编排文件以目录的形式存放在指定的路径下,这样Rancher就能读取为一个一个应用。

如图:

GitLab中的目录结构:

Templates下面是各个应用。

使用私有部署的GitLab或者直接使用GitHub也可以。

终于说到重点了,应用商店

之前提到过Rancher的Catalog和Kubernetes的Helm很相似,比如Helm各种Charts,Values和Templates等定义,帮助用户固化对应用的定制。Rancher的Catalog也是这个设计思路,Helm围绕Kubernetes,Rancher则是围绕Cattle而生。

下面以Catalog中的一个应用来解释一下。这是刚刚TiDB应用的目录结构:

0目录和1目录是版本目录,Rancher可以帮助维护应用的版本,可以帮你把老版本的应用实例升级到新版本,升级动作也是通过应用商店手工完成的。

进入0目录可以看到文件,这就是Rancher的服务定义文件了。

看到熟悉的docker-compose.yml和陌生的rancher-compose.yml,这两个文件的关系要从Cattle说起。

Rancher的Cattle编排引擎设计的很巧妙。 Cattle直接用docker-compose定义服务和服务的关系,比如一个服务使用哪些镜像,暴露哪些端口,存储卷定义等等。我们知道docker-compose其实是一个单机容器编排工具,直接作为集群编排文件的话还缺少很多重要元素:

缺少对服务的replica(副本)定义。

缺少容器之间的隶属关系(模拟Kubernetes的Pod),通过deponds_on能控制service的先后启动,但是一个service中的多个容器之间的关系就没有了。

缺少对服务的编排控制,比如一个服务起来后调度到哪个主机上。

缺少对容器的生命周期控制,比如只在服务启动时某容器执行一次,重启服务也不再启动等。

docker-compose缺少的定义则由rancher-compose.yml来补充。实际在执行时Cattle只是根据编排规则,将docker-compose文件中容器的定义部分直接丢给对应主机的Docker执行创建容器。利用Docker容器的label功能做标记,容器起来后Cattle从label中获取容器的现状,再与编排规则做对比看看是否满足要求, 比如:Scale,多了就干掉,少了就拉起。有了这两个文件的定义Cattle就可以在各个主机间调度和创建容器了,举几个调度的例子:

a:如果要调度一个容器到某个主机上,只需要在容器上打上如下标签:

Cattle就会将容器的定义发送到有cn.xdf.edge=true标签的主机上,随后启动容器。

b:更复杂一点的调度实现,比如在每个主机上只启动某服务的一个容器(单例),或者说类似Kubernetes daemonset,这个在Rancher里是怎么实现呢?

这个标签会把容器在每台主机上启动,并只启动一个。

如果我不想占用所有主机,只是按照Scale数目调度到目标主机,并且每个主机只跑一个实例:

这个意思是说:

启动时的主机上必须没有符合冒号后面表达式的容器,并且是一个软限制,去掉soft则是严格限制。

服务名字是这个服务的实例名和服务名。

也就是说只要这台机器启动了这个服务的一个实例就不要再调度另一个上去。

还有其他一些标签:

io.rancher.sidekicks:容器名,容器名

设置从属容器,比如做个side car容器,你希望第一个容器启动提供存储volume,然后启动第二个容器跑服务,接着第三个容器做日志的接收转发等等。

io.rancher.container.pull_image:always

启动服务时总是拉取容器镜像

详细的调度和标签说明请参考: http://rancher.com/docs/ranche ... bels/ 。

rancher-compose除了定义调度外,还提供了questions功能。

questions设置一些问题,用户在启动的时候输入,输入的结果保留到answer.txt中, 这个设计类似helm的values_file,只不过value文件不是预先定义的,而是用户启动时输入后产生的。

根据上面的定义,Rancher UI会为不同类型的question配置输入框,比如 enum是一个下拉列表, int是一个只能输入整数的输入框,Rancher会做基本的输入检查。

上图的代码会被自动转化为下图中的UI。

解释到这里可能大家就明白了,这就是应用商店的原理:

一套服务和容器的定义(docker-compose)

一套编排的设置(rancher-compose)

一套用户可以输入值的UI

用户在UI中填入值

随后由编排引擎交给主机上的Docker执行。

应用商店使用情况:

目前应用商店主要是运维团队内部使用。下一步我们打算以Rancher作为管理后台,通过调用Rancher的API,对接到新东方云平台上。与新东方云现有的申请和开通流程保持一致,简化用户的输入,最终形成一套用户能自服务的PaaS平台。

我最近会将Rancher 1.X的实践工作做一系列的总结,具体技术细节大家可以关注我的工作日志 http://jiangjiang.space 。

推荐阅读

原创干货│利用Rancher构建容器服务

原创干货│生产环境部署容器的五大挑战及应对之策

CaaS“容器即服务”:是营销手段还是有其价值?

钢铁电商平台的Docker容器云平台建设实践

原文  http://dockone.io/article/5106
正文到此结束
Loading...