领域修炼之路

遗留应用如何快速迁移到DC/OS

讨论正题之前,先讲一个场景,有个同事,非技术人员,他想体验一下Phacility公司的 Phabricator 产品,于是从网上搜索各种安装文档,着手安装。搞技术的都知道,现在的服务大多数部署在Linux环境,所以安装文档优先考虑Linux的部署,而技术人员的另一个爱好就是在文档中简单的几句描述一下命令行步骤就不管了,类似Windows上的图形化安装,那是奢求,尤其是对开源产品,所以过程可想而知。

Phabricator是PHP开发,依赖MySQL数据库,推荐跑在Nginx中。我的这位同事参照文档,搞定了数据库(至少完成了安装),卡在了Nginx上,他用的Macbook,找了几个技术来帮忙,比较诡异,都没搞定,我看了一下,也没找出问题,因为有别的事,也没心思细琢磨。然后,突然想起来,只是个体验,直接用Docker跑个Phabricator的镜像不就OK了,瞬间觉得思维又开阔了些。

最近一直在深入研究DC/OS,这件事让我开始进一步思考遗留应用的迁移问题。下面进入正题:

遗留应用的特点

遗留应用最明显的一个特点是与运行环境强力绑定,有的应用具有复杂的依赖,超级复杂的配置,一旦部署,没人“敢”调整。

遗留应用的另一个问题是扩展非常复杂。如果没有完整的文档,新增节点服务启动后很可能会发现:用户忘记创建,目录忘记创建,目录权限忘记设置,端口忘记打开,某个依赖的应用忘记安装,目录链接忘记创建,NFS忘记挂载,Nginx代理忘记配置,某个系统参数忘记调整等等。这是运维人员的噩梦。

再讲一个实际案例,我们有个产品采用ansible管理应用的持续部署,但是,有一天,应用要部署到一个新节点,而这个新节点已经部署了部分应用,Ansible部署时设定的环境与现有环境冲突,需要重新调整脚本。这也是一个运维过程中经常出现的场景。面对这种问题,不同的决策可能带来不同的结果,有好有坏。

这一切问题的核心根源是什么?应用服务运行需要满足一定的环境。如果把这个环境制作成光盘,把应用烧录进去,插入光驱即可运行,这种场景多么美好。

一种思路是走虚拟机镜像,这是一种可行的方案,但是它太“”了,我一个APP本来只要512MB内存就可以跑,为了启动个虚拟机,还要再多分配512MB甚至更多内存,一台4GB内存的主机能跑几个应用?!

容器带来的优势

容器带来的好处是什么?

很明显,第一个好处是,它可以让你把你的应用的运行环境构建到一个镜像文件中,这样你就再也不用为了让用户能够体验你的产品,而针对各种系统各种版本编写各种安装程序,然后写一本书一样的安装手册,再然后到处培训,不厌其烦的给用户解释各种问题,帮助用户调试各种奇葩的运行环境。

第二个好处,docker并没有为你的应用构建一个操作系统,它很轻量,还是运行在现有的系统环境中,跟其他应用使用相同的CPU,内存和磁盘,不同的是在操作系统内核级别做了资源隔离。

随之第三个好处是,因为隔离,你的系统环境非常“干净”。不必因为要运行某个应用需要安装一堆的依赖,卸载时无法卸载干净,在安装另一个应用时因为依赖的版本冲突不得不绞尽脑汁想各种奇葩的手段,最后还可能无功而返,不得不重装系统。

第四个好处是容器让应用更具弹性,服务节点可以随时上下线,根据需求快速伸缩。

再有,它弥合了Dev和ops之间的鸿沟,专业的人做专业的事。开发人员知道自己的应用需要什么环境,如何配置;运维人员知道服务态势,可以根据需要调整资源配给。

遗留应用如何发挥容器的优势

遗留应用通常处于少量开发甚至不再开发或维护的状态。不必担心,这个问题不会成为迁移到容器的障碍。只需要准备好基础系统,所需依赖,按照应用的部署过程定义一个Dockerfile,生成一个镜像文件,就可以解放了。应用还是那个应用,它不再依赖陈旧的设备,难以维护的环境可以随时随地迁移重组。

解决了遗留应用对环境的依赖问题,就可以将应用部署到弹性计算环境中,根据需要动态地调配资源,而这正是DCOS/Mesos集群的工作目标。

在DC/OS中部署遗留应用

DC/OS即数据中心操作系统是Apache Mesos, Marathon, Docker容器及其它很多服务(监控、日志、负载均衡及服务发现等)整合而成的服务调度管理平台。DC/OS提供了一个完整的弹性计算环境,让部署的应用服务可以开箱即用

当前DC/OS支持AppC容器和Docker容器两种应用定义。可以根据应用的具体类型和特点,选择特定的方案。

直接部署

以部署一个Tomcat应用为例,可以直接通过Marathon下载Tomcat发布程序,打包好的应用War包,然后启动Tomcat。这个过程可以通过Marathon的应用JSON定义描述:

1
2
3
4
5
6
7
8
9
10
11
12
{
"id": "tomcat",
"cmd": "mv *.war apache-tomcat-*/webapps && cd apache-tomcat-* && sed \"s/8080/$PORT/g\" < ./conf/server.xml > ./conf/server-mesos.xml && ./bin/catalina.sh run -config ./conf/server-mesos.xml",
"mem": 512,
"cpus": 1.0,
"disk": 4096,
"instances": 1,
"uris": [
"http://mirrors.aliyun.com/apache/tomcat/tomcat-8/v8.5.6/bin/apache-tomcat-8.5.6.tar.gz",
"http://192.168.1.100/nexus/content/repositories/releases/com/example/example/1.0/example-1.0.war"
]
}

这个Tomcat应用部署到DC/OS集群后,就可以根据需要动态调整应用的服务实例数,可以通过Marathon-LB为这个应用服务提供负载均衡。

Docker容器部署

如果上述Tomcat+应用War包封装为一个名为“docker-tomcat-war”的Docker镜像,则可以以Docker容器化的方式直接在DC/OS集群中运行该应用。
同样需要定义一个Marathon应用JSON描述文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"id": "exampleapp",
"instances": 1,
"cpus": 0.25,
"mem": 128,
"uris":[],
"env": { },
"ports":[9000],
"container": {
"type": "DOCKER",
"volumes": [],
"docker": {
"image": "chrisrc/docker-tomcat-war:0.0.1",
"network": "BRIDGE",
"portMappings": [{ "containerPort": 8080, "servicePort": 9000 , "hostPort": 0, "protocol": "tcp" }]
}
}
}

结论

关于上述示例的详细步骤可以参考“在Jenkins on DCOS上编译部署Tomcat应用

通过简单的Marathon应用程序定义,应用既可以迁移运行在弹性计算的环境,又可以直接使用DC/OS平台所提供的各种监控、调度和负载均衡方案,让应用的维护不再一片“黑暗”。

chrisrc wechat
更多信息请订阅我的微信订阅号