2018-10-03 docker构建本地ci环境

看到docker的介绍,感觉这个东西用于在本地构建环境还是非常好用的。他不仅免除了大量的配置过程,还让电脑环境干净。当需要删除一个应用时,只需要停止对应的docker容器,然后删除即可。因此,尝试在本地使用docker来构建jenkins+nexus的个人构建环境。

关于docker的基础知识,直接看官方中文网站上的例子就足够了,我就不啰嗦了。
官方中文网站,上面有官方入门教程的翻译
还有RUNOOB也很不错
自己看帖子就好。

1. 首先,是安装docker-ce

根据官方提供的centos安装docker-ce的例子代码:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

考虑,docker是否其实也有提供fedora的软件源呢?输入

http://mirrors.aliyun.com/docker-ce/linux/ 

发现果然有提供fedora发行版本的软件源:

《2018-10-03 docker构建本地ci环境》 阿里代理docker软件源

于是执行如下代码:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/fedora/docker-ce.repo

检查dnf软件源列表,可以发现docker软件源已经可用:

dnf repolist 

结果如下:

《2018-10-03 docker构建本地ci环境》 安装好的docker软件源.png

好了,现在可以安装docker了。最新版本的docker,根据社区和企业商用,提供了不同的发行版,分别是docker-ce 和 docker-ee,商用版(也就是docker-ee)需要付费。我们个人使用,docker-ce 就可以了:

dnf -y install docker-ce

安装docker过程到此为止。等安装完毕后,执行service docker start 就可以启动docker守候进程了。

2. 安装 nexus

先检查是否已经存在nexus的镜像。可以直接上docker的官方镜像仓库搜索,也可以直接执行docker命令搜索:

docker search nexus

可以看到有官方提供的镜像:

《2018-10-03 docker构建本地ci环境》 nexus的docker镜像.png

于是,执行如下命令来下载nexus3的镜像:

docker pull sonatype/nexus3

之后,可以使用命令查看本地的镜像列表:

docker images

可以看到,我本地已经有了该镜像:

《2018-10-03 docker构建本地ci环境》 本地镜像列表.png

这样,接下来就可以安装容器了。
在这里,有几个问题需要注意:

  • docker的运行容器中的端口,和主机的端口需要映射,否则无法访问
  • docker容器内的软件存储路径,和主机的文件系统存储路径,需要进行映射,否则你很难访问容器内软件的资料。

我的做法,是将各种容器的创建脚本写在对应的.sh 文件内,然后存放在/install/docker 目录下。
对于nexus,其创建容器的脚本文件 create-nexus.sh 内容如下:

docker run -d -p 8081:8081 --name nexus -v /appdata/nexus:/nexus-data sonatype/nexus3

其中:

  • -d 表示该容器以独立进程运行
  • -p 8081:8081 表示主机端口8081(冒号前的8081)用于映射到容器内的8081端口(冒号后的8081)。原因是在nexus的容器的makefile中,我们可以看到nexus的运行端口就是8081。
  • –name nexus 表示将该容器命名为 nexus,以后可以通过该名字操作该容器
  • -v /appdata/nexus:/nexus-data 表示将主机的 /appdata/nexus 映射到 容器内的/nexus-data 目录。原因是在 nexus容器的makefile中,nexus使用容器内的 /nexus-data 目录作为数据目录使用。
  • sonatype/nexus3 命令最后的这个字串,是镜像的名字,表示使用该镜像来创建容器。

好了,创建容器的脚本就好了。但在正式执行该脚本之前,还需要对主机上的 /appdata/nexus 目录进行预处理,否则启动容器时将因为没有权限而失败,因为容器内的用户,和主机的用户是独立,没有关系的:

$cd /appdata
$mkdir nexus
$chmod 777 /appdata/nexus
$cd /install/docker
$chmod 754 create-nexus.sh

好了,现在可以通过这个脚本来创建并启动nexus的容器了:

/install/docker/create-nexus.sh

如果不使用该容器了,可以通过如下命令停止容器:

docker stop nexus

其中,nexus是我们创建容器时给容器取的名字,详见创建容器脚本。
我们也可以在下次再重新启动前面创建好的容器:

docker start nexus

就和启动本地应用一样简单快捷。
如果要查看nexus的日志,可以通过如下命令:

docker logs -f nexus

该指令等同于查看本地安装应用的日志文件的命令:

tail -100f xxx.log

如果要查看容器内的进程,可以执行如下命令:

docker top

如果容器操作错了,想重新安装nexus,也非常简单快捷:

$docker stop nexux
$docker rm nexux
$cd /appdata
$rm -rf /appdata/nexus
$cd /install/docker
$./create-nexus.sh

可以通过

http://localhost:8180/nexus

来访问刚安装好的nexus,其默认管理员账号是 admin/admin123

2. 安装jenkins

首先在docker官方仓库网页搜索jenkins的镜像。注意,要安装的是 jenkins/jenins:lts,不是jenins,后者已经被官方废弃了。

通过如下命令准备好环境:

$docker pull jenkins/jenkins:lts
$mkdir /appdata/jenkins
$chmod 777 /appdata/jenkins
$vi /install/create-jenkins.sh

最后一个命令打开的编辑器中,输入内容:

docker run -id -p 8080:8080 -p 50000:50000 --privileged=true --name jenkins -v /appdata/jenkins:/var/jenkins_home jenkins/jenkins:lts

执行如下命令启动容器:

$chmod 754 /install/docker/create-jenkins.sh
$/install/docker/create-jenkins.sh
$docker logs -f jenkins

最后,完成jenkins内部配置即可。

3. 问题与解决方案

3.1. nexus无法搜索代理仓库

启动后的nexus,没有自动下载被代理库(比如中央库)的索引,因此搜索没有结果。也没有向nexus2那样,提供主动下载远端库的选项。目前还没有找到办法。

==》2018-10-14更新:

因为前两天系统重装,我重新安装了docker并重配了nexus容器。结果这一次无法搜索代理仓库的问题自己消失了。
回忆并对比了一下两次安装过程的差异,估计前一次无法搜索的原因,在于那次安装没有结束的时候,就重启了nexus容器,导致nexus的初始化过程没有完全完成。

具体过程如下:
刚完成容器启动时,我没有看容器的日志,只是执行了docker ps命令,看到容器允许起来了,就在浏览器中访问nexus。结果发现nexus无法访问,就急躁的判断是启动失败,直接重启了容器。结果重启后,发现还是无法访问。这时才想到查看容器日志,结果发现了一大堆乱七八糟的异常。
不得已,只能删除nexus数据文件目录,删除nexus容器,然后重新创建容器。这一次,我吸取教训,一直开着log,果然经过了整整5分钟,才完成nexus初始化。等初始化完成后,才去访问界面,这一次成功进入。
再次完成nexus配置后,搜索 commons-lang3,成功搜索。

根据这个现象,初步估计上一次创建nexus容器,也没有等初始化彻底完成就重启了容器,当时虽然容器显示启动成功,也能访问界面,但不知道哪里的初始化过程被中断了,导致搜索maven-central失败。

3.2. jenkins启动后许多插件无法安装

原来安装docker时,没有使用 官方仓库的web界面,而是直接使用命令来搜索仓库并根据概述选择了jenkins这个镜像:

[root@wangqaing ~]# docker search jenkins
NAME                                   DESCRIPTION                                     STARS               OFFICIAL            
jenkins                                Official Jenkins Docker image                   3858                [OK]                
jenkins/jenkins                        The leading open source automation server       993                                     
jenkinsci/jenkins                      Jenkins Continuous Integration and Delivery …   338                                     

因为它被显示为官方构建的镜像。但安装完毕后,发现许多插件都报无法安装。
通过命令:

docker logs -f jenkins

查看日志,发现这些插件都说因为jenkins版本太低,建议从v2.60.3 升级到 v2.73.3或以上:

Oct 04, 2018 2:33:21 PM jenkins.InitReactorRunner$1 onTaskFailed
SEVERE: Failed Loading plugin Pipeline: Declarative v1.3.2 (pipeline-model-definition)
java.io.IOException: Pipeline: Declarative v1.3.2 failed to load.
 - You must update Jenkins from v2.60.3 to v2.73.3 or later to run this plugin.
 - Pipeline: Shared Groovy Libraries v2.12 failed to load. Fix this plugin first.
    at hudson.PluginWrapper.resolvePluginDependencies(PluginWrapper.java:626)
    at hudson.PluginManager$2$1$1.run(PluginManager.java:516)
    at org.jvnet.hudson.reactor.TaskGraphBuilder$TaskImpl.run(TaskGraphBuilder.java:169)
    at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:282)
    at jenkins.model.Jenkins$7.runTask(Jenkins.java:1090)
    at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:210)
    at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:117)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

这就让我感到奇怪了。难道官方的镜像其实不是最新的吗?
我从官方仓库的web界面去搜索,才发现镜像 jenkins 的介绍里,说该镜像已经被deprecated了,官方建议使用 jenkins/jenins:lts
好吧。
先通过命令:

docker stop jenkins

停止jenkins容器运行。
再通过命令:

docker rm jenkins

删掉已安装的容器。
最后通过命令:

docker rmi jenkins

删掉旧镜像,重新下载并安装当前的推荐镜像:

docker pull jenkins/jenkins:lts

调整创建容器的脚本内容为:

ocker run -id -p 8080:8080 -p 50000:50000 --privileged=true --name jenkins -v /appdata/jenkins:/var/jenkins_home jenkins/jenkins:lts

清空并重建jenkins工作空间:

$rm -rf /appdata/jenkins
$mkdir /appdata/jenkins
$chmod 777 /appdata/jenkins

创建并启动jenkins容器:

$/install/docker/create-jenkins.sh

最后查看日志:

$jenkins logs -f jenkins

完成jenkins的配置并使用。

3.3. 容器时区和本地时区不一致

启动容器后,在查看日志时,偶尔发现容器内的时区和本地时区不一致,容器时间少了8个小时。

  1. 创建容器时就复制宿主的时区和本地时间到容器

最傻瓜的解决方案:在第一次允许 docker run 时,就已经意识到这个问题并将容器内地时区设置为和宿主机器的一样。
假如我要修改容器nexus的时区,那么:

$docker run -d -p 8081:8081 --name nexus -v /appdata/nexus:/nexus-data -v /etc/localtime:/etc/localtime sonatype/nexus3
$docker stop nexus
$docker start nexus

但事情往往没有这么理想。如果我们已经创建了容器,那么如何修改该容器的时区呢?

先进入容器命令行环境查看时间:

$docker exec -it nexus bash
$date

然后退出容器命令行,在宿主命令行拷贝本地时区文件到容器:

$docker cp /etc/localtime jenkins:/etc/localtime

其中,第一个 /etc/localtime 是宿主机器上的文件;jenkins 是容器的名字,这里也可以用容器的id来替换;冒号后面的 /etc/localtime ,是拷贝到docker容器后的路径。
现在,我们来验证一下:

$date

可以看到,现在系统时间已经更改过来了。

但是我们如果在jenkins界面上看,会发现jenkins的时间,仍然比北京时间晚8个小时。如果进入 系统管理->系统信息 菜单,看“系统属性”列表的最后一个属性,可以看到其时区是 etc/UTC,这代表格林尼治时间。显然不对。

$cat /etc/timezone

可以看到显示内容也是 etc/UTC。也就是说jenkins容器的时区还需要修改。而该文件是ubuntu的文件,redhat系列的fedora上,是没有这个文件的。解决方案是在本地编辑一个timezone文件,其内容为:

Asia/Shanghai

然后再将该文件拷贝到容器内,覆盖原来的/etc/timezone文件,最后重启容器即可:

docker cp timezone jenkins:/etc/timezone
docker restart jenkins

最后再次进入jenkins浏览器界面,会发现时区已经正常。

3.4. 启用docker的aliyun镜像加速

今天在拉去官方docker hub的镜像时,速度特别慢。正好我有阿里云的账户,又正好发现阿里云有docker的镜像加速服务,就使用了。具体过程是直接参考的阿里云的说明文档。

  1. 登录阿里云
  2. 进入容器镜像服务菜单:

    《2018-10-03 docker构建本地ci环境》 容器镜像服务.png

  3. 选择镜像加速器,可以看到自己的专属加速器地址
  4. 配置docker使用镜像地址:
$cd /etc/docker
$vi /etc/docker/daemon.json

将如下脚本写入 daemon.json:

{
“registry-mirrors”: [“https://sa2gfpxw.mirror.aliyuncs.com“]
}

  1. 重启容器
$service docker stop
$service docker start

好了,现在拉取镜像的速度飞起来了。

    原文作者:FredWorks
    原文地址: https://www.jianshu.com/p/61adada18438
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞