Docker——使测试更美好

第一次尝试使用docker是在去年六月。

当时基于一些原因,笔者想把UI自动化用例放到docker里执行。但发现在docker中执行UI测试不是那么靠谱,于是就老老实实地用windows测试机,搞了个jenkins slave来执行用例。前不久,有一键部署测试环境的需求,就想到用docker完成这个工作。现在这个story已经算是比较完整了,分享给大家。

基于docker的测试环境一键部署

无论是开发自测环境的搭建还是测试环境的部署,一套环境从无到有的过程往往意味着各种下载与配置。这就好比你去一个地方,要先坐地铁,再转公交,非但要转公交,从公交车上下来,还需要走15分钟的路。而一键部署就好比出门打了一辆车,你在车上听歌,微信,摇一摇。你只需等司机告诉你到了,然后开开心心下车就好。

基本思路:

图里的头像分别代表:git,docker,jenkins以及需要部署的机器。

基本的思路是:先按照需求build 基础镜像。封装与复用的概念想必大家都听过,build 基础镜像其实也是如此。把一些依赖的,不变的组件build 进基础镜像,比如tomcat,比如jdk。再把变化的那部分用git 以及jenkins 来管理,比如war 包,比如配置文件。之后把不变的那部分与变的那部分组合起来,build成一个全新的镜像(—个全新的,能被复用的,不需要配置的,run起来就是一个服务的镜像)。最后只需在部署的机器上把这个镜像run起来即可。

一个应用一般包含不止一个服务,服务之间注册与发现的机制各有不同。在用docker完成一键部署的时候,服务之间的注册与发现问题已经转换为docker间的通信问题。

实现docker间通信的基础方法有两个:

使用docker的端口映射,以宿主机为媒介完成docker间通信;

使用docker link。

兵无常势,水无常形。这两种方式各有利弊,只要灵活运用就好。

具体实现:

照着上面的思路,笔者会先说如何构建一个单独的服务镜像,然后说如何让服务间相互发现,直至成为一个完整的应用。

以构建一个webApplication的镜像为例:

1、build一个基础镜像,这里需求各不相同,不细说。

2、在jenkins新建一个job,代码用git管理

分支是一个变量,用参数化构建来管理。类似的,所有可能会发生的变化都用参数化构建来管理,不一一列举。

3、在jenkins里新建Excute Shell,大部分你想实现的功能都可以用脚本来实现。比如编译代码打war包,比如你想自定义tomcat启动时的JAVA_OPTS。

4、当然最不可缺少的就是Dockerfile。

5、然后就是构建镜像,并push到私人仓库,清理空间。

此时,一个webApplication的镜像已经在你的私人仓库里。但镜像是不能提供服务的,镜像需要run成容器,docker run有很多门道。只需在你的docker client输入docker run --help,你就会明白我所言非虚。

上面提到过,docker间通信有两种基本的方法,采用哪种方式决定了如何run。下面会分别说一说:

1)使用端口映射实现docker间通信

端口映射使用的是docker run的 -p 参数。如 -p 8081:8080,代表了宿主机的8081端口映射了容器内的8080端口。你访问宿主机的8081端口,实际访问的是容器内的8080端口提供的服务。假如此时容器内的8080端口监听的是tomcat服务,你就能在浏览器里看到那只可爱的猫了。

举个栗子,这个webApplication需要一个mongoDB服务,这个mongoDB也运行在容器内。那么问题来了,如果我们能知道MongoDB所在容器的ip地址,只需使用类似docker run的--add-host参数就能指定被依赖服务的地址。但偏偏,docker run的容器ip是很难指定的。除非进到运行mongoDB的那个docker容器里查看ip地址,否则就不能告知webApplication,mongoDB服务的地址。但既然是一键部署,当然不能用手工的方式去查看IP了!怎么办?

很简单,只需要在run mongo容器的时候把mongoDB的服务端口映射到宿主机上,如 -p 27017:27017。那么webApplication只需访问宿主机的27017端口,就是在访问docker中的mongoDB服务了。宿主机的ip可以是固定的,把被依赖者的服务端口映射给宿主机,依赖者访问宿主机的映射端口。一个应用的各个服务就能用这种方式相互发现了。

但有个问题,假如宿主机的27017被占用了呢?

这个简单,改成-p 27018:27017就好!

如果webApplication指定访问的是27017端口呢?

让开发工程师去改代码?

不是不可以。但是——

幸好还有一种方法。

2)Docker link

用docker run的 --link参数能实现docker container之间的连接。

1、run一个mongoDB服务,用 --name 参数指定container的名字为 mongo

2、查明在webApplication里依赖的mongoDB的hostName为my-mongo

3、用--link参数,启动webApplication的container

4、webApplication容器内hosts文件下就有了下面这一行

目的已经达到,webApplication已经知道mongo的ip地址。无论你有多少个服务。只要你理清楚服务之间的依赖关系,用--link参数,按顺序启动容器。一个完整的应用就起来了。

但是,用这种方式有个致命的问题,服务之间耦合太高。当其中一个服务不可用,需要重新run container时。link它的容器也需要重新run,犹如多米诺骨牌。最坏的情况是整个应用的服务全都需要重新run。如果应用包含的服务很多,那简直就是噩梦。

在实践中,笔者创建了两套job。给类似DEMO环境这种专属机器部署的时候笔者用端口映射的方式,专属机器上几乎不可能会有不可避免的端口冲突。在给个人开发机提供部署服务的时候,笔者选择用link的方式。因为此时端口冲突的几率非常大。也不用太担心那个耦合度太高的问题,能在个人机器上部署的应用,可想而知不会有太多服务。再者,假如有端口冲突,用户是不太希望去修改配置的。就像没有人希望打车的时候司机不停问路。

基于docker的jvm监控一键部署

没有性能监控的性能测试,就像没有沙拉的蔬菜沙拉。

监控至关重要。

对java应用而言,最重要的监控是对jvm的监控。通过监控jvm,你可以了解虚拟机运行时的状态,例如Heap、MemoryPool等。通过这些参数可以分析代码的缺陷等。

说起jvm的监控,大家首先想到的是jconsole,这个朴实无华却又非常实用的工具。

jconsole

若是监控本地java进程,只需打开jconsole,选择对应的本地进程即可。像这样

若要监控远程进程,配置也不复杂,只需要在java进程的启动参数中加入如下几个配置(这里有一些安全配置,不在本文讨论范围之内)

在jconsole客户端中连接远程进程

jconsole实在是一款很好用的工具

但是,jconsole有一些局限。

有时候你需要监控的远程进程运行在一台网络策略比较复杂的远程机器上,这时候使用jconsole就会很头疼。若是这个进程还运行在docker容器内,那简直就能让你的头爆炸。

怎么解决?

Jconsole是基于JMX的工具。JMX有一套API,称为MBean。也许我们可以利用MBean写一套框架,像特洛伊木马一样让它在远程机器上执行。这套框架的工作很简单:收集需要监控进程的运行时数据,发给一个数据状态收集工具,比如graphite。这个数据收集工具就像一个管家,你关心的所有数据它都能告诉你。客户端只需要保证和这个数据工具的网络互通即可。

但无论对谁来说,从零开始写一套可靠的框架都不是一件太容易的事。维护和优化需要很多的时间。

幸好,已经有了一套现成的方案

JmxTrans

这不仅是一套现成的框架,甚至有现成的镜像。你要做的就是把镜像run成容器,照着官方文档修改一下配置就能使用。如下:

1、启动容器

2、查看Dockerfile,找到配置文件所在目录,在笔者的实践中,配置文件在 /opt/jmxtrans/conf目录下

3、新建自己的配置文件

大多数你可能需要使用的配置,都可以在jmxtrans的官网上找到,但不排除有一些奇特的坑。踩踩更健康。

4、重启容器,查看jmxtrans的日志是否有报错信息,我的日志在/opt/jmxtrans/log目录下。如果你的配置没有问题,log看起来是这样的

Graphite

jmxtrans获取到java进程的运行时数据后,需要一个收集并展示的组件。对于jmxtrans而言,这个组件是一个"writer"。jmxtrans可以配合很多种"writer"使用。笔者用的是graphite,当然也是跑在docker里的。

graphite的api服务监听在80端口。可以看到,docker run时映射了宿主机的80端口,如何处理端口冲突在上篇中已经说过。现在只需在浏览器中访问http://${宿主机ip}:${宿主机映射端口}

dashbord长这样:

实现一键部署

现在我们已经能用jmxtrans和graphite完成远程jvm的监控,但配置的过程略显繁琐。尤其是每个jmxtrans都要加入新的配置文件,非常麻烦。所以,笔者也对这套环境监控做了一键部署,如下:

1、把jmxtrans的配置文件用git来管理,不同环境的配置文件用不同的分支。

2、用jenkins job做一键部署的载体,在job中拉取git仓库里的jmxtrans配置文件。

3、把配置文件Add进jmxtrans镜像,build成一个包含指定配置文件、即插即用的镜像。

4、启动graphite容器,上文提过。

5、启动jmxtrans容器,这时采用link的方式是极好的.因为在jmxtrans配置文件中声明的地址,需要在jmxtrans所在docker容器的hosts文件中定义其真实ip。docker的真实ip在一键部署中是动态变化的,没法预先知道。

然后只需把jenkins的job串联起来,监控的一键部署就完成了。但是,graphite的dashbord实在是丑。为了心情好,我们需要一个颜值高的图表

grafana

依然使用docker

然后在浏览器中打开grafana,创建DataSource

配置graphite data source

创建graph

创建所有你想看到的监控图表

比较graphite的图表,心情岂非好上许多?

本文作者:施凯(点融黑帮),目前就职于点融网infra部门,擅长质量保证体系的搭建和开发。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,508评论 15 147
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,597评论 18 139
  • 0. 前言 docker是什么?docker是用GO语言开发的应用容器引擎,基于容器化,沙箱机制的应用部署技术。可...
    sessionboy阅读 3,838评论 2 49
  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,468评论 0 120
  • 特别特别简单的一道菜,但是味道很赞哦,中午做了一顿大受好评,晚上又如法炮制了一盘,依然被吃光光了。 材料...
    小狗子他娘阅读 595评论 0 0