skyemperor 发表于 2020-12-4 12:20

docker通过gitlab部署CICD



# docker通过gitlab部署CICD

## 一、 部署gitlab

### 1.1 拉取gitlab镜像

```sh
# gitlab-ce为稳定版本,后面不填写版本则默认pull最新latest版本
# 注意需要配置镜像加速器,不然会非常慢
docker pull gitlab/gitlab-ce
```

### 1.2 运行gitlab镜像

```sh
docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /opt/gitlab/config:/etc/gitlab -v /opt/gitlab/log:/var/log/gitlab -v /opt/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce

# -d:后台运行
# -p:将容器内部端口向外映射
# --name:命名容器名称
# -v:将容器内数据文件夹或者日志、配置等文件夹挂载到宿主机指定目录
```

### 1.3 配置

```sh
# gitlab.rb文件内容默认全是注释
vim /opt/gitlab/config/gitlab.rb
```

```sh
# 配置内容如下:

# 配置http协议所使用的访问地址,不加端口号默认为80
external_url 'http://192.168.6.21'

# 配置ssh协议所使用的访问地址和端口
gitlab_rails['gitlab_ssh_host'] = '192.168.6.21'
gitlab_rails['gitlab_shell_ssh_port'] = 222 # 此端口是run时22端口映射的222端口
```

```sh
# 重启gitlab容器
docker restart gitlab
```

### 1.4 若发生502报错

```sh
docker exec -it gitlab bash # 进入容器内部
gitlab-ctl restart sidekiq
gitlab-ctl hup unicorn
```





## 二、 CI

>GitLab-CI/CD是GitLab的一套内置的工具,主要实现了对程序开发的持续化集成、连续发布、自动化部署等功能。
>
>**以下引用官方文档进行介绍:**
>
>>持续集成的工作原理是将小的代码块推送到Git存储库中托管的应用程序代码库中,并且每次推送时,都要运行脚本管道来构建,测试和验证代码更改,然后再将其合并到主分支中。
>>
>> 持续交付和部署包括进一步的CI,可在每次推送到存储库默认分支时将应用程序部署到生产环境。
>>
>> 这些方法使您可以在开发周期的早期发现错误和错误,从而确保部署到生产环境的所有代码均符合为应用程序建立的代码标准。
>
>>**CI(continuous intergration)持续集成**
>>持续集成:编写代码时,完成了一个功能后,立即提交代码到Git仓库中,将项目重新的构建并且测试。
>>
>>1.快速发现错误。
>>2.防止代码偏离主分支。

### 2.1 Runner 搭建

> Runner是CI/CD中必不可少一个组件,它是我们持续化集成的实际操作者,当我们通过GitLab Service端发起操作时,实际都是分配到各个Runner服务器进行执行,Runner可以在任意服务器中部署然后再Service端中进行注册。

```sh
#1.为了方便操作,请先进入到root权限
sudo su

#2.下载安装包文件
curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

#3.添加权限
chmod +x /usr/local/bin/gitlab-runner

#4.新建一个操作用户
useradd --comment 'gitlab-runner' --create-home gitlab-runner --shell /bin/bash

#5.安装
#注意: --working-directory 是runner实际执行目录,所有从service端发起的请求命令,都会到该目录下进行执行。
gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner

#6.启动
gitlab-runner start
```

- 常用命令

```sh
gitlab-runner stop 停止服务
gitlab-runner start 启动服务
gitlab-runner restart 重启服务

gitlab-runner list #查看各个 Runner 的状态
gitlab-runner verify    #此命令检查注册的runner是否可以连接,但不验证GitLab服务是否正在使用runner。 --delete 删除
gitlab-runner register#默认交互模式下使用,非交互模式添加 --non-interactive

gitlab-runner unregister   #该命令使用GitLab取消已注册的runner。
        #使用令牌注销
        gitlab-runner unregister --url http://gitlab.example.com/ --token t0k3n

        #使用名称注销(同名删除第一个)
        gitlab-runner unregister --name test-runner

        #注销所有
        gitlab-runner unregister --all-runners
```



> 因为gitlab-runner可能会用到maven,docker,git,所以需要提前安装好这些东西

```
yum install java-1.8.0-openjdk* -y
```

```sh
yum install git
```

```sh
# 安装docker略
usermod -aG docker gitlab-runner# 保证可以使用docker
sudo -u gitlab-runner -H docker info # 验证是否有效
```

```sh
# 安装docker-compose略
```


```sh
# 安装maven
yum -y install maven
mvn -v#查看maven版本

# 配置aliyun镜像
vim /etc/maven/settings.xml
# mirrors节点下添加(注意不能有tab键)
    <mirrors>
      <mirror>
            <id>alimaven</id>
            <mirrorOf>central</mirrorOf>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
      </mirror>

      <mirror>
            <id>repo1</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name for this Mirror.</name>
            <url>http://repo1.maven.org/maven2/</url>
      </mirror>

      <mirror>
            <id>repo2</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name for this Mirror.</name>
            <url>http://repo2.maven.org/maven2/</url>
      </mirror>
    </mirrors>
```

### 2.2 注册Runner

```sh
gitlab-runner register
```

>会要求输入gitlab的**url和Token**.
>查找过程如下:
>进入仓库->settings->CI/CD,找到Runner Settings这一项,点击Expend,即可在`Setup a specific Runner manually`这项中找到。

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_23.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_24.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_25.png)

### 2.3 样例测试

#### 2.3.1 新建maven-tomcat项目

> 下方为`pom.xml`

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cicd.test</groupId>
    <artifactId>cicd_test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
      <java.version>1.8</java.version>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
      <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
      </dependency>
    </dependencies>

    <build>
      <finalName>cicd-test</finalName>
      <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
                </configuration>
            </plugin>
      </plugins>
    </build>
</project>
```

#### 2.3.2 创建.gitlab-ci.yml

```yml
stages:
- test

test_job:
stage: test
script:
    - echo hello hi
    - mvn clean
    - mvn package
    - cp target/cicd-test.war docker/cicd-test.war
    - docker-compose down
    - docker-compose up -d --build
    - docker rmi $(docker images -qf "dangling=true")
tags:
    - cicd-test
only:
    - master
```

#### 2.3.3 编写Dockerfile文件

> 在根目录下新建docker文件夹,在docker文件夹下创建Dockerfile

```sh
FROM daocloud.io/library/tomcat:8.5.15-jre8
COPY cicd-test.war /usr/local/tomcat/webapps
```

#### 2.3.4 编写docker-compose.yml文件

> 在根目录下创建

```yml
version: "3.1"
services:
testci:
    build: docker
    restart: always
    container_name: testci
    ports:
   - 8080:8080
```

## 三、 CD

> **CD(持续交付,持续部署)**
>
> 持续交付:将代码交给专业的测试团队去测试
>
> 持续部署:将测试通过的代码,发布到生产环境

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_26.png)

### 3.1 安装Jenkins

> 官网https://www.jenkins.io/

> **docker-compose.yml**

```yml
version: "3.1"
services:
jenkins:
    image: jenkins/jenkins:lts
    restart: always
    container_name: jenkins
    ports:
      - 8888:8080
      - 50000:50000
    volumes:
      - /opt/jenkins/data:/var/jenkins_home
      - /opt/jenkins/etc:/etc
```

```sh
docker run -d -p 8888:8080 -p 50000:50000 -v /opt/jenkins/data:/var/jenkins_home -v /opt/jenkins/etc:/etc --name jenkins --restart always jenkins/jenkins:lts
```


> 第一次运行时,因为data目录没有权限,会导致启动失败

```sh
chmod 777 data
```

> 查看运行日志

```sh
docker-compose logs -f
```

> 找到管理员密码

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_27.png)

> 配置国内源,以获得更快的插件下载速度

- 安装两个插件

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_52.png)



![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_53.png)

### 3.2 配置目标服务器及Gitlab免密码登录

> Gitlab->Jenkins->目标服务器

#### 3.2.1Jenkins连接目标服务器

> 系统管理 -> 系统配置 -> Publish over SSH -> 新增

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_28.png)

#### 3.2.2 配置Gitlab免密码登录

> 1、 进入Jenkins容器内部

```
docker exec -it jenkins bash
```

> 2、 生成SSH密钥

```sh
ssh-keygen -t rsa -C "1809227959@qq.com"
# Your public key has been saved in /var/jenkins_home/.ssh/id_rsa.pub.
```

> 3、 复制到Gitlab的密钥中

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_29.png)



#### 3.2.3 配置JDK和Maven

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_30.png)



#### 3.2.3 手动拉取Gitlab项目

> 主要是为了完成第一次的拉取,输入yes,之后可以删掉这个

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_31.png)



#### 3.2.4 创建Maven任务

> 1、在idea新建一个简单的maven项目(cd_test) , 并将其推送到gitlab上

> 2、 在Jenkins的监控页面新建maven任务

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_32.png)



![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_33.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_34.png)



![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_35.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_36.png)

> 3、 执行任务

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_37.png)

> 4、 最终效果: 在**/var/jenkins_home/worksplace**下成功编译成功,得到war包

### 3.3 实现持续交付持续部署

> 1、安装Git Parameter,Persistent Parameter插件

> 2、 重新指定构建项目的方式

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_38.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_39.png)

```sh
echo $Tag
cd /var/jenkins_home/workspace/cd_test
git checkout $Tag
git pull origin $Tag
/var/jenkins_home/maven/apache-maven-3.6.3/bin/mvn clean package
```



> 3、 构建项目成功后,需要将内容发布到目标服务器中

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_40.png)

```sh
cd /home/cd_test
cp target/cd-test.war docker
docker-compose down
docker-compose up -d --build
docker image prune -f
```



> 4、修改程序代码,提交到gitlab仓库

- docker/Dockerfile

```sh
FROM daocloud.io/library/tomcat:8.5.15-jre8
COPY cd-test.war /usr/local/tomcat/webapps
```

- docker-compose.yml

```yml
version: "3.1"
services:
    cd-test:
      build: docker
      restart: always
      container_name: testci
      ports:
      - 8081:8080
```



> 5、 测试
>
>         1. 给当前代码添加一个标签
>
>        2. 到Jenkins中查看

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_41.png)





## 四、 简单的SpringBoot项目实践

### 4.1 新建一个项目



### 4.2 Jenkins里新建任务

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_42.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_43.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_44.png)



### 4.3 **构建触发器**

> 构建触发器的设置经常使用的有三种:**定时构建**(不管有没有代码有没有变化)、**定时轮询构建**(定时轮询代码仓库,有改动才会构建)、**远程仓库接收到push事件时构建**(也就是有人向远程仓库成功的push了代码)。这里主要讲这三种触发方式。

#### 4.3.1 Build periodically (**定时构建**)

> 此时的定时构建是时间到达日程表所设置的时间后,就开始构建。此时不管前面源码管理处设置的分支是上的内容是否有变化都会开始构建。例如:在日程表的白框里填写H/30 * * * *,表示每隔30分钟构建一次。具体的定时语法写法课点击旁边的蓝色?图标查看。

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_45.png)

#### 4.3.2 Poll SCM

> 这个也是定时构建,但不同的是在达到所设置的时间后,系统会去轮询设置的远程仓库是否有变化,有变化才构建。例如:在日程表的白框里填写H/30 * * * *,表示每隔30分钟就检测一下远程仓库是否有变化,有变化就开始构建,没有变化则不构建。

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_46.png)



#### 4.3.3 远程仓库接收到push事件时构建

> 当有人成功的向仓库push代码时,触发构建。

> 选择Build when a change is pushed to GitLab这个选项。打开”高级”按钮,如下图红圈1标识部分:

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_47.png)

**1)在上图红圈2部分设置需要跟踪变化的分支,根据上面的选项配置,可以是允许全部分支的变化触发构建,也可以设置只是具体的某些分支触发,这里示例是允许master分支上的变化触发构建。**

**2)要想Gitlab上仓库有push事件发生时触发构建,还需要进一步的设置。在Gitlab上找到要构建的项目,在侧栏找到点击设置图标,找到webhook,点击进入。**

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_48.png)

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_49.png)



- **URL部分**复制上述步骤“当有人成功的向仓库push代码时,触发构建”中的图片上**红圈1部分的http地址**;

- **Secret token**则填写的是红圈3部分(要先**点击generate生成**);

- 然后再**Tigger中勾选push events**,表示当有代码push到该仓库时触发,最后点击**末尾Add Webhook**保存。

> 之后在Jenkins的item设置中设置好构建环境、构建步骤、以及构建后操作。当Gitlab上我们添加了webhook的的项目有代码push的时候,便可以自动触发Jenkins的构建。



> 若出现以下情况,进入 **Admin area => Settings => Network ,然后点击 Outbound requests 右边 的“expand”按钮**

![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_50.png)



![](https://gitee.com/skyyemperor/pic/raw/master/2020/11/Screenshot_51.png)










从来不想 发表于 2022-1-12 14:08

厉害了,收藏慢慢学
页: [1]
查看完整版本: docker通过gitlab部署CICD