在测试中如何使用Docker

这篇文章给大家分享的是有关在测试中如何使用Docker的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

成都创新互联专注于随县网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供随县营销型网站建设,随县网站制作、随县网页设计、随县网站官网定制、微信小程序开发服务,打造随县网络公司原创品牌,更为您提供随县网站排名全网营销落地服务。

5.1 使用Docker测试静态网站(Nginx)

将项目命名为Sample

首先建立构建环境

mkdir sample
cd sample
touch Dockerfile

在构建环境中下载作者配置好的两个nginx配置文件:

mkdir nginx && cd nginx
wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/nginx/global.conf
 wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/nginx/nginx.conf

写Dockerfile

FROM ubuntu:14.04
MAINTAINER Ivan Jiangzhi "ivanjz93@163.com"
ENV REFRESHED_AT 2016-07-09
RUN apt-get update
RUN apt-get -y -q install nginx
RUN mkdir -p /var/www/html
ADD nginx/global.conf /etc/nginx/conf.d/
ADD nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

在nginx.conf配置文件中daemon off;选项阻止Nginx进入后台,强制其在前台运行。这是因为想要保持Docker容器的活跃状态,需要其中运行的进程不能中断。默认情况下,Nginx会以守护进程的方式启动,这会导致容器只是短暂运行,在守护进程被fork启动后,发起守护进程的原始进程就会退出,这时容器就停止了。

构建Sample

docker build -t ivan/nginx .

构建完成后可使用docker history查看构建步骤:

docker history ivan/nginx

下载作者写好的html(或者自己写一个也可以)

mkdir website && cd website
wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/website/index.html

创建容器并运行

docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website ivan/nginx nginx

-v 选项将宿主机的目录作为卷挂载到容器里。

卷是在一个或者多个容器内被选定的目录,可以绕过分层的联合文件系统,为Docker提供持久数据或者共享数据。这意味着对卷的修改会直接生效并绕过镜像。当提交或者创建镜像时,卷不被包含在镜像里。

在下面的时候可以考虑使用卷:

  • 希望同时对代码作开发和测试;

  • 代码改动很频繁,不想在开发过程中重构镜像;

  • 希望在多个容器间共享代码。

-v 指定了卷的源目录(宿主机目录)和容器里的目录,这两个目录用:分割。如果目的目录不存在,Docker会自动创建一个。

也可以通过在目的目录后面加上rw或者ro来指定目的目录的读写状态:

docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website:ro ivan/nginx nginx

上例使目的目录变成只读状态。

docker run成功后在浏览器中访问 宿主机IP:映射端口即可看到页面,修改$PWD/website/index.html保存后刷新浏览器即时生效。

5.2 构建并测试Web应用程序(Sinatra + redis)

1、构建Sinatra应用程序

创建sinatra构建环境:

mkdir sinatra
cd sinatra
touch Dockerfile

编写Dockerfile,书上的例子:

FROM ubuntu:14.04
MAINTAINER James Turnbull james@example.com
ENV REFRESHED_AT 2014-6-1

RUN apt-get update
RUN apt-get -y install ruby ruby-dev build-essential redis-tools
RUN gem install --no-rdoc --no-ri sinatra json redis

RUN mkdir -p /opt/webapp

EXPOSE 4567

CMD ["/opt/webapp/bin/webapp"]

构建镜像

docker build -t ivan/sinatra .

2、创建Sinatra容器

下载作者编写的Sinatra Web应用程序的源码:

wget --cut-dirs=3 -nH --no-parent --no-check-certificate http://dockerbook.com/code/5/sinatra/webapp/

使用书中的命令下载时会报错,按报错的提示加入--no-check-certificate参数后成功下载。

为webapp/bin/webapp添加执行权限:

chmod +x $PWD/webapp/bin/webapp

启动容器并把$PWD/webapp按卷挂在到容器中:

docker run -d -p 4567 --name webapp -v $PWD/webapp:/opt/webapp ivan/sinatra

我在操作时遇到的问题和解决方法

构建时会报错,说安装的ruby是1.9版本,而gem install json需要2.0以上的版本。

我直接从ruby镜像构建,去掉apt-get ruby的安装,容器可以正常构建。但是启动时会包找不到/opt/webapp/bin/webapp的错误,执行的权限已经添加,/bin/bash命令启动容器发现webapp用/usr/bin/ruby启动,但是容器里的ruby在/usr/local/bin/ruby,所以在构建时添加cp命令。我的Dockerfile如下:

FROM ruby
MAINTAINER James Turnbull james@example.com
ENV REFRESHED_AT 2014-6-1

RUN apt-get update
RUN apt-get -y install ruby-dev build-essential redis-tools
RUN gem install --no-rdoc --no-ri sinatra json redis

RUN mkdir -p /opt/webapp
RUN cp /usr/local/bin/ruby /usr/bin/ruby

EXPOSE 4567

CMD ["/opt/webapp/bin/webapp"]

启动成功后查看执行命令的输出:

docker logs webapp

查看容器运行的进程:

docker top webapp

查看容器的4567端口映射到宿主机的端口:

docker port webapp 4567

测试Sinatra应用的运行情况,假设映射到宿主机的端口为49160(它接收输入参数,并将其转化为Json返回):

curl -l -H 'Accept:application/json' -d 'name=Foo&status=Bar' http://localhost:49160/json

3、构建Redis镜像和容器

创建redis构建环境:

mkdir redis
cd redis
touch Dockerfile

redis Dockerfile的内容:

FROM ubuntu:14.04
MAINTAINER James Turnbull james@example.com
ENV REFRESHED_AT 2016-07-11

RUN apt-get update
RUN apt-get -y install redis-server redis-tools
EXPOSE 6379
ENTRYPOINT ["/user/bin/redis-server"]
CMD []

构建redis镜像:

docker build -t ivan/redis .

创建并启动redis容器:

docker run -d -p 6379 --name redis ivan/redis

查看容器 6379端口映射到宿主机上的哪个端口:

docker port redis 6379

然后在宿主机上使用redis-cli测试redis-server在容器中的运行情况:

sudo apt-get -y install redis-tools
redis-cli -h 127.0.0.1 -p 49161

(假设容器的6379端口映射到了宿主机的49161端口上)。

我在宿主机的ubuntu上使用apt-get -y install redis-tools报无法定位redis-tools packages的错误,直接apt-get -y install redis-server 后可以使用redis-cli。

4、连接到Redis容器

一般有两种方法实现容器间的网络连接:

第一,Docker容器公开端口并绑定到本地网络接口,这样可以把容器里的服务在本地Docker宿主机所在的外部网络上公开(比如,把容器里的80端口绑到本地宿主机的高端口上)。

第二,内部网路。在安装Docker时,会创建一个新的网络接口,名字是docker0。docker0接口有符合RFC1918的私有IP地址,范围是172.16~172.30。docker0接口本身的地址是这个Docker网络的网关地址,也是所有Docker容器的网关地址。Docker默认会使用172.17.x.x作为子网地址,如果这个子网被占用,会在172.16~172.30这个范围内尝试创建子网。接口docker0是一个虚拟的以太网桥,用于连接容器和本地宿主网络。Docker宿主机的会有一系列名字以veth开头的接口,Docker每创建一个容器就会创建一组互联的网络接口。这组接口就像管道的两端,其中一端作为容器里的eth0接口,而另一端统一命名为以veth开头的名字,作为宿主机的一个端口。通过把每个veth*接口绑定到docker0网桥,Docker创建了一个虚拟子网,这个子网由宿主机和所有的Docker容器共享。

在运行的容器内部查看一下对望通信的路由信息,发现容器地址后的下一跳就是宿主网络上docker0的地址:

apt-get -yqq update && apt-get install -yqq traceroute
traceroute google.com

(3)Docker网络还有另外一个部分的配置才能允许建立连接:防火墙规则和NAT配置。这些配置允许Docker在宿主网络和容器间路由。在宿主机上查看IPTables NAT配置:

sudo iptables -t nat -L -n

容器默认是无法访问的。从宿主网络与容器通信时,必须明确指定打开的端口。

5、连接Redis

用docker inspect查看Redis容器的网络配置:

docker inspect redis

该命令展示了Docker容器的细节,包括配置信息和网络状况。可以使用-f标志只获取IP地址:

docker inspect -f '{{.NetworkSettings.IPAddress}}' redis

如果Docker宿主机运行在本地,可以直接使用Redis服务器的IP地址与Redis服务器通信。

这个方法有两个问题:第一,要在应用程序里对Redis容器的IP地址做硬编码;第二,如果重启容器,Docker可能会改变容器的IP地址。

6、让Docker容器互连

删除之前运行的redis容器和webapp容器:

docker rm -f webapp
docker rm -f redis

新建一个redis容器,与之前不同的是并不公开任何端口:

docker run -d --name redis ivan/redis

启动Web应用程序容器,并把它连接到新的Redis容器上去:

docker run -p 4567 --name webapp --link redis:db -t -i -v $PWD/webapp:/opt/webapp ivan/sinatra /bin/bash

--link编制创建了两个容器间的父子连接。这个标志需要两个参数:一个是要连接的容器名字,另一个是连接后容器的别名。这个例子中,把新容器连接到redis容器,并使用db作为别名。连接让父容器有能力访问子容器,并把子容器的一些连接细节分享给父容器,这些细节有助于配置应用程序并使用这个连接。(新创建的容器时父容器,连接到的容器时子容器)

连接也能得到一些安全上的好处。容器的端口不需要对本地宿主机公开。

出于安全原因,可以强制Docker只允许有连接的容器之间相互通信,需要在启动Docker守护进程时加上--icc=false标志,关闭所有没有连接的容器间的通信。

也可以把多个容器连接在一起。比如,如果想让这个Redis实例服务于多个Web应用程序,可以把每个Web应用程序的容器和同一个redis容器连接在一起。

被连接的容器必须运行在同一个Docker宿主机上。不同Docker宿主机上运行的容器无法连接。

Docker在父容器里的以下两个地方写入了连接信息:

  • /etc/hosts文件中;

  • 包含连接信息的环境变量中。

/etc/hosts文件中有连接指令创建的项,是redis容器的IP地址和该连接的对应的子容器别名。

如果重启了容器,容器的IP地址可能会发生变化。从Docker1.3开始,如果被连接的容器重启了,/etc/host文件中的IP地址会被新的IP地址更新。

在bash环境中运行env查看环境变量,可以看到一些以DB开头的环境变量。Docker在连接webapp和redis容器时,自动创建了以DB开头的环境变量。DB是创建连接时的子容器别名。这些环境变量主要包含以下信息:

  • 子容器的名字;

  • 子容器里运行服务使用的协议、IP和端口号;

  • 子容器里由Docker设置的环境变量的值。

这些环境变量会随容器不同而变化,取决于子容器是如何配置的。

7、测试容器连接情况

需要下载作者代码/code/5/sinatra/webapp_redis中的内容替换原sinatra/webapp的内容,然后后台启动webapp容器的/opt/webapp/bin/webapp。向web服务提交数据(假设映射到宿主机的端口是49160):

curl -l -H 'Accept:application/json' -d 'name=Foo&status=Bar' http://localhost:49160/json

用get方法测试提交情况:

cuil -i http://localhost:49160/json

5.3 Docker用于持续集成(Jenkins)

1、构建Jenkins和Docker容器

书中代码的Dockerfile无法构建成功,可能是由于版本升级造成的。去Github上下载更新过的代码把 5/jenkins/Dockerfile和dockerjenkins.sh放入构建环境的文件夹中。

Dockerfile中使用了VOLUME指令。从容器运行的宿主机上挂载一个卷。

构建成功后启动容器:

docker run -p 8080:8080 --name jenkins --privileged -d ivan/dockerjenkins

这里使用了一个新标志--privileged,它可以启动Docker的特权模式,允许我们以其宿主机具有的所有能力来运行容器,包括一些内核特性和设备访问。这是可以在Docker中运行Docker的必要能力。

让Docker在特权模式运行会有一些安全隐患。在这种模式下运行容器对Docker宿主机有root访问权限。

感谢各位的阅读!关于“在测试中如何使用Docker”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!


网站栏目:在测试中如何使用Docker
标题网址:http://scyanting.com/article/jsihes.html