Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录

前言:

本文只包含部署单节点的后端应用或接口api,不含链接数据库,不包含链接web服务器中间件(nginx),需自行根据实际需求,在运行容器的时候添加其他功能节点的链接,如--link mysql_test:mysql.test.com,如需部署完整web服务项目,可以考虑使用docker-compose等工具统一部署。

一,安装Harbor:

1.步骤和流程可以参考该文章https://blog.csdn.net/liuyunshengsir/article/details/79976520

2.其余需要补充的是,在docker版本19.03.4中,假如安装的harbor没有配置HTTPS安全访问,而使用HTTP访问协议的话,需要给docker添加非安全仓库,以便进行访问,否则会提示证书和不安全的问题,拒绝访问,具体步骤如下

编辑配置文件/etc/docker/daemon.json并重启docker服务systemctl restart docker.service

{
  "registry-mirrors":["http://hub-mirror.c.163.com","https://registry.docker-cn.com"],
  "insecure-registries":["10.0.7.229"],
  "max-concurrent-downloads":10
}

其中"insecure-registries":["10.0.7.229"],数据段即为添加的非安全仓库,而harbor也是部署在10.0.7.229这台服务器上,而"registry-mirrors"代表安全仓库,可添加就近的镜像源地址以供下载或者上传其他docker镜像时候获取加速

3.默认docker pull [IMAGE_NAME] 或者push 镜像的时候使用的是安全仓库,要使用刚部署的私有仓库harbor则需要

docker login -u 用户名 -p 密码 10.0.7.229

登录到私有仓库后再进行后续镜像的上传docker push和下载docker pull操作

二,安装Gitlab:

1.拉取gitlab镜像,这里选取了社区中文翻译版

docker pull twang2218/gitlab-ce-zh:latest

2.启动gitlab容器,分别映射服务端口和数据目录,以及系统时区

docker run -d --hostname tgitlab.bond520.com -p 8443:443 -p 48080:80 -p 8022:22  --name gitlab_test --restart always
-v /docker_test/docker_volume/gitlab/config:/etc/gitlab -v /docker_test/docker_volume/gitlab/logs:/var/log/gitlab -v /docker_test/docker_volume/gitlab/data:/var/opt/gitlab -v  /etc/localtime:/etc/localtime twang2218/gitlab-ce-zh:latest

命令说明:

--hostname tgitlab.bond520.com   //设置容器主机名为tgitlab.bond520.com

-p 8443:443   //映射使用HTTPS协议访问gitlab时的443端口到宿主机的8443

-p 48080:80   //映射使用HTTP协议访问gitlab时的80端口到宿主机的48080

-p 8022:22    //映射SSH到容器内的端口22到宿主机的8022

--name gitlab_test   //容器名设置为gitlab_test

--restart always  //设置容器自动重启

-v /docker_test/docker_volume/gitlab/config:/etc/gitlab   //映射宿主机的目录到容器对应目录中,作为gitlab的配置文件目录

-v /docker_test/docker_volume/gitlab/logs:/var/log/gitlab   //映射宿主机的目录到容器对应目录中,作为gitlab的日志输出目录

-v /docker_test/docker_volume/gitlab/data:/var/opt/gitlab   //映射宿主机的目录到容器对应目录中,作为gitlab的数据目录

-v  /etc/localtime:/etc/localtime    //映射宿主机的系统时间配置文件到容器中,同步系统时间

3.在gitlab客户端的host文件配置10.0.7.227 tgitlab.bond520.com,即可使用tgitlab.bond520.com:48080进行访问

4.登陆gitlab创建用户,新建项目仓库,上传代码,打标签tag,git上传代码可参考

https://blog.csdn.net/BearStarX/article/details/84785468

https://www.cnblogs.com/chenhuichao/p/9631754.html

三,安装Jenkins:

1.由于国内环境在使用官方镜像部署的时候下载插件使用的仓库地址的下载速度十分的缓慢,所以使用已更换为国内源的jenkins镜像,项目地址如下

https://github.com/jenkins-zh/jenkins-formulas

里面也有使用说明和用法介绍。这里我个人是在该中文镜像的基础下,编写一个Dockerfile来构建所需的镜像,Dockerfile内容如下

FROM jenkins/jenkins:lts
LABEL maintainer="[email protected]"
USER root
#替换jenkins更新中心和插件下载源
ENV JENKINS_UC https://updates.jenkins-zh.cn
ENV JENKINS_UC_DOWNLOAD https://mirrors.tuna.tsinghua.edu.cn/jenkins

ENV JENKINS_OPTS="-Dhudson.model.UpdateCenter.updateCenterUrl=https://updates.jenkins-zh.cn/update-center.json"
#关闭安装引导
ENV JENKINS_OPTS="-Djenkins.install.runSetupWizard=false"

#替换jenkins初始化脚本,内含重新设置证书目录
COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/init.groovy
#替换jenkins更新中心地址,即插件选项里的高级选项设置
COPY hudson.model.UpdateCenter.xml /usr/share/jenkins/ref/hudson.model.UpdateCenter.xml
#替换SSL证书以便使用新的插件下载镜像源
COPY mirror-adapter.crt /usr/share/jenkins/ref/mirror-adapter.crt

#替换系统的软件下载源为阿里云镜像源
RUN echo '' > /etc/apt/sources.list.d/jessie-backports.list \
  && echo "deb http://mirrors.aliyun.com/debian jessie main contrib non-free" > /etc/apt/sources.list \
  && echo "deb http://mirrors.aliyun.com/debian jessie-updates main contrib non-free" >> /etc/apt/sources.list \
  && echo "deb http://mirrors.aliyun.com/debian-security jessie/updates main contrib non-free" >> /etc/apt/sources.list
#执行系统软件版本升级
RUN apt-get update
#调整系统时区
RUN echo "Asia/Shanghai" > /etc/timezone

#新增docker用户组并修改组id,之后把用户jenkins添加为docker组成员,容器启动默认使用jenkins用户建立服务进程,要使用docker工具则必须在同一个用户组下
ARG dockerGid=999
RUN echo "docker:x:${dockerGid}:jenkins" >> /etc/group
USER jenkins

接着在前面提到的github项目地址中把init.groovy   hudson.model.UpdateCenter.xml   mirror-adapter.crt下载下来,和刚才新建的Dockfile放在同一个目录下,切换到该目录,然后开始构建jenkins镜像

docker build -t jenkins:configured .

镜像构建完成后,启动一个容器实例,完成部署,启动命令如下

docker run -d --name jenkins_test --restart always --link gitlab_test:tgitlab.bond520.com -v \ &&
/docker_test/docker_volume/jenkins_home:/var/jenkins_home -v /etc/localtime:/etc/localtime \ &&
-v /docker_test/docker_volume/jdk/jdk1.8.0_162:/var/jdk1.8.0_162 -v /docker_test/docker_volume/maven/apache-maven-3.6.3:/var/apache-maven-3.6.3 \ &&
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -p 38080:8080 -p 50001:50000 \ && jenkins:configured

命令说明如下:

--name jenkins_test   //容器名

--restart always   //容器自动重启

--link gitlab_test:tgitlab.bond520.com //表示链接到刚才启动的命名为gitlab_test的容器实例,在jenkins实例中别名用tgitlab.bond520.com代替,之后jenkins和gitlab相通之后才能下载和拉取gitlab上的代码

-v /docker_test/docker_volume/jenkins_home:/var/jenkins_home   //表示持久化jenkins的数据目录

-v /docker_test/docker_volume/jdk/jdk1.8.0_162:/var/jdk1.8.0_162  //添加不同的jdk版本到容器中,可以根据需要操作

-v /docker_test/docker_volume/maven/apache-maven-3.6.3:/var/apache-maven-3.6.3   //添加maven工具到容器中,根据需要操作

-v /var/run/docker.sock:/var/run/docker.sock   和   -v $(which docker):/usr/bin/docker

//以上两项,是让jenkins容器也可以使用宿主机的docker工具,让jenkins可以把应用构建成docker镜像推送到私库并运行,此处是运用了docker-in-docker的相关技术,可以参考以下英文文档https://tutorials.releaseworksacademy.com/learn/the-simple-way-to-run-docker-in-docker-for-ci

-p 38080:8080     //映射jenkins的访问端口8080为宿主机的38080

-p  50001:50000    //映射jenkins的主从集群的slave默认通信端口50000为宿主机的50001

启动期间可以通过docker logs -f [容器id]  查看容器日志是否出现异常,并获取jenkins的默认登陆密码,也可以通过jenkins容器所映射的宿主机目录/docker_test/docker_volume/jenkins_home/secrets下的initialAdminPassword文件查看初始密码。之后系统会提示新建管理员用户和设置用户密码,便可使用管理员用户进行登录和操作。

2.接着进行jenkins的配置和所需插件的安装,此次需要通过gitlab作为代码仓库,构建maven项目,并由jenkins所在主机执行脚本和构建docker镜像,因此所需安装的插件和说明如下:

SSH plugin    //让jenkins所在主机能够使用ssh命令远程连接到其他主机上执行命令等操作

Maven Integration plugin  //项目配置里添加maven构建的相关功能

Git plugin     //项目配置里添加git获取代码库的相关功能

Git Parameter Plug-In   //使git插件能够获取代码的指定版本并进行构建,也可以把版本号作为变量供构建过程调取和使用,前提需要在代码仓库gitlab里打过标签tag

Docker plugin       //使jenkins在构建过程中能够使用docker相关功能

Localization: Chinese (Simplified)      //简体中文汉化,可选

插件安装完毕后,重启jenkins容器docker restart [容器id],也可使用jenkins系统内的插件安装完毕后重启功能

然后是配置maven,docker,git,jdk的可执行文件所在位置,依次打开系统管理--全局工具配置,如下图:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第1张图片

注意此处JDK也可使用默认设置,即根据jenkins容器内系统的环境变量JAVA_HOME决定所使用的JDK。

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第2张图片

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第3张图片

之后保存设置,接着打开系统管理--系统配置,设置远程主机连接,此处需要安装上文提到的SSH插件才会出现该配置项,如下图:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第4张图片

笔者在配置该项的时候,点击添加凭据按钮出现无响应的问题,重启jenkins容器情况依旧,所以采用预先在系统配置菜单处添加凭据,再回到这里进行选用。管理员用户登录后,在主菜单处依次点击凭据--系统--全局凭据--添加凭据,如下图:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第5张图片

四,新建Jenkins任务,构建并试运行:

(此处以Java项目为例,其他语言的项目可根据实际调整)

1.准备工作,新建tomcat8:base镜像作为后台应用运行的基础镜像:

FROM centos6-base
LABEL maintainer="[email protected]"
# 调整容器内时区为上海时区
RUN echo "Asia/Shanghai" > /etc/timezone
# 安装JDK环境,设置其环境变量
ADD jdk1.8.0_162 /usr/local/java
ENV JAVA_HOME /usr/local/java
ENV JAVA_BIN $JAVA_HOME/bin
ENV JRE_HOME $JAVA_HOME/jre
ENV PATH $PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
# 添加tomcat到容器内
ADD apache-tomcat-8.5.28 /usr/local/tomcat8
# 开放tomcat的web服务默认访问端口8080
EXPOSE 8080
# 容器启动时执行启动tomcat服务
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]

此处的centos6-base为dockerhub上centos6的64位系统基础镜像,可以根据实际选用,其次需要注意添加到容器内的apache-tomcat-8.5.28和jdk1.8.0_162需和Dockerfile处于同一目录下。

然后在Dockerfile的目录下运行

docker build -t 10.0.7.229/test_project/tomcat8:base .       //构建镜像

docker login -u root -p Chen@1989 10.0.7.229          //登录10.0.7.229上的harbor私库

docker push 10.0.7.229/test_project/tomcat8:base    //推送镜像到私库上,以便后续使用

2.在安装了maven插件Maven Integration plugin的前提下,添加maven项目,否则不会出现该项,如下图:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第6张图片

3.配置项目构建选项和参数,docker-vod-test为新建任务时候指定的项目名称,如下:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第7张图片

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第8张图片

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第9张图片

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第10张图片

注意此时新建的Dockerfile是生成在jenkins的项目根目录下,其他配置项需要注意相对路径问题,最后保存设置。

4.最后,确保远程主机和jenkins容器网络连通,jenkins点击构建该项目即可部署到上文指定的远程主机10.0.7.227上。

五,遇到的问题:

1.安装jenkins时候遇到国内地区下载和更新插件缓慢的情况,可以根据上文中提到的替换更新中心UpdateCenter的配置项解决,或者直接使用docker中文社区提供的镜像,里面已配置好国内下载源并已对系统汉化,具体见上文安装jenkins篇

2.启动容器时日志出现Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?的报错,是由于在把宿主机的文件目录映射到容器内时候,文件从属权限的问题,以jenkins容器为例,该容器的默认运行用户是jenkins,用户id为1000,则需要把宿主机上的文件目录权限也更改为一致,即chown -R 1000:1000 [宿主机目录],即可正常读写数据

3.某些旧版本jenkins在右上角出现提示系统更新时候,点击更新无法自动安装和替换原系统的老文件,需要外部上传新版的jenkins.war包到容器内,再由容器启动时候通过初始化脚本来解包和运行,容器内旧war包的位置可以通过在容器内执行whereis jenkins查看,默认jenkins镜像在/usr/share/jenkins/内,把新版war包先拷贝到宿主机上的映射目录,接着进入容器内执行cp替换即可,也需注意war包的权限问题,参考第2点。

4.忘记jenkins的密码,修改jenkins根目录下config.xml中true为false,然后重启jenkins,之后在系统管理--全局安全配置--安全域 处启用jenkins专有用户数据库,然后点击管理用户,即可重新设置密码

5.docker v19.03.4版本,想通过修改服务配置文件/var/lib/systemd/system/docker.service,添加修改EnvironmentFile=-/etc/default/docker
EnvironmentFile=-/etc/sysconfig/docker

ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS --containerd=/run/containerd/containerd.sock

接着在/etc/default/docker和/etc/sysconfig/docker中添加修改DOCKER_OPTS="xxxx"

然后执行systemctl daemon-reload 和systemctl restart docker  重启docker服务

发现添加的DOCKER_OPTS参数项都不生效,疑似该版本无效 

6.构建jenkins镜像的时候可不进行添加jdk到容器内的操作,可以先试运行原镜像是否自带jdk

7.尽量不使用docker commit CONTAINERID [REPOSITORY[:TAG]]提交容器内的修改并制作新镜像,commit一次就会增加新的镜像修改层,导致镜像体积变大,根据docker容器是无状态的核心思想,如非必要,对原镜像尽量少改动和修改,否则违背docker轻量化,服务(容器)启动快的特点

补充问题:

使用一段时间后发现在使用jenkins构建项目时候报错,报错信息为:

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/auth: dial unix /var/run/docker.sock: connect: permission denied

字面理解是在jenkins容器内使用docker命令的时候出现权限错误,于是进入到jenkins容器内(593为jenkins容器的id号),查看jenkins用户组:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第11张图片

发现用户jenkins所属用户组在docker用户组之内,接着又查看系统用户组配置文件:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第12张图片

发现用户组id为995(此处笔者已经把错误的用户组id由995改回到993),相当于用户jenkins已不在docker用户组内,接着再查看从docker宿主机挂载过来的套接字docker.sock的文件状态:

Docker环境下Jenkins+Gitlab+Harbor的持续集成和自动发布(CI/CD)的部署流程和问题记录_第13张图片

发现/var/run/docker.sock的用户组也变成了995(此处由于笔者已经把错误改正过来,所以用户组能正确显示为docker)。此外docker的执行文件/usr/bin/docker所有用户都有执行权限“x”,这个没有问题。

所以下面需要进入到jenkins容器里,使用groupmod命令把用户组docker的id修改成993,如下图:

之后使用newgrp命令更新用户组属性即可:

以上容器内的操作如果提示权限不足,可以使用root用户身份进入容器再执行:

之前一直使用该配置构建镜像,为何从宿主机挂载的docker.sock的文件从属发生变化的问题目前仍不清楚,只能临时先使用修改用户组id的方法解决。

参考文章:

https://www.jianshu.com/p/8b1241a90d7a

https://www.jianshu.com/p/8103f2a8339b

https://blog.csdn.net/lyfqyr/article/details/84068063

https://www.shangyexinzhi.com/article/523683.html

https://blog.csdn.net/weixin_43840640/article/details/100597073

https://www.cnblogs.com/chenhuichao/p/9631754.html

你可能感兴趣的:(容器技术,运维,jenkins,ci/cd,harbor,gitlab)