docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库

主机规划

192.168.2.180 :jenkins
192.168.2.163 : gitlab
192.168.2.199 : registry
192.168.2.230 : docker server

compose文件部署jnekins

version: '3'

services:
  jenkins:
    image: jenkins/jenkins:lts
    container_name: jenkins
    hostname: jenkins
    ports:
      - "8088:8080"
    volumes:
      - /data/jenkins:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
  • 查看,没有启动成功
[root@jenkins jenkins]# docker-compose up -d
Creating jenkins ... done
[root@jenkins jenkins]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
  • 查看日志如下
[root@jenkins jenkins]# docker logs jenkins
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied

原因是本地挂载目录权限问题,将本地挂载目录属主属组改成和容器中的jenkins用户uid相同,(容器中的jenkins用户id为1000)

[root@jenkins jenkins]# chown -R  1000.1000 /data/jenkins/
  • 修改目录权限后重新启动容器
[root@jenkins jenkins]# docker start jenkins
jenkins
[root@jenkins jenkins]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                               NAMES
c0852fe3e63d        jenkins/jenkins:lts   "/sbin/tini -- /usr/…"   6 minutes ago       Up 4 seconds        50000/tcp, 0.0.0.0:8088->8080/tcp   jenkins

浏览器访问ip+8088登录jenkins

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

根据提示的位置找到登录的密码,在挂载目录下可以看到,不需要进入容器

[root@jenkins ~]# cat /data/jenkins/secrets/initialAdminPassword 
7c75815ce8554d018db1f9411f541949

安装方式选择第一种默认安装即可,部分插件等待安装完成后登录jenkins后自己按需安装

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》
初始化安装后设置账号密码等信息,设置登录的URL

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

  • 最后登陆的首页如下
    《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

测试jenkins容器内部的docker指令

jenkins容器中默认无法执行docker指令,使用挂载宿主机的docker指令经常会出现不同的问题,所以要先进入容器测试docker指令能不能正常运行

  • 容器内部执行docker命令出现两个问题
jenkins@jenkins:/$ ls /data/docker/
ls: cannot open directory '/data/docker/': Permission denied
#jenkins用户无法访问docker数据目录

jenkins@jenkins:~$ docker ps
docker: error while loading shared libraries: libltdl.so.7: cannot open shared object file: No such file or directory
#执行docker提示找不到对应的库文件

解决

  • 权限问题:修改docker数据目录的属主
[root@jenkins ~]# chown -R 1000 /data/docker/
  • 找不到libltdl.so.7库文件:修改docker-compose.yml文件,挂载宿主机对应库文件到容器

最终compose文件如下

version: '3'

services:
  jenkins:
    image: jenkins/jenkins:lts
    container_name: jenkins
    hostname: jenkins
    ports:
      - "8088:8080"
    volumes:
      - /data/jenkins:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker
      - /data/docker:/data/docker
      - /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7

jenkins容器打包时会用到maven工具,通过宿主机挂载的方式容器内部无法执行mvn工具,其他java,git指令默认安装了,maven可以在配置中选择自动安装。

修改配置文件后要重启jenkins

[root@jenkins jenkins]# docker-compose down
[root@jenkins jenkins]# docker-compose up -d

启动后再进入容器执行docker指令正常。

安装常用插件

登录首页 点击 系统管理 >> 插件管理 进行安装插件

  • Git Parameter Plug-In — gitlab版本控制,打包时指定Tag
  • Gitlab Hook Plugin — gitlab的webhook功能插件
  • GitLab Plugin —gitlab插件
  • Maven Integration plugin — maven插件
  • Publish Over SSH — 远程主机连接
  • SSH plugin

配置jenkins

配置 Publish over SSH

点击 系统管理 >> 系统设置 到最下面的 Publish over SSH 设置远程登录信息,如下:

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

配置SSH remote hosts (SSH plugin插件配置)

点击 凭据 >> 系统 >> 全局凭据 >> 添加凭据 ;添加容器中的jenkins SSH 远程连接到docker主机上的方式,这里可以使用账号密码的方式,也可以使用秘钥免密码登录。
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

点击 系统管理 >> 系统设置 找到 ssh remote host 添加远程登录的主机

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

配置git,jdk,maven

点击 系统管理 >> 全局工具配置 配置jdk,git,maven,(这里的几个工具,可以使用系统或容器中已经装好的配置,也可以选择在这里自动安装,容器中的工具路径要进入容器找到在这里配置,或者就用自动安装)

maven配置文件选择使用默认
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

JDK这里也选择了默认安装
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

配置git
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

选择自动安装maven
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

设置后 点击应用保存

配置gitlab

将jenkins容器中生成的公钥文件内容添加到gitlab中,Jenkins容器就可以通过本地的git向gitlab基于ssh的方式拉取代码到本地,然后进行下一步编译打包操作

登录到gitlab管理页面,点击 用户头像 >> settings,进入用户设置页面找到 SSH keys,添加jenkins容器中的公钥文件内容

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

添加公钥如下:
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

gitlab的英文界面看着挺费劲的,可以设置成中文

做到这里,jenkins的环境配置基本已经配置完了,下面就可以创建一个任务进行自动构建打包了

创建一个新的任务

  • 起一个任务名称,选择一个构建类型

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

  • 选择参数化构建,使用gitlab中的tag进行最终的镜像版本区分

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

  • 设置git仓库地址,这里拉取的代码是根据tag标签来获取的

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

  • 构建触发器,满足什么条件时自动构建,这里不做设置

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

build:到构建栏目时选择打包方式,这里使用maven,并且设置打包后的操作,配置如下:
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

jenkins容器将镜像推送到远程镜像仓库后,还需要下一步操作,就是远程登录到docker主机上运行新的容器,进行面的配置,点击build add step按钮,选择Execute shell script on remote host using ssh,设置远程docker主机要执行的指令,如下:

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

至此,所有任务配置项完成,点击应用保存,测试构建。

为了区分构建的版本,在gitlab新建一个tag为 1.4.4,构建时选择这个tag,打包成镜像后,该tag就成了镜像的版本号
《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

上面两处的指令:

容器内执行shell

cd /var/jenkins_home/workspace/test-dev/docker
cp -a ../target/demo-0.0.1-SNAPSHOT.jar ./
IMAGE=192.168.2.199:5000/tccp/demo:$Tag
docker build -t $IMAGE .
docker push $IMAGE

ssh到远程支持指令

IMAGE=192.168.2.199:5000/tccp/demo:${Tag}
docker rm -f demo
docker run --name demo -itd -p 8888:8080 $IMAGE

查看控制台输出信息如下:

Started by user yufu
Building in workspace /var/jenkins_home/workspace/test-dev
Cloning the remote Git repository
Cloning repository git@192.168.2.163:dev/test-prod.git
 > /usr/bin/git init /var/jenkins_home/workspace/test-dev # timeout=10
Fetching upstream changes from git@192.168.2.163:dev/test-prod.git
 > /usr/bin/git --version # timeout=10
using GIT_SSH to set credentials 
 > /usr/bin/git fetch --tags --progress git@192.168.2.163:dev/test-prod.git +refs/heads/*:refs/remotes/origin/*
 > /usr/bin/git config remote.origin.url git@192.168.2.163:dev/test-prod.git # timeout=10
 > /usr/bin/git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
 > /usr/bin/git config remote.origin.url git@192.168.2.163:dev/test-prod.git # timeout=10
Fetching upstream changes from git@192.168.2.163:dev/test-prod.git
using GIT_SSH to set credentials 
 > /usr/bin/git fetch --tags --progress git@192.168.2.163:dev/test-prod.git +refs/heads/*:refs/remotes/origin/*
 > /usr/bin/git rev-parse origin/v1.4.4^{commit} # timeout=10
 > /usr/bin/git rev-parse v1.4.4^{commit} # timeout=10
Checking out Revision 9b25eb6fd2d9ceb45ec35cde86f36e0a37810aa3 (v1.4.4)
 > /usr/bin/git config core.sparsecheckout # timeout=10
 > /usr/bin/git checkout -f 9b25eb6fd2d9ceb45ec35cde86f36e0a37810aa3
Commit message: "Update DemoApplication.java"
First time build. Skipping changelog.
[test-dev] $ /var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/maven/bin/mvn clean package
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.6.1:clean (default-clean) @ demo ---
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /var/jenkins_home/workspace/test-dev/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /var/jenkins_home/workspace/test-dev/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /var/jenkins_home/workspace/test-dev/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.20:test (default-test) @ demo ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ demo ---
[INFO] Building jar: /var/jenkins_home/workspace/test-dev/target/demo-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:1.5.8.RELEASE:repackage (default) @ demo ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.645 s
[INFO] Finished at: 2018-12-20T04:16:49Z
[INFO] Final Memory: 32M/267M
[INFO] ------------------------------------------------------------------------
[test-dev] $ /bin/sh -xe /tmp/jenkins8349948840798057187.sh
+ cd /var/jenkins_home/workspace/test-dev/docker
+ cp -a ../target/demo-0.0.1-SNAPSHOT.jar ./
+ IMAGE=192.168.2.199:5000/tccp/demo:v1.4.4
+ docker build -t 192.168.2.199:5000/tccp/demo:v1.4.4 .
Sending build context to Docker daemon   14.5MB

Step 1/6 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/6 : VOLUME /tmp
 ---> Using cache
 ---> faa497a7c7ef
Step 3/6 : ADD demo-0.0.1-SNAPSHOT.jar app.jar
 ---> 4e1a4cf92388
Step 4/6 : RUN bash -c 'touch /app.jar'
 ---> Running in 20d8b91e81d1
Removing intermediate container 20d8b91e81d1
 ---> fce500945189
Step 5/6 : EXPOSE 8080
 ---> Running in 64099ff10717
Removing intermediate container 64099ff10717
 ---> 05824d1a7601
Step 6/6 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
 ---> Running in 09973187e46d
Removing intermediate container 09973187e46d
 ---> 288b62069241
Successfully built 288b62069241
Successfully tagged 192.168.2.199:5000/tccp/demo:v1.4.4
+ docker push 192.168.2.199:5000/tccp/demo:v1.4.4
The push refers to repository [192.168.2.199:5000/tccp/demo]
868b9cf96dcb: Preparing
84b6bd138f7a: Preparing
35c20f26d188: Preparing
c3fe59dd9556: Preparing
6ed1a81ba5b6: Preparing
a3483ce177ce: Preparing
ce6c8756685b: Preparing
30339f20ced0: Preparing
0eb22bfb707d: Preparing
a2ae92ffcd29: Preparing
ce6c8756685b: Waiting
30339f20ced0: Waiting
0eb22bfb707d: Waiting
a2ae92ffcd29: Waiting
a3483ce177ce: Waiting
35c20f26d188: Layer already exists
6ed1a81ba5b6: Layer already exists
c3fe59dd9556: Layer already exists
ce6c8756685b: Layer already exists
30339f20ced0: Layer already exists
a3483ce177ce: Layer already exists
0eb22bfb707d: Layer already exists
a2ae92ffcd29: Layer already exists
84b6bd138f7a: Pushed
868b9cf96dcb: Pushed
v1.4.4: digest: sha256:aa125b7386d6bc24ea2ae78780a1f9e6e9f309b03e3259b8056af4f424c2257d size: 2424
[SSH] script:
Tag="v1.4.4"

IMAGE=192.168.2.199:5000/tccp/demo:${Tag}
docker rm -f demo
docker run --name demo -itd -p 8888:8080 $IMAGE

[SSH] executing...
Unable to find image '192.168.2.199:5000/tccp/demo:v1.4.4' locally
v1.4.4: Pulling from tccp/demo
7448db3b31eb: Already exists
c36604fa7939: Already exists
29e8ef0e3340: Already exists
a0c934d2565d: Already exists
a360a17c9cab: Already exists
cfcc996af805: Already exists
2cf014724202: Already exists
4bc402a00dfe: Already exists
450222d3f3df: Pulling fs layer
7b7100ff3582: Pulling fs layer
450222d3f3df: Verifying Checksum
450222d3f3df: Download complete
7b7100ff3582: Verifying Checksum
7b7100ff3582: Download complete
demo
450222d3f3df: Pull complete
7b7100ff3582: Pull complete
Digest: sha256:aa125b7386d6bc24ea2ae78780a1f9e6e9f309b03e3259b8056af4f424c2257d
Status: Downloaded newer image for 192.168.2.199:5000/tccp/demo:v1.4.4
46f31cdd611bdfac9c92c1ac09ead8e450d8c9014d14f412c9b07ee355b59b9f

[SSH] completed
[SSH] exit-status: 0

Finished: SUCCESS

至此,构建打包发布成功,登录到远程的docker主机上查看

[root@tccp ~]# docker image ls
REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
192.168.2.199:5000/tccp/demo                  v1.4.4              288b62069241        2 minutes ago       672MB
registry.cn-shanghai.aliyuncs.com/yufu/tccp   v1.4.1              4eab586a191a        2 hours ago         672MB

[root@tccp ~]# docker ps
CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS                  PORTS                               NAMES
46f31cdd611b        192.168.2.199:5000/tccp/demo:v1.4.4   "java -Djava.securit…"   3 minutes ago       Up 3 minutes            0.0.0.0:8888->8080/tcp              demo

访问服务测试

《docker部署jenkins+gitlab自动构建打包推送镜像至远程仓库》

其他注意的地方

上面的环境中国构建docker镜像是采用Dockerfile文件的方式镜像打包镜像,并且将Dockerfile文件和源码放在一起存在gitlab仓库,jenkins拉取代码时把Dockerfile文件一同下载下来,存放在jenkins工作目录中,工程目录名称和jenkins任务名称同名。

Dockerfile内容

FROM java:8
VOLUME /tmp
ADD demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

上面测试使用的示列代码

https://pan.baidu.com/s/16RzqIYX1MriJfoBOiVqRKg

总结

上面的环境测试只测试打包了单个jar包,通常我们打包的服务是比较多的,这种情况下,脚本的内容就比较复杂了,还有结合gitlab的webhook功能实现自动构建也很方便,以后有时间再慢慢研究这些功能吧。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注