Docker:10---测试案例之(Docker与Jenkins进行持续集成测试、附加Docker-in-Docker)

一、本文目的

  • 在前面的文章中,所有的测试例子都是本地的、围绕着单个开发者的(就是说,如何让本地开发者使用Docker来测试本地网站或者引用程序)。现在来看看在多开发者的持续集成测试场景中如何使用Docker
  • Docker很擅长快速创建和处理一个或多个容器。这个能力显然可以为持续集成测试这个概念提供帮助。在测试场景里,用户需要频繁安装软件,或者部署到多台宿主机上,运行测试,再清理宿主机为下一次运行做准备
  • 在持续集成环境里,每天要执行好几次安装并分发到宿主机的过程。这为测试生命周期增加了构建和配置开销。打包和安装也消耗了很多时间,而且这个过程很恼人,尤其是需求变化频繁或者需要复杂、耗时的处理步骤进行清理的情况下
  • Docker让部署以及这些步骤和宿主机的清理遍历开销很低。为了演示这一点,我们将使用Kenkins CI构建一个测试流水线:首先,构建一个运行Dokcer的Kenkins服务器。为了更有意思些,我们会让Dokcer递归地运行在Docker内部
  • 一旦Jenkins运行起来,将展示最基础的单容器测试运行,最后将展示多容器的测试场景

备注

备注

  • 除了Jenkins,还有许多其他的持续集成工具,包括Strider和Drone.io这种直接利用Docker的工具,这些工具都是真正基于Docker的。另外,Jenkins也提供了一个插件,这样就可以不用使用我们将要看到的Dokcer-in-Docker这种方式了。使用Docker插件可能更简单,但我觉得使用Docker-in-Docker这种方式很有趣

本文的代码、文件链接

二、构建带有Jenkins的Docker容器

①创建工作目录

  • 与以往一样,创建一个jenkins目录,用来作为下面所有工作环境的主目录
mkdir jenkins

cd jenkins

②创建Dockerfile和脚本

  • 第一步:在jenkins目录下创建一个Dockerfile,用来下面构建镜像,内容如下:
touch Dockerfile

vim Dockerfile
FROM jenkins/jenkins:lts
MAINTAINER https://blog.csdn.net/qq_41453285
ENV REFRESHED_AT 2020-07-27

USER root
RUN apt-get -qq update && apt-get install -qq sudo
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN wget http://get.docker.com/builds/Linux/x86_64/docker-latest.tgz
RUN tar -xvzf docker-latest.tgz
RUN mv docker/* /usr/bin/

USER jenkins
RUN /usr/local/bin/install-plugins.sh junit git git-client ssh-slaves greenballs chucknorris ws-cleanup
  • 第二步:在jenkins目录下创建一个dockerjenkins.sh的脚本,并赋予可执行权限,脚本的内容如下:
touch dockerjenkins.sh

vim dockerjenkins.sh

chmod 0755 dockerjenkins.sh
#!/bin/bash

# First, make sure that cgroups are mounted correctly.
CGROUP=/sys/fs/cgroup

[ -d $CGROUP ] ||
  mkdir $CGROUP

mountpoint -q $CGROUP ||
  mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup $CGROUP || {
    echo "Could not make a tmpfs mount. Did you use -privileged?"
    exit 1
  }

# Mount the cgroup hierarchies exactly as they are in the parent system.
for SUBSYS in $(cut -d: -f2 /proc/1/cgroup)
do
  [ -d $CGROUP/$SUBSYS ] || mkdir $CGROUP/$SUBSYS
  mountpoint -q $CGROUP/$SUBSYS ||
    mount -n -t cgroup -o $SUBSYS cgroup $CGROUP/$SUBSYS
done

# Now, close extraneous file descriptors.
pushd /proc/self/fd
for FD in *
do
  case "$FD" in
  # Keep stdin/stdout/stderr
  [012])
    ;;
  # Nuke everything else
  *)
    eval exec "$FD>&-"
    ;;
  esac
done
popd

docker daemon &
exec java -jar /opt/jenkins/jenkins.war
  • 现在jenkins目录中有如下两个文件:

③构建镜像

  • 第一步:输入下面的命令创建一个新镜像,镜像的名字为dongshao/dockerjenkins
sudo docker build -t dongshao/dockerjenkins .

  • 构建的时间会很长,我这边构建了半个小时,最终的结果如下所示:

  • 第二步:查看新创建的镜像
sudo docker images

④运行容器

  • 第一步:基于上面的镜像,我们输入下面的命令创建一个新容器:
    • -d:将容器以守护进程的模式在宿主机中运行
    • -p:将Docker容器的8080端口映射到宿主机的8080端口上
    • --name:容器的名字取名为jenkins
    • --privileged:启动Docker的特权模式
    • 最后一个参数:上面创建的镜像的名称
sudo docker run -d -p 8080:8080 --name jenkins --privileged -d dongshao/dockerjenkins

  • 备注(--privileged选项):让Docker运行在--privileged特权模式会有一些安全风险。在这种模式下运行容器对Docker宿主机拥有root访问权限。确保已经对Docker宿主机进行了恰当的安全保护,并且只在确实可信的域中使用特权访问Docker宿主机,或者仅在有类似信任的情况下运行容器
  • 第二步:查看一下新创建的容器:
# 查看当前正在运行的容器
sudo docker ps

访问Jenkins

  • 第一步:现在我们就可以去访问jenkins主页了,输入“ip:8080”即可进入。进入之后会让你输入密码(见第二步)

  • 第二步:初次进入需要输入密码,可以从Docker的日志容器中查看,如下所示日志的信息很多,内容大致为:
    • 上面的:Jenkins服务运行时打印的日志
    • 中间的:我们需要的密码()
sudo docker logs -f jenkins

  • 第三步:将上面图片中中间所指的密码输入进去即可
  • 第四步:之后会选择让你安装插件,选择默认的插件即可,选择之后进入下面的界面

  • 第五步:创建一个管理员用户,账号密码自己随便输入

  • 第六步:选择保存并完成

  • 第七步:选择重启

  • 第八步:重启之后刷新网页,输入上面创建的用户名和密码即可登录成功

  • 第九步:登陆成功

三、创建新的Jenkins作业

  • 上面Jenkins服务器已经运行起来了,现在我们可以来创建一个Jenkins作业了
  • 第一步:点击主页中的“create new jobs”创建新作业

  • 第二步:进入之后添加任务的名称(此处命名为“Docker_test_job”),并选择第一个,然后点击“确定”去到下一个界面

  • 第三步:进入之后选择“高级”去到下一个界面

  • 第四步:进入之后勾选“使用自定义的工作空间”,并填入下面的内容作为Directory(目录),这个目录是运行Jenkins的工作空间
/tmp/jenkins-buildenv/${JOB_NAME}/workspace

  • 第五步:接着往下滑动,选择"Git",并添加下面的Github仓库链接,这个仓库包含了一些基于Ruby的RSpec测试
https://github.com/jamtur01/docker-jenkins-sample.git

  • 第六步:接着往下滑动,在“增加构建步骤”中选择“执行shell”,跳到下一个画面

  • 第七步:来到这个画面之后,把下面的脚本(jenkins_single_shell_step)输入进去,该脚本用来启动测试和Docker。内容如下:
    • 1.使用包含上面Git仓库的Dockerfile创建一个新的Docker镜像(旋转到第八步看解析,再回到此处继续查看,此处不讲解)
    • 2.创建一个包含Jenkins工作空间(就是签出Git仓库的地方)的目录,会把这个目录挂载到Docker容器,并在这个目录里执行测试
    • 3.然后创建容器,并且运行了测试。在容器里,把工作空间挂载到/opt/project目录。之后执行命令切换到这个目录,并执行rake spec来运行RSPec测试
    • 上面容器启动之后我们就可以拿到容器的ID
    • Docker在启动容器时支持--cidfile选项,这个选项会让Docker截获容器ID并将其存到--cidfile选项指定的文件里,如--cidfile=/tmp/containerid.txt
    • 4.使用docker attach命令进入容器,得到容器执行时输出的内容
    • 5.使用docker wait命令,该命令会一直阻塞,直到容器里的命令执行完成才会返回容器退出时的返回码。变量RC捕获到容器退出时的返回吗
    • 6.清理环境,删除刚刚创建的容器
    • 7.使用容器的返回码退出,这个返回码应该就是测试执行结果的返回码。Jenkins依赖这个返回码得知作业的测试结果是成功哈市失败
# 脚本名为jenkins_single_shell_step
# 1.构建用于此作业的镜像
IMAGE=$(docker build . | tail -1 | awk '{ print $NF }')

# 2.构建挂载到Docker的目录
MNT="$WORKSPACE/.."

# 3.在Docker里执行编译测试
CONTAINER=$(docker run -d -v "$MNT:/opt/project/" $IMAGE /bin/bash -c 'cd /opt/project/workspace && rake spec')

# 4.进入容器,这样可以看到输出的内容
sudo docker attach $CONTAINER

# 5.等待程序退出,得到返回码
RC=$(docker wait $CONTAINER)

# 6.删除刚刚用到的容器
docker rm $CONTAINER

# 7.使用刚才的返回码退出整个脚本
exit $RC

  • 第八步:Git仓库的Dockerfile内容如下
    • 上面的脚本首先使用包含上面Git仓库的Dockerfile创建一个新的Docker镜像
    • 这个Dockerfile提供了想要执行的测试环境,Dockerfile的内容如下,可以在https://github.com/turnbullpress/docker-jenkins-sample/blob/master/Dockerfile中查看
    • 该Dockerfile构建了一个ubuntu宿主机,安装了Ruby和RubyGems,之后安装了两个gem:rspec和ci_reporter_rspec。这样构建的镜像可以用于测试典型的基于Ruby且使用RSpec测试框架的应用程序
    • ci_reporter_rspec gem会把RSpec的输出转换为JUint格式的XML输出,并交给Jenkins做解析。一会儿就能看到这个转换的结果

  • 第九步:接着点击“增加构建后操作步骤”,加入一个“Publish JUnit test result report”(公布JUint测试结果报告)的动作

  • 第十步:接着上面,在“测试报告(XML)”中输入下面的内容,spec/reports/目录是ci_reporter gem的XML输出的位置,找到这个目录会让Jenkins处理测试的历史结果和输出结果
spec/reports/*.xml

  • 第十一步:点击保存按钮,保存这个新作业

  • 第十二步:回到Jenkins主页中,就可以看到这个新作业了

四、运行Jenkins作业

  • 上面我们创建了一个Jenkins作业,现在可以来运行这个作业了
  • 第一步:点击这个作业

  • 第二步:来到这个作业的界面中,之后点击左侧的“立即构建”按钮

  • 备注:第一次测试时,可能会因为构建新的镜像而等待较长一段时间。但是,下次运行测试时,因为Docker已经准备好镜像了,执行速度会快很多
  • 第三步:点击“构建历史”,就会出现这个作业

  • 第四步:之后点击那个圆点,然后再点击“任务”的名称就会查看这个测试运行的详细信息

  • 第五步:测试运行的详细信息如下所示

  • 第六步:点击“控制台输出”可以查看作业已经执行的命令

  • 很遗憾,运行到这里错误了,不知道为什么,查看了控制台的输出,发现是脚本错了,脚本执行到第3步的时候命令出错,也不知道什么原因,后来在脚本的docker命令之前加上sudo还是执行失败
  • 就先到这里吧,不搞了

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/107613066
今日推荐