本实践介绍了利用Jenkins和docker技术,如何实现CI/CD的各环节的步骤,包括环境准备,代码提交,编译程序,构建镜像,部署,测试,一套完整的安装部署流程。

一、应用场景问题

       一个产品项目,开发测试所需要处理的事情大概有:申请测试机器、编码实现、部署测试、集成等,而其中申请测试机器和部署测试是两个最耗时且低技术含量的操作。那如何简化整个流程,使开发人员一提交代码后,就能快速将应用部署到一台服务器上,以提高项目的开发效率?
     测试环境和正式环境,由于两者环境的不同,比如操作系统、中间件版本、环境变量、安装路径等等,导致泄露到正式环境的bug通常是由于这种原因引起,那如何尽可能保证这两个环境的一致性,以提高项目的质量?

二、解决思路及步骤

基于docker容器技术的自动化部署,程序员提交代码到gitLab仓库,可触发Jenkins触发构建项目,拉取代码,编码、再打包镜像,推送到镜像仓库,并由Jenkins执行脚本把docker镜像Run起来。

整个流程需要用到如下的工具:
gitlab:源代码版本管理工具,开发人员提交代码到GitLab仓库
Jenkins:Jenkins人工或定时触发构建项目,拉取代码,编码、再打包镜像,推送到镜像仓库
harbor:存放镜像的仓库

jenkins迁移到docker jenkins docker cicd_tomcat

jenkins迁移到docker jenkins docker cicd_tomcat_02

 环境准备:

主机名                          IP                          角色

gitlab.jackyops.com    192.168.3.17          gitlab

reg.jackyops.com       192.168.3.16           jenkins   harbor

node01                        92.168.3.10            docker 

操作系统centos 7.3  关闭防火墙 ,selinux 

三、gitlab仓库部署

安装GitLab仓库并启动

[root@gitlab gitlab]# curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
[root@gitlab gitlab]# yum install -y gitlab-ce
# 配置和启动GitLab
[root@gitlab gitlab]# gitlab-ctl reconfigure

GitLab常用命令
sudo gitlab-ctl start    # 启动所有 gitlab 组件;
sudo gitlab-ctl stop        # 停止所有 gitlab 组件;
sudo gitlab-ctl restart        # 重启所有 gitlab 组件;
sudo gitlab-ctl status        # 查看服务状态;
sudo gitlab-ctl reconfigure        # 启动服务;
sudo vim /etc/gitlab/gitlab.rb        # 修改默认的配置文件;
gitlab-rake gitlab:check SANITIZE=true --trace    # 检查gitlab;
sudo gitlab-ctl tail        # 查看日志;

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_03

或者直接使用git创建仓库

[root@gitlab gitlab]# yum install git -y
# 创建Git用户并设置密码
[root@gitlab gitlab]# useradd git
[root@gitlab gitlab]# passwd git
# 创建仓库
[root@gitlab gitlab]# su - git
[root@gitlab gitlab]# mkdir solo.git
[root@gitlab gitlab]# cd solo.git
[root@gitlab gitlab]# git --bare init
# 访问创建的这个仓库
[root@gitlab gitlab]# git clone git@gitlab.jackyops.com:/home/git/solo.git

四、安装Jenkins

      Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台。这是一个免费的源代码,可以处理任何类型的构建或持续集成。集成Jenkins可以用于一些测试和部署技术。Jenkins是一种软件允许持续集成。

产品设计成型 -> 开发人员开发代码 -> 测试人员测试功能 -> 运维人员发布上线 
持续集成 (Continuous integration,简称CI) 
持续交付(Continuous delivery) 
持续部署(continuous deployment)

官方下载链接:https://jenkins.io/download/

jenkins迁移到docker jenkins docker cicd_tomcat_04

下载长期TLS维护版本,本次是通过下载Generic Java package(.war)包安装Jenkins

maven官网下载: http://maven.apache.org/download.cgi

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_05

下载 apache-maven-3.5.4-bin.tar.gz

在安装前需要具备Java&maven环境,安装方式如下:

[root@reg ~]# tar zxf jdk-8u45-linux-x64.tar.gz 
[root@reg ~]# tar zxf apache-maven-3.5.4-bin.tar.gz
[root@reg ~]# mv jdk-8u45-linux-x64 /usr/local/jdk8
[root@reg ~]# mv apache-maven-3.5.4-bin /usr/local/maven
[root@reg ~]# vi /etc/profile
export MAVEN_HOME=/usr/local/maven
export JAVA_HOME=/usr/local/jdk8
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
[root@reg ~]# source /etc/profile

在reg.jackyops.com主机安装Jenkins,下载Tomcat二进制包将war包到webapps下

[root@reg ~]# wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war 
[root@reg ~]# wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.32/bin/apache-tomcat-8.5.32.tar.gz 
[root@reg ~]# tar zxf apache-tomcat-8.5.32.tar.gz 
[root@reg ~]# mv apache-tomcat-8.5.32 /opt/tomcat-jenkins
[root@reg ~]# rm /opt/tomcat-jenkins/webapps/* -rf 
[root@reg ~]# unzip jenkins.war -d /opt/tomcat-jenkins/webapps/ROOT 
[root@reg ~]# /opt/tomcat-jenkins/bin/startup.sh
[root@reg ~]# tailf /opt/tomcat-jenkins/logs/catalina.out
... 
Jenkins initial setup is required. An admin user has been created and a password generated. 
Please use the following password to proceed to installation: 

3kd844lde167fd4b8ab62f9497d3242ldsfs 

This may also be found at: /root/.jenkins/secrets/initialAdminPassword ...

以上成功的部署完Jenkins,访问Jenkins http://192.168.3.16:8080/jenkins

第一步:输入上面日志输出的密码:3kd844lde167fd4b8ab62f9497d3242ldsfs ,或者从本机/root/.jenkins/secrets/initialAdminPassword文件获取,点击继续
第二步:点击“选择插件来安装”
第三步:保持默认,点击继续
第四步:创建管理员用户,保存并完成
第五步:设置Jenkins访问地址,保持默认,点击保存完成

安装完成,开始使用Jenkins:

jenkins迁移到docker jenkins docker cicd_git_06

五 安装dokcer

分配在reg.jackyops.com,node01主机安装Docker,如下:

1. 安装依赖包
# yum install -y yum-utils   device-mapper-persistent-data   lvm2
2. 添加Docker源
#  yum-config-manager --add-repo     https://download.docker.com/linux/centos/docker-ce.repo
3. 安装Docker CE 
# yum -y install docker-ce
4 .配置加速器
# curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://bc437cce.m.daocloud.io
5. 添加开机自启,启动服务
# systemctl start docker
 # systemctl enable docker6. 配置国内镜像(可选)
# cat /etc/docker/daemon.json 
 {
 "registry-mirrors": [ "https://registry.docker-cn.com"],
 "insecure-registries":["jackyops.com","192.168.3.16","reg.jackyops.com"]
 }

六  部署harbor私有仓库

       Harbor是镜像仓库,那么就应当是存储镜像的,这个可能是大多数接触harbor的人的一个误区,当深入了解以后才发现,镜像的存储harbor使用的是官方的docker registry服务去完成,至于registry是用本地存储或者s3都是可以的,harbor的功能是在此之上提供用户权限管理、镜像复制等功能,提高使用的registry的效率。

安装harbor之前需要先安装 docker-compose,harbor下载地址:https://github.com/goharbor/harbor/releases

# unzip docker-compose-linux-x86_64.zip 
# cp docker-compose /usr/bin/
# chmod +x /usr/bin/docker-compose 
# tar -xvf harbor-offline-installer-v1.5.1.tgz 
# cd harbor
# vim harbor.cfg
  hostname = reg.jackyops.com
#  ./prepare
# ./install.sh 
# 查看容器是否运行
#  docker-compose ps

jenkins迁移到docker jenkins docker cicd_tomcat_07

七. 构建Tomcat基础镜像

     JAVA程序必须有JDK环境才可以运行,为了减少镜像文件大小及提高性能,这里直接把JDK放到宿主机上,容器以挂载形式使用。
在reg.jackyops.com,node01上安装JDK:

# tar zxvf jdk-8u45-linux-x64.tar.gz 
 # mv jdk-8u45-linux-x64 /usr/local/jdk
 Tomcat基础镜像Dockerfile:# cat Dockerfile
FROM centos:7
MAINTAINER zhouyuchun

ENV VERSION=8.5.32

ENV JAVA_HOME /usr/local/jdk

RUN yum -y update && \
    yum install wget curl -y && \
    yum clean all && \
    wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz && \
    tar zxf apache-tomcat-${VERSION}.tar.gz && \
    mv apache-tomcat-${VERSION} /usr/local/tomcat && \
    rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* && \
    mkdir -p /usr/local/tomcat/webapps/ROOT  && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

WORKDIR /usr/local/tomcat

EXPOSE 8080
CMD ["./bin/catalina.sh", "run"]

构建镜像并上传到registry:

# docker pull reg.jackyops.com/ops/tomcat8:v1.0 -f Dockerfile .
# docker push reg.jackyops.com/ops/tomcat8:v1.0

 

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_08

 八. Jenkins配置全局工具配置

主页面 -> 系统管理 -> 全局工具配置

指定JDK、Maven、Git路径

jenkins迁移到docker jenkins docker cicd_git_09

如果Jenkins主机没有git命令,需要安装Git:
# yum install git -y

 

九、Jenkins安装必要插件

1. Jenkins安装必要插件
主页面 -> 系统管理 ->管理插件

jenkins迁移到docker jenkins docker cicd_docker_10

安装SSH与Git Parameter插件。

插件说明:

  • SSH:用于SSH远程Docker主机执行Shell命令
  • Git Parameter:动态获取Git仓库Branch、Tag

2. 配置SSH插件
第一步:先创建一个用于连接Docker主机的凭据。
主页面 -> 凭据 -> 系统 -> 右击全局凭据 -> 添加凭据:

jenkins迁移到docker jenkins docker cicd_tomcat_11

输入连接node01主机的用户名和密码: 

jenkins迁移到docker jenkins docker cicd_tomcat_12

第二步:添加SSH远程主机
主页面 -> 系统管理 -> 系统设置 -> SSH remote hosts:

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_13

十. 上传solo项目代码到gitlab仓库

从Github拉取开源博客系统solo:

# git clone https://github.com/b3log/solo
# cd solo
移除旧的推送地址,添加新的:
# git remote remove origin 
# git remote add origin git@reg.jackyops.com/solo.git
提交代码到Git仓库并创建tag:
# touch src/main/webapp/test.html
# git add .
# git commit -m “init jacky”
创建标签:
# git tag 3.0.0
推送到Git服务器:
# git push origin 3.0.0

十一. Jenkins创建项目并发布测试

主页》新建任务>输入任务名,构建一个Maven项目

jenkins迁移到docker jenkins docker cicd_tomcat_14

如果没有显示“构建一个Maven项目”选项,需要在管理插件里安装“Maven Integration plugin”插件。
配置Git参数化构建:

jenkins迁移到docker jenkins docker cicd_docker_15

动态获取GitLab仓库tag,与用户交互选择Tag发布:

jenkins迁移到docker jenkins docker cicd_git_16

指定项目Gitlab仓库地址:

jenkins迁移到docker jenkins docker cicd_tomcat_17

修改*/master为$Tag,Tag是上面动态获取的变量名,表示根据用户选择打代码tag版本。

设置maven构建命令选项:

jenkins迁移到docker jenkins docker cicd_tomcat_18

利用pom.xml文件构建solo项目。
在Jenkins本机镜像构建与推送到harbor镜像仓库,并SSH远程连接到node01主机使用推送的镜像创建容器:

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_19

图中,在Jenkins主机执行的Shell命令如下:

docker login reg.jackyops.com --username=jacky --password=Jacky123
REPOSITORY=reg.jackyops.com/project/solo:${Tag}
# 构建镜像
cat > Dockerfile << EOF
FROM reg.jackyops.com/ops/tomcat8:v1.0
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY target/*.war /usr/local/tomcat/webapps/ROOT.war
WORKDIR /usr/local/tomcat
CMD ["./bin/catalina.sh", "run"]
EOF
docker build -t $REPOSITORY .
# 上传镜像
docker push $REPOSITORY

图中,SSH远程node01主机执行的Shell命令如下:

REPOSITORY=reg.jackyops.com/project/solo:${Tag}

# 部署
docker rm -f blog-solo |true
docker images $REPOSITORY  |true
docker container run -d --name blog-solo -v /usr/local/jdk:/usr/local/jdk -p 89:8080 $REPOSITORY

注:容器名称blog-solo,暴露宿主机端口89,即使用宿主机IP:89访问blog-solo项目。
blog-solo项目已配置完成,开始构建:

选择tag,开始构建:

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_20

jenkins迁移到docker jenkins docker cicd_docker_21

jenkins迁移到docker jenkins docker cicd_git_22

最终访问的web界面如下

jenkins迁移到docker jenkins docker cicd_jenkins迁移到docker_23

如果输出上述页面说明是正常的,页面没有加载成功样式,需要修改下项目里访问地址。

Jenkins+docker的CI/CD环境搭建完成,可以模拟提交代码并打tag测试自动化发布流程。