之前在《环境管理》那一篇分享中介绍了我在管理环境上的一些经验,但是并没有介绍 docker 的使用细节。但有些小伙伴们还是比较感兴趣的。关于 docker 的教程网上其实也是满天飞,各种命令和原理的文章,中文的英文的数不胜数。所以我就不从安装开始,介绍各种命令了。这么讲我觉得我也讲不出什么花来,但是网上的这些教程大多数都是理论层次的。他们告诉你这么命令是干什么的,却没有用一条线把他们穿起来告诉你怎么用他们。所以今天我来用我们在测试中实际遇到的例子给大家穿一条线出来。让没用过 docker 的小伙伴们大概知道 docker 是怎么用的,有多简单,通过例子把大概的概念和理论了解一下。 这样就不会被漫天高大上的专有名字搞懵逼了。
官网上和各类文章中都对 docker 作出了明确的阐释,但是这些定义过于专业和高大上了。所以他姥爷这个土鳖就用俺们村的大白话给大家说一下。
Docker 这个单词英文原意是码头工人,搬运工的意思,这个搬运工搬运的是各种应用。docker 是一种容器技术。有的小伙伴们不了解什么是容器的话就把它当虚拟机吧。虽然 docker 不是虚拟机,但是大家可以把它当成虚拟机用。我们把各种应用(例如我们测试环境中的各种服务)制作成镜像(镜像制作很简单),docker 这个搬运工要搬运的东西就是这个镜像,它可以启动一个或者 N 个容器并把镜像搬运进去,这就是为什么我在《环境管理》那篇分享中可以一下子启动近 30 套测试环境的原因。只要我有镜像,在任何有 docker 服务的机器中都可以迅速拉起 N 套测试环境来。
干说概念性的东西容易让人懵逼。我们还是像学习编程从 hello world 开始一样,我们先演示一个 demo,从迅速搭建一个 test link 应用开始。
首先我们需要一个 mysql 服务来存储 test link 的数据。按照上面说的,我们需要一个 mysql 镜像。 那么我们如何制作镜像呢? docker 的好处之一就是共享,他人制作的镜像我们可以下载下来直接使用。怎么做呢? 我们可以去 docker hub 中直接搜寻 mysql 的官方镜像
具体的使用细节官方镜像附带的说明中写的很清楚,很简单。我们来用一下吧。首先是下载 mysql 5.5 的镜像。命令如下:
docker pull mysql:5.5
运行过后我们下载了镜像. docker pull 这条命令就是在 docker hub 上搜寻并下载一个镜像。接下来我们运行一下 docker images | grep mysql 来查看本地下载的 mysql 镜像。docker images 的意思就是列出所有的镜像。
OK,我们有了 mysql 的镜像了,那么我们怎么使用这个镜像呢。 来来来,我们关键的地方到了。请看下面的脚本
export name=testlink_mysql
export ip=172.27.1.221
docker rm -f $name
docker run --name=$name -e MYSQL_ROOT_PASSWORD=root -itd -v /home/testlink_data:/var/lib/mysql --net=none mysql:5.5
pipework br0 $name $ip/20@172.27.0.1
接下来我们讲解一下这些命令。从 docker rm -f 开始把,这条命令是删除一个容器,还记得什么是容器么? 容器是镜像的载体。我们的镜像要放在容器里运行的。所以如果有同名的容器我们先删除它,当然这一步不是必须得。 接下来我们看 docker run 的命令, 这条命令就是用镜像去启动一个容器,命令的最后的那个 mysql:5.5 就是镜像的名称(我们之前用 docker pull 下载的),是不是很简单。这样我们就启动了这个 mysql 的服务了。当然中间有一些参数我来详细的讲解一下。
OK,运行这个脚本后,我们的数据库服务就搭建好了。是不是很简单。你不是运维的同学,你不必懂 mysql 得配置,你只需要下载官方镜像直接使用就可以了。
接下来我们搞一搞 test link 吧。同样现在 docker hub 上搜一下有没有人已经做好了 test link 的镜像。很幸运的我发现也是有的。我们运行一下 docker pull otechlabs/testlink 下载即可。我们同样用下面的命令启动 test link 容器
export name=testlink_new
export ip=172.27.1.220
docker rm -f $name
docker run -itd --name=$name --hostname=$name --net=none -v /home/testlink_upload:/var/testlink testlink
pipework br0 $name $ip/20@172.27.0.1
命令跟上面 mysql 一样,也很简单,唯一需要注意的是我挂载目录的位置是 test link 保存附件的文件夹,testlink 不是所有数据都保存在数据库里的,所以这部分也要挂载出来保存。容器启动后,我们使用 ip 登录 test link,见证奇迹的时刻就到了。剩下的你只需要根据 test link 的页面配置一下数据库了。到这里我们就搭建了一个在测试工作中很常见的用例管理工具。当然到了这里我们还有些不太完美。就是到了这里我们的数据虽然都挂载到宿主机上保存了。但是 test link 的配置缺没有,这是容器启动后,我们在页面上配置的。这部分的信息我们没有保存。所以我们需要修改一下镜像了。如下:
FROM otechlabs/testlink
ADD files /var/www/testlink
这是一个 Dockerfile,制作镜像的语法文件。我们使用 Dockerfile 的语法来扩展一个镜像。 第一行的 FROM 命令大家看到了,说明是继承自另一个镜像的。也就是说我们对 test link 镜像做扩展。熟悉编程的小伙伴们理解起来一定很容易,你就把它当成面向对象语言中的继承就行了。 接下来我们用 ADD 命令,把宿主机中的 files 文件夹下所有的文件都 copy 到镜像中的/var/www/testlink 文件夹中。 这里说一下我把 test link 的 config 文件存在了 files 文件中,所以也就是说 config 文件现在被 copy 到了 test link 容器里了。接下来我们运行一个简单的命令构建镜像。
docker build -t testlink .
这是构建一个惊险的命令,要在 Dockerfile 的目录下执行。这样我们新的镜像就做好了。我们用新的镜像代替之前启动 test link 的旧镜像。一切就 OK 了,完美了。test link 的配置文件也就存到了镜像里了。
这是一个搭建 test link 的简单应用。我们经理了下载官方镜像并使用的过程,扩展镜像满足我们自己需要的过程。 我们可以用这个思想搭建各种基础服务。那下面我们再说复杂一点的场景
现在说说我们的测试环境,要搭建测试环境肯定就没有那么成熟的镜像给我们用了。我们需要自己专门定制一个镜像出来,首先我们要做一个基础镜像,解决依赖的问题,例如我们的产品是 java 的项目,那我们要装:maven,jdk,git,ssh 等等。下面看一下 Dockerfile 的例子:
FROM docker.io/ludalex/docker-java7-maven-aws-git
MAINTAINER sungaofei(sungaofei@4paradigm.com)
ADD files /root
RUN apt-get update \
&& apt-get install wget -y \
&& apt-get install -y openssh-server \
&& /etc/init.d/ssh start \
&& apt-get install -y oracle-java7-set-default \
&& cd /tmp \
&& wget http://apache.claz.org/thrift/0.9.3/thrift-0.9.3.tar.gz \
&& tar -zxvf thrift-0.9.3.tar.gz \
&& cd thrift-0.9.3 \
&& ./configure && make \
&& make install \
&& cd /opt \
&& mkdir web \
大家看到首先我还是继承了一个从 docker hub 上下载的基础镜像,通过名字就可以看出来,这个基础镜像里已经有了 maven,git 之类的东西。但还不够,我们需要再下载一点东西。RUN 这个命令就是执行 shell 命令的。 它最大的作用就是安装一些依赖包。在 RUN 里面,最常用的就是 apt-get 了。上面的例子我下载并安装了 ssh 的组件包,jdk7,thrift 的 RPC 框架包等等。然后再运行一个 docker built -t 我们就做好这个基础镜像了,这解决了我们的依赖问题。以后再制作任何 java 镜像我们都可以通过扩展这个基础镜像来做。
接下来我们看一下部署镜像的 Dockerfile
FROM 4paradigm/dango2.0-test-base-new
ADD files /root
ENTRYPOINT ["/root/entrypoint.sh"]
可以看到这个镜像貌似没干什么。但是,恩? ENTRYPOINT 是个什么鬼? 这个很重要,非常重要。大家记住了,这是启动容器后第一个运行的命令。也就是说,它是容器的启动命令,它是容器启动后干的第一个事。我们通常把启动服务的脚本放在这里。我们同 ADD 命令把一些启动脚本放在容器的/root 目录下。然后通过 ENTRYPOINT,运行启动脚本。我们来看一下 entrypoint.sh 这个脚本都干了什么
cd /root
echo "setup is running"
# deploy simba
cd /opt/web
git clone git@git.4paradigm.com:prophet/simba.git
cd /opt/web/simba
git checkout ${simba_branch}
if [ -n ${simba_commit_id} ]
then
echo "reset to commit_id ${simba_commit_id}"
git reset ${simba_commit_id}
fi
mvn -DskipTests clean package -U
cd /opt/web
./startserver.sh
中间我删除了一些干扰代码,真实的情况比这个复杂些。看到这个脚本里我们拉取了 git 上的代码。编译并运行了启动脚本。大家注意这里我读取了一些环境变量,例如${simba_branch},这就是通过启动容器的时候(也就是 docker run)的 -e 的参数传递进来的环境变量。 这样我们就做到了容器的参数化。接下来我们运行 docker run 就可以了,我们的这个 java 项目的测试环境的搭建起来了。当然我中间刻意忽略了一些细节免得大家被干扰。但是我们用 docekr 搭建测试环境的流程大概就是这样的了。
今天他姥爷就讲到这里吧,我用了两个在工作中用到 docker 的简单例子来给各位扫一下盲。特别详细的教程他姥爷真的木有时间写了,大家去翻官方文档吧,平时工作比较忙。女王大人还怀孕了,而且女王大人对我这种老是坐在电脑面前码字或者撸代码不管老婆孩子的行为很是不满了。所以各位见谅,我的这个系列文章真的没办法很详细的写个教程。就是带大家入个门,让大家看一下大概怎么做的,做成什么样子。很多细节大家要自己探索和阅读文档了。