什么是 CI/CD

持续集成(Continuous IntegrationCI):代码合并、构建、测试、部署都在一起,不断地执行这个过程,并对结果反馈。

持续部署(Continuous DeploymentCD):部署到测试环境、预生产环境、生产环境。

持续交付(Continuous DeliveryCD):将最终产品发布到生产环境,给用户使用。


流程图与机器资源分配

01.png

主机名 IP 作用
K8-200 192.168.1.200 Gitlab、Harbor
K8-210 192.168.1.210 Jenkins
K8-210 192.168.1.220 部署应用

三台机器均安装好 Docker


Gitlab

部署

# 创建目录
mkdir -p /data/gitlab/{config,logs,data}

# 执行 Docker 部署
docker run -itd -p 4433:443 -p 800:80 -p 222:22 --name gitlab --restart always -v /data/gitlab/config:/etc/gitlab -v /data/gitlab/logs:/var/log/gitlab -v /data/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce

# 修改配置文件
vim /data/gitlab/config/gitlab.rb
external_url 'http://192.168.1.200'  #IP 为宿主机 IP 地址
gitlab_rails['gitlab_ssh_host'] = '192.168.1.200'  #宿主机 IP 地址
gitlab_rails['gitlab_shell_ssh_port'] = 222  #启动时指定的宿主机 ssh 端口

# 重启
docker restart gitlab

# 获取 root 默认密码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
Password: pGkV/PmEx5znOJ/TmPVITaZFquGKI6w9fRqH67tabkE=

网页登陆地址:http://192.168.1.200:800/
登入后修改 语言密码

01.png

02.png

03.png

准备项目

01.png

02.png

03.png

推送代码到仓库

cd /usr/local/src/tomcat-java-demo-master/
git config --global user.name "lance"
git config --global user.email "[email protected]"
git init
git remote add origin http://192.168.1.200:800/root/java-demo.git
git add .
git commit -m "java-demo"
git push -u origin master

Gitlab 上检查

01.png


Harbor

部署

# 解包并修改配置文件
wget https://github.com/goharbor/harbor/releases/download/v2.5.3/harbor-offline-installer-v2.5.3.tgz
tar xvf harbor-offline-installer-v2.5.3.tgz
cd harbor/ && cp harbor.yml.tmpl harbor.yml

vim harbor.yml
# 此处 IP 可改为域名地址
hostname: 192.168.1.200
# 注释 https 相关的信息,修改登陆密码
harbor_admin_password: lance12345

# 安装 docker-compose
yum install -y https://mirrors.tuna.tsinghua.edu.cn/remi/enterprise/remi-release-7.rpm
yum install -y python36-devel python36-pip.noarch
pip3.6 install -U pip setuptools
pip3.6 install docker-compose

./prepare
./install.sh

# 开启主机允许使用 http 登录 harbor,此处 IP 可改为域名地址
vim /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.1.200"]
}

systemctl restart docker
docker-compose up -d

# 客户端 docker login 192.168.1.200 登录仓库

# 如后续启用 https,则需要配置好 https 后,执行 ./prepare,再执行 docker-compose down,最后执行 docker-compose up -d

# 如是私有证书,则需要将证书拷贝到 Docker 主机指定位置作为验证(此处以域名访问为例)
mkdir /etc/docker/certs.d/reg.harbor.com
cp reg.harbor.com.pem /etc/docker/certs.d/reg.harbor.com/reg.harbor.com.crt

Harbor 上检查

01.png

创建项目

02.png

03.png

制作 Tomcat 镜像

# 自备 Tomcat
tree /data/tomcat/
/data/tomcat/
├── apache-tomcat-8.5.43.tar.gz
├── Dockerfile

# 编写 Dockerfile
vim Dockerfile
FROM centos:7
MAINTAINER www.itwordsweb.net

ENV VERSION=8.5.43

RUN yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && \
    yum clean all && \
    rm -rf /var/cache/yum/*

ADD apache-tomcat-${VERSION}.tar.gz /usr/local/
RUN mv /usr/local/apache-tomcat-${VERSION} /usr/local/tomcat && \
    sed -i '1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"' /usr/local/tomcat/bin/catalina.sh && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/tomcat/bin

WORKDIR /usr/local/tomcat

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

# 构建镜像并上传到 Harbor
docker build -t tomcat:v1 .
docker tag tomcat:v1 192.168.1.200/library/tomcat:v1
docker login http://192.168.1.200/
docker push 192.168.1.200/library/tomcat:v1

220 机器配置可免 https 登录镜像仓库

# 开启主机允许使用 http 登录 harbor,此处 IP 可改为域名地址
vim /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.1.200"]
}
systemctl daemon-reload
systemctl restart docker.service

Jenkins

部署

# 自行准备 JDK8 与 Maven 安装包
# 请根据项目实际需要准备对应版本
tar xvf jdk-8u45-linux-x64.tar.gz
mv jdk1.8.0_45 /usr/local/jdk
tar xvf apache-maven-3.5.0-bin.tar.gz
mv apache-maven-3.5.0 /usr/local/maven

#配置 210 机器允许使用 http 登录 Harbor
vim /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.31.200"]
}

systemctl daemon-reload
systemctl restart docker.service

# 自定义 Jenkins 镜像
mkdir -p /data/jenkins

vim /data/jenkins/Dockerfile
FROM jenkins/jenkins:latest
USER root
# 把容器内的 jenkins 用户加入到 docker 组中
ARG dockerGid=999
RUN echo "docker:x:${dockerGid}:jenkins" >> /etc/group \
USER jenkins

cd /data/jenkins/ && docker build -t jenkins:v1 .

# Docker 部署
chown -R 1000:1000 /data/jenkins/ && docker run -itd --name jenkins --hostname jenkins --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /usr/local/maven:/usr/local/maven -v /usr/local/jdk:/usr/local/jdk -v /data/jenkins:/var/jenkins_home -v /etc/docker/daemon.json:/etc/docker/daemon.json -v /etc/localtime:/etc/localtime:ro -p 8080:8080 -p 50000:50000 jenkins:v1

# 重点参数解释
-v /var/run/docker.sock:/var/run/docker.sock 与 -v /usr/bin/docker:/usr/bin/docker 可以使 Docker 容器使用 Docker 命令
-v /usr/local/maven:/usr/local/maven 和 -v /usr/local/jdk:/usr/local/jdk 把宿主机的 jdk 和 maven 挂载到容器,给容器使用

# 查询配置密钥
cat /data/jenkins/secrets/initialAdminPassword 
dd1adb960de246e796e894f98c7f8aa2

配置 Jenkins

01.png

02.png

03.png

04.png

05.png

06.png

修改插件源及安装 sshpass

# 修改插件源
vim /data/jenkins/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
  </site>
</sites>

# 修改网络检测地址
sed -i "s#http://www.google.com/#https://www.baidu.com/#g" /data/jenkins/updates/default.json
 
sed -i "s#https://updates.jenkins.io/download#https://mirrors.tuna.tsinghua.edu.cn/jenkins#g" /data/jenkins/updates/default.json
 
# 重启 jenkins
docker restart jenkins

# 安装 sshpass
docker exec -it jenkins bash
apt-get update
apt-get install -y sshpass
exit

安装必须插件

01.png

02.png

03.png

04.png

添加 Harbor 项目用户信息以及 Gitlab 项目用户信息

请注意,实际环境需要做用户权限管理,一般情况下不建议直接使用管理员用户

01.png

02.png

03.png

04.png

05.png

06.png

创建流水线(以发布 java 项目为例)

01.png

02.png

03.png

04.png

流水线脚本

#!/usr/bin/env groovy

// 指定容器仓库地址
def registry = "192.168.1.200"
// 指定仓库项目名
def project = "java"
// 指定应用名
def app_name = "java-demo"
// 由 仓库地址+项目名+应用名+分支名+Jenkins Build 的数值 组成镜像名称
def image_name = "${registry}/${project}/${app_name}:${Branch}-${BUILD_NUMBER}"
// 指定 gitlab 项目地址
def git_address = "http://192.168.1.200:800/root/java-demo.git"
// 容器仓库登录的用户名密码 ID(需要在 Jenkins 添加凭据)
def docker_registry_auth = "7de518a8-f281-468a-aeab-26839b7720cd"
// Gitlab 仓库登录的用户名密码 ID(需要在 Jenkins 添加凭据)
def git_auth = "98c8cfa3-99a0-49da-a58b-dd6d9e2c024a"

// 配置 220 机器的登陆信息(此处为达到实验效果,采用明文设置)
def ssh_host ='192.168.31.220'
def ssh_user = 'root'
def ssh_password ='ITsupport.0'

// 正文
pipeline {
    agent any
    stages {
	    // 第一步,拉取代码
        stage('拉取代码'){
		    // 使用 checkout 参数来拉取代码
            steps {
              checkout([$class: 'GitSCM', branches: [[name: '${Branch}']], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
            }
        }
        // 第二步,编译代码
        stage('代码编译'){
		   // 使用 sh 在 Jenkins 上执行一些命令来构建代码
           steps {
             sh """
                JAVA_HOME=/usr/local/jdk
                PATH=$JAVA_HOME/bin:/usr/local/maven/bin:$PATH
                mvn clean package -Dmaven.test.skip=true
                """ 
           }
        }
        // 第三步,生成镜像并传输到容器仓库
        stage('构建镜像'){
           steps {
		        // withCredentials 用来做密码加密认证,登录容器仓库
                withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                // 使用 sh 在 Jenkins 上执行一些命令来生成镜像并传输到容器仓库
                // 编写 Dockfile
                // 运行 Dockerfile
                sh """
                  echo '
                    FROM ${registry}/library/tomcat:v1
                    LABEL maitainer lance
                    RUN rm -rf /usr/local/tomcat/webapps/*
                    ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
                  ' > Dockerfile
                  docker build -t ${image_name} .
                  docker login -u ${username} -p '${password}' ${registry}
                  docker push ${image_name}
                """
                }
           } 
        }
        // 第四步,把服务部署到 220 机器并运行
        stage('部署到 220 机器'){
           steps {
                // withCredentials 用来做密码加密认证,登录容器仓库
                withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                // 使用 sshpass 命令在远端服务器执行部署操作
                sh """
                  sshpass -p ${ssh_password} ssh -o StrictHostKeyChecking=no ${ssh_user}@${ssh_host} << reallsh
                  docker rm -f tomcat-java-demo 2> /dev/null
                  docker login -u ${username} -p '${password}' ${registry}
                  docker container run -itd --name tomcat-java-demo -p 8080:8080 ${image_name}
                  exit
                  reallsh
                  """
              }
           }
        }
    }
}

构建测试

01.png

02.jpg

至此,基于 Docker 使用 Jnekins 实现 Pipeline 流水线(CI/CD)部署已经完成,当然,这里只是个简单的例子,在实际项目中还需要根据实际项目来做一些调整,学无止境。


文章作者: Runfa Li
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Linux 小白鼠
Linux Linux Centos7 Centos7 自动化发布 docker gitlab jenkins 私有仓库 仓库 docker仓库 dockerfile cicd jenkinsfile
觉得文章不错,打赏一点吧,1分也是爱~
打赏
微信 微信
支付宝 支付宝