Docker + Jenkins + Gitlab 自动化构建部署


一、概述

本次主要通过 Docker+Gitlab+Jenkins 来实现自动化集成和部署的全过程,通过 Docker 容器,节约了我们的部署时间,只要把镜像拉取下来,并做好相应的端口映射,文件路径映射,就可以进行访问了,其部署过程也比较简单,但是得明白 Docker 的工作原理,拉取镜像的相关流程。其应用场景就不言而喻了,通过 Gitlab+Jenkins 研发人员能更方便的进行代码提交、代码合并、版本回退等操作,相比于传统的提交方式,极大地提高了工作效率。

非 docker 方式的部署的 CICD 我前面的博客有详细介绍,感兴趣的可以去了解了解Jenkins + Gitlab 前后端项目自动化构建部署

二、部署

2.1 规划

1、服务器

OS配置用途备注
CentOS 8(10.20.10.62)6C/8GDocker+Jenkins+Gitlab+maven+node实际生产中CICD的配置稍微给高点
CentOS 8(10.20.10.69)6C/8Gapplication作为应用测试(模拟远程服务器)

2、资源

(1)Docker

  • Docker 版本:20.10.2
  • 资源路径:https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-ce-20.10.2-3.el8.x86_64.rpm

(2)Jenkins

  • Jenkins 版本:2.263.1(实际生产中pull稳定版)
  • Docker 直接pull镜像(jenkins/jenkins:2.263.1)
  • 资源路径:http://updates.jenkins-ci.org/download/war/

(3)Gitlab

  • Gitlab 版本:13.7.1
  • Docker 直接pull镜像(gitlab/gitlab-ce:13.7.1-ce.0)
  • 资源路径:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el8/

2.2 安装 Docker

国内源安装:使用 aliyun docker yum 源安装新版 Docker

(1)删除已安装的Docker

# dnf -y remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine

(2)安装依赖

# dnf install -y epel*
# dnf install -y yum-utils device-mapper-persistent-data lvm2 git
# dnf install -y https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm

注:centos8 默认使用 podman 代替docker,所以需要安装 containerd.io 新版本,否则报错

(3)配置阿里云Docker Yum源

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

(4)安装Docker

# dnf install -y docker-ce

(5)启动Docker服务:

# systemctl start docker && systemctl enable docker

(6)查看docker版本状态:

# docker -v        # 简洁
Docker version 20.10.2, build 2291f61

# docker version   # 详细

(7)查看docker运行状态:

# systemctl status docker

(8)配置加速器

该加速器为阿里云加速器。

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://q1rw9tzz.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload && systemctl restart docker

2.3 安装 Jenkins

(1)拉取 Jenkins 镜像

# docker pull jenkins/jenkins:2.263.1

(2)端口/路径映射

# docker run -itd -u root --privileged=true  --name jenkins --restart=always -p 2021:8080 -p 50000:50000 -v /home/data/jenkins:/var/jenkins_home -v /home/data/scedu:/data/jenkins -v /var/run/docker.sock:/var/run/docker.sock -v /usr/local/maven:/usr/local/maven -v /usr/local/nodejs:/usr/local/nodejs -e JAVA_OPTS=-Duser.timezone=Asia/Shanghai jenkins/jenkins:2.263.1

参数说明:
-itd                 # -i:标准输入输出 -t:分配一个终端或控制台 -d:后台启动
-u root              # 指定容器的用户
--privileged=true    # 指定容器是否为特权容器,特权容器拥有所有的capabilities
--name jenkins       # 容器实例名
--restart=always     # 容器随docker自启动,因为重启docker时,默认容器都会被关闭
-p                   # 映射端口(容器暴露的端口)
-v                   # 映射目录(给容器挂载存储卷)
-e                   # 指定环境变量

注意:
1. 将容器8080、50000端口映射到宿主机(映射8080即可),映射端口不要和宿主机冲突
2. 将容器对应的数据目录映射到宿主机上(实现数据持久化)
3. 将宿主机node、maven等前后台构建工具(环境变量)映射到容器中
4. Jenkins镜像创建的容器自带Git工具(/usr/bin/git)
5. Jenkins镜像创建的容器自带java环境(/usr/local/openjdk-8/bin/java)

(3)浏览器访问

http://10.20.10.62:2021/

2.4 安装 Gitlab

(1)拉取 Gitlab 镜像

# docker pull gitlab/gitlab-ce:13.7.1-ce.0

(2)创建映射目录

# mkdir -p /home/data/gitlab/{etc,log,dada}

(3)端口/路径映射

# docker run -itd -u root --privileged=true  --name gitlab --restart=always -p 443:443 -p 2080:80 -p 2022:22 -v /home/data/gitlab/etc:/etc/gitlab -v /home/data/gitlab/log:/var/log/gitlab -v /home/data/gitlab/data:/var/opt/gitlab -v /home/data/gitlab/git-data:/home/gitlab/git-data gitlab/gitlab-ce:13.7.1-ce.0

注意:
映射端口不要和宿主机有冲突,否则无法启动容器(而仅创建容器)

三、验证

3.1 Jenkins 访问测试

如下图,可正常访问http://10.20.10.62:2021/

中间省略了插件安装、用户名设置等步骤。

注意:开始访问时会让你输入一串密码,改密码路径为:/home/data/jenkins/secrets/initialAdminPassword(或Jenkins容器中:界面会有具体路径提示)

在这里插入图片描述

基本配置:

  1. 全局配置:

    在这里插入图片描述

  2. 系统配置:

    详细的配置可参考我之前的博客(非Docker方式部署)

3.2 Gitlab 访问测试

如下图,可正常访问。

在这里插入图片描述

3.3 Jenkins+Gitlab 测试

1. Gitlab 性能测试

(1)创建测试项目
在这里插入图片描述

(2)上传公钥

$ ssh-keygen -t rsa -C "xxxxxxxxx@163.com"   # Gitlab创建的用户的邮箱
$ cat ~/.ssh/id_rsa.pub

注:将cat的内容上传至 Gitlab 服务对应的位置,目的是为了在项目 clone 时免密。

(3)给用户配置 Git

$ git config --global user.email "xxxxxxxxx@163.com"   # Gitlab创建的用户的邮箱
$ git config --global user.name "zhurongsen"           # Gitlab创建的用户

注:zhurongsen 用户及对应的邮箱是我在 Gitlab 中创建的用户

(4)在本地 clone 项目

  • SSH方式:

    $ git clone ssh://git@10.20.10.62:2022/scedu/test.git
    

    注意格式:我的 Gitlab 服务的 22 端口映射到了宿主机的 2022 端口了,所以在 clone 的时候必须跟上。

  • HTTP方式:

    $ git clone http://10.20.10.62:2080/scedu/test.git
    

    注意格式:我的 Gitlab 服务的 80 端口映射到了宿主机的 2080 端口了,所以在 clone 的时候必须跟上。

    与 SSH 方式不同的是,HTTP 方式每次 clone 都需要输入用户名和密码(用户名和密码是在 Gitlab 服务上创建的)

(5)修改完后合并推送

在这里插入图片描述

至此,说明 Gitlab 可用!

2. Jenkins 构建项目至本地服务器

(1)系统设置

这里主要是做一些基础的设置,如添加环境变量、邮箱等等。

(2)全局工具配置

持续集成需要用的哪些工具,就需要在这里添加配置,例如 JDK。

(3)新建项目

(4)配置项目

(5)源码管理

就是配置拉取代码的地方,可以git或SVN

分别上传公钥和私钥:私钥上传至 Jenkins 中,公钥上传至 Gitlab 中。目的是为了 Jenkins 和Gitlab 建立关系来拉取代码(即项目代码的来源)。

注意ssh格式:ssh://git@10.20.10.62:2022/zhurs/test.git

(6)本地构建

构建成功(SUCCESS),表明 Jenkins 基本功能可用(需注意点详见最后FAQ)

在这里插入图片描述

3. Jenkins 构建项目至远程服务器

思路:Jenkins 安装 publish over ssh 插件,配置远程服务器相关信息,并进行测试,详细的配置可参考我之前的博客(非Docker方式部署)。如需自动化构建,可安装 webhook 插件(当 Gitlab 有代码更新时,会自动构建)。

  • Jenkins 配置远程服务器信息

    在这里插入图片描述

  • 新建maven工程项目(以构建后端实例进行演示)

  • maven工程项目配置

  • 构建项目

    在这里插入图片描述

    # 到10.20.10.69服务器对应的目录看包是否构建成功
    # 如下结果,说明成功构建到远程服务器
    # ls /home/data/scedu/
    mail-service-bak.jar
    

    :以上操作仅仅是以 Docker 方式的CICD部署与项目构建,一般在实际生产中构建完成后还有相应的部署,即运行后台程序等,具体操作不再演示,其实很简单,就是几行脚本的问题。

四、FAQ

1、安装docker提示 containerd.io 版本过低

  • 问题描述:

    CentOS8 安装 Docker 报错(提示 containerd.io 版本过低)

    # dnf -y install docker-ce
    Last metadata expiration check: 0:00:16 ago on Thu 07 Jan 2021 10:36:31 AM CST.
    Error: 
     Problem: package docker-ce-3:20.10.2-3.el7.x86_64 requires containerd.io >= 1.4.1, but none of the providers can be installed
      - cannot install the best candidate for the job
      - package containerd.io-1.4.3-3.1.el7.x86_64 is filtered out by modular filtering
    (try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
    
  • 解决方案1:

    下载版本大于1.4.1的 containerd.io,然后再重新安装docker即可解决问题

    # dnf install -y https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm
    # dnf -y install docker-ce
    
  • 解决方案2:

    安装指定docker旧版本,不要安装最新的 containerd.io

    # dnf -y install docker-ce-18.03.0.ce
    

2、需注意点:centos 版本问题

  • 问题描述:

    对于 centos7.6 以下的版本,在安装 Docker 前,需要进行软件更新操作,否则无法安装。

  • 解决方案:

    # yum update -y
    

3、在 clone 项目的时候需注意

  • 问题描述:

    在 clone 的时候失败(无法clone项目)

  • 解决方案:

    由于我是使用 Docker 来部署的应用,为了防止和宿主机端口冲突,因此对端口和目录做了相应的映射,所以在 clone 的时候加上对应的端口即可 clone。

4、Jenkins 构建 shell 命令报错

  • 问题描述:

    在 docker 运行的 Jenkins 容器中,在使用 shell 命令是总是报错,提示说文件不存在。如下图所示:

    在这里插入图片描述

  • 解决方案:

    在这里插入图片描述

    因为是 docker 运行的 Jenkins 容器,所以执行 cp 后面的目标路径为容器里面的路径(即Jenkins执行的shell指令都是在Jenkins容器中进行的)

    报错的原因是:容器里面没有该路径。解决方法就是:在容器中创建相应的目录(-v 参数可自动创建),并将该目录映射到宿主机目录中即可。

5、gitlab 推送代码报错

  • 问题描述:

    $ git push origin dev
    To ssh://10.20.10.62:2022/mygroup/myproject.git
     ! [rejected]        dev -> dev (non-fast-forward)
    error: failed to push some refs to 'ssh://10.20.10.62:2022/mygroup/myproject.git'
    hint: Updates were rejected because the tip of your current branch is behind
    hint: its remote counterpart. Integrate the remote changes (e.g.
    hint: 'git pull ...') before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details
    
  • 解决方案:

    出现上述错误的原因在于远程仓库中的文件和我们本地的仓库有差异,比如我的远程仓库的dev分支有test.txt文件,而我现在clone下来的dev分支没有test.txt文件,就会导致上述错误。解决方案如下:

    git pull --rebase origin dev
    

    git pull命令用于从另一个存储库或本地分支获取并集成(整合),取回远程主机某个分支的更新,再与本地的指定分支合并。如果强行推送的话,那之前的同事推送到该分支的内容将会被覆盖掉,导致数据的丢失。

6、切换分支报错

  • 问题描述:

    在切换分支的时候,报如下错误。

    $ git checkout master
    error: Your local changes to the following files would be overwritten by checkout:
    	test.txt
    Please commit your changes or stash them before you switch branches.
    
  • 解决方案:

    报错的原因很明显,就是你修改了当前分支的文件,但没有提交到暂存区/本地仓库,如果强行切换的话,修改的数据将会丢失。

    $ git add 修改的文件名
    $ git commit -m "描述"
    

    修改完成后再切换:

    $ git checkout master
    Switched to branch 'master'
    Your branch is up to date with 'origin/master'.
    

7、前端项目构建包的权限问题

  • 问题描述:

    一般前端的包构建后都会生成一个 dist 文件,该文件一般包括 index.html、css、js、img等文件。但通过 Jenkins 构建后权限被改变了,如文件没有读(r)权限、目录没有执行(x)权限。

  • 解决方案:

    可写一个修改权限的脚本,Jenkins 构建完后执行该脚本即可解决,如果你是普通用户执行的,可赋予该普通用户相关的权限。

<点击跳转至开头>

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值