扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章给大家分享的是有关在测试中如何使用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”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流