Jenkins+GitLab+Docker自动化部署

Jenkins+GitLab+Docker自动化部署

Posted by 冷小冰 on September 19, 2019

Jenkins+GitLab+Docker自动化部署

简陋的Jenkins自动化部署

环境配置

服务器列表

服务器 操作系统 安装软件
代码仓库 CentOS_7_5_64 docker,gitlab
镜像仓库/Jenkins CentOS_7_5_64 docker,Harbor,Jenkins,jdk1.8,maven,git
服务部署 CentOS_7_5_64 docker,jdk1.8

服务器环境配置

关闭防火墙

1
systemctl stop firewalld & systemctl disable firewalld 

关闭SeLinux

1
2
setenforce 0 
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config 

关闭Swap

  • 执行swapoff -a可临时关闭,但系统重启后恢复
  • 编辑/etc/fstab,注释掉包含swap的那一行即可,重启后可永久关闭,如下所示:
1
sed -i '/ swap / s/^/#/' /etc/fstab

Docker

安装步骤参见:安装docker

Harbor

安装步骤参见:安装Harbor

Jenkins

  • 安装jdk,maven

下载安装包,上传到服务器,解压,配置环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
# 修改配置文件
vim /etc/profile

export JAVA_HOME=/opt/jdk1.8.0_172
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

export MAVEN_HOME=/opt/maven/bin
export PATH=$MAVEN_HOME:$PATH

# 立即生效
source /etc/profile
  • 安装git
1
yum install git
  • 安装Jenkins
1
2
3
4
5
6
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
# 安装
yum install jenkins
# 启动
systemctl start jenkins
  • 配置Jenkins

全局工具配置

全局安全配置

  • 其他说明
    • jenkins 工作目录:/var/lib/jenkins/workspace

Gitlab

安装

安装步骤参见:使用docker搭建GitLab环境

配置

开启本地webhook

自动化部署

  • 创建项目

在gitlab上创建一个项目,并编写相关的DockerfileJenkinsfile文件。

  • Jenkins配置流水线

  • 构建触发器

JENKINS_URL:表示Jenkins的ip和端口号;TOKEN_NAME:表示身份验证令牌

  • 流水线配置

  • gitlab项目webhook配置

在项目设置的集成配置里面,设置webhook的url。

Jenkinsfile

本示例所用的完整Jenkinsfile文件如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env groovy

pipeline {
    agent any

    environment {
        IMAGE_STORE="store.iaas.biz:80"
        IMAGE_STORE_PATH="store.iaas.biz:80/dev"
        DOCKER_USER="admin"
        DOCKER_PASSWORD="Harbor12345"
        MODULE="eureka-test"
        VERSION="latest"
        DEPLOY_IP="deploy.iaas.biz"
    }

    stages {
        stage('编译') {
            steps {
                echo "==========编译开始=========="
                sh "mvn clean package -Dmaven.test.skip=true"
                echo "==========编译结束=========="
            }
        }
        stage('构建镜像') {
            steps {
                echo "==========构建镜像开始=========="
                sh "sudo docker build -t ${IMAGE_STORE_PATH}/${MODULE}:${VERSION} ."
                echo "==========构建镜像结束=========="
            }
        }
        stage('推送镜像') {
            steps {
                echo "==========推送镜像开始=========="
                sh "sudo docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWORD} ${IMAGE_STORE}"
                sh "sudo docker push ${IMAGE_STORE_PATH}/${MODULE}:${VERSION}"
                echo "==========推送镜像结束=========="
            }
        }
        stage('部署服务') {
            steps {
                echo "==========部署服务开始=========="
                echo "----------拉取镜像----------"
                sh "sudo ssh ${DEPLOY_IP} 'sudo docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWORD} ${IMAGE_STORE}'"
                sh "sudo ssh ${DEPLOY_IP} 'sudo docker pull ${IMAGE_STORE_PATH}/${MODULE}:${VERSION}'"

                echo "----------删除老的容器----------"
                sh "sudo docker ps -f name=${MODULE} -q | xargs --no-run-if-empty docker container stop"
                sh "sudo docker container ls -a -f name=${MODULE} -q | xargs -r docker container rm"

                echo "----------启动新的容器----------"
                sh "sudo ssh ${DEPLOY_IP} 'sudo docker run --name ${MODULE} -d -p 10000:10000 ${IMAGE_STORE_PATH}/${MODULE}:${VERSION}'"
                echo "==========部署服务结束=========="
            }
        }
    }
}

遇到的坑

maven命令无法使用

在Jenkins的使用过程中,如果在脚本中使用到maven命令,有可能出现如下所示的错误:

1
script.sh: line 1: mvn: command not found

对于java或maven的路径的环境变量是放在/etc/profile中的,而/etc/profile只有在用户登录的时候才会被load,Jenkins在运行命令时,使用的是Non-login的方式,而这种方式在运行命令时,/etc/profile是不会被load进来的,所以jenkins只能在当前路径下寻找可执行文件.

解决方式:

在Jenkins中设置全局属性中的环境变量,jenkins主页面->Manage Jenkins->Configure System->Global Properties 中,将Environment variables复选框选中,会出来List of variables, 填入以下内容:

  • name: JAVA_HOME value:/opt/jdk1.8.0_172
  • name: M2_HOME value:/usr/cyz/apache-maven-3.6.1
  • name: PATH+EXTRA value: $M2_HOME/bin

注意最后标色的 PATH+EXTRA, 这表示PATH=EXTRA:$PATH, 即扩展当前的PATH变量.

docker调用失败

在Jenkins的使用过程中,如果在脚本中使用到docker命令,有可能出现如下所示的错误:

1
dial unix /var/run/docker.sock: connect: permission denied

Docker守护程序绑定到Unix socket而不是TCP端口。默认情况下,Unix socket由root用户拥有,其他用户需要使sudo。Docker守护程序始终以root用户身份运行。

解决方式:

在命令前加sudo

sudo命令无法使用

在Jenkins的使用过程中,如果在脚本中使用到sudo命令,有可能出现如下所示的错误:

1
sudo: no tty present and no askpass program specified

这是因为Jenkins服务器在执行sudo命令时的上下文有误,导致这个命令执行的异常。

解决方式:

在Jenkins宿主服务器上运行如下命令

1
sudo visudo

在文件的末尾加上一行

1
jenkins ALL=(ALL) NOPASSWD: ALL

保存文件(注意保存的时候修改文件名,文件名后缀不要加上默认的.tmp,即可覆盖原文件)

1
Ctrl+O

退出编辑

1
Ctrl+X

重启Jenkins服务

1
systemctl restart jenkins

最后,重新执行构建任务,不会出现先前的错误。