一、安装GitLab(单独)

1. yum源安装

这个方法比较方便,傻瓜式安装即可

  1. 配置yum源
vim /etc/yum.repos.d/gitlab-ce.repo
复制以下内容:

[gitlab-ce]
name=Gitlab CE Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
gpgcheck=0
enabled=1
  1. 更新yum缓存
    yum clean && yum makecache
  2. 安装,默认安装最新版本
    yum install -y gitlab-ce

2. Docker安装

  1. 下载镜像,默认案子最新版
    docker pull gitlab/gitlab-ce
  2. 运行镜像,指定需要映射出的端口
# -d:后台运行
# -p:将容器内部端口向外映射
# --name:命名容器名称
# -v:将容器内数据文件夹或者日志、配置等文件夹挂载到宿主机指定目录
docker run -d  -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /etc/gitlab/config:/etc/gitlab -v /etc/gitlab/logs:/var/log/gitlab -v /etc/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce

3. 修改配置文件

使用yum源安装的时候,后台使用了nginx做了代理,但是使用docker安装的时候,使用的是Docker镜像自己的HostName。

  1. 修改 /etc/gitlab/gitlab.rb
# gitlab.rb文件内容默认全是注释
# 配置http协议所使用的访问地址,不加端口号默认为80
external_url 'http://ip:23333'
# 配置ssh协议所使用的访问地址和端口
gitlab_rails['gitlab_ssh_host'] = 'ip'
gitlab_rails['gitlab_shell_ssh_port'] = 23334 # 此端口是run时22端口映射的222端口
  1. 重启GitLab
# yum源
gitlab-ctl start
# docker
docker restart gitlab

二、安装GitRunner(单独)

  1. 获取rpm安装包
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
  1. 安装
    yum install -y gitlab-ci-multi-runner
  2. 设置Docker权限
# 主要是后续的Runner需要使用Docker
usermod -aG docker gitlab-runner

三、安装Gitlab+GitRunner(Docker-compose)# 不推荐

一般来说,构建任务都会占用很多的系统资源 (譬如编译代码),而 GitLab CI 又是 GitLab的一部分,如果由 GitLab CI 来运行构建任务的话,在执行构建任务的时候,GitLab 的性能会大幅下降。

GitLab CI 最大的作用是管理各个项目的构建状态,因此,运行构建任务这种浪费资源的事情就交给 GitLab Runner 来做。

所以把 GitLab Runner 安装到不同的机器上,在构建任务运行期间并不会影响到 GitLab 的性能。

这也就是为什么不推荐使用这种办法安装。

  1. 配置文件 docker-compose.yml
version: '3'  #1
services:
    gitlab:
      image: gitlab/gitlab-ce:latest  #2
      container_name: "gitlab"
      restart: unless-stopped
      privileged: true
      hostname: "172.17.193.109:7780"  #3
      environment:
        #4
        GITLAB_OMNIBUS_CONFIG: |
          # external_url 'http://172.17.193.109:7780'
          gitlab_rails["time_zone"] = "Asia/Shanghai"
          gitlab_rails["gitlab_shell_ssh_port"] = 7722
          nginx["listen_port"] = 80
      #5
      ports:
        - "7780:80"
        - "7722:22"
      #6
      volumes:
        - /home/cache/gitlab/config:/etc/gitlab
        - /home/cache/gitlab/data:/var/opt/gitlab
        - /home/cache/gitlab/logs:/var/log/gitlab
    gitlab-runner:
      container_name: gitlab-runner
      image: gitlab/gitlab-runner:latest  #7
      restart: always
      volumes:
        - "/var/run/docker.sock:/var/run/docker.sock"
        - "/home/cache/gitlab/runner-config:/etc/gitlab-runner"
  • #1:为 docker-compose 文件的版本号,它和 docker 版本有一个对应,具体在 docker 官方文档中有明确说明。一般写 3 就可以了。
  • #2:当前部署使用 Gitlab 官方最新版的镜像。
  • #3:hostname 填写的是部署成功后,Gitlab 的入口地址。由于我使用的 docker 不在本地,所以配置了一个 ip 地址,本地写 localhost 就可以了。当前配置的意思为,通过 172.17.193.109 的 7780 端口访问 Gitlab 页面。
  • #4:GITLAB_OMNIBUS_CONFIG 为 Gitlab 的配置参数,对应 /etc/gitlab/gitlab.rb。该文件下的所有键值对都可以在这里进行配置,容器启动时会自动配置进去。当然也可以在 Gitlab 容器启动后,手动修改 gitlab.rb 文件。
  • #5:配置了需要用到的两个端口。默认 Gitlab 容器内部 80 端口用于 Gitlab 页面的访问,22 用于 ssh 连接远程仓库。分别对其进行外网映射。
  • #6:volume 映射,三个 volume 和官方文档一致就可以了。
  • #7:这里用的是 gitlab-runner 镜像,部分博客使用的 gitlab-ci-multi-runner 是旧版本,最新的镜像统一修改为 gitlab-runner。
  1. 运行:docker-compose -f docker-compose up -d --build

四、GitLab配置GitRunner以及使用

1. 创建一个项目

2. 注册Runner

  1. 打开创建好的项目;Setting —> CI/CD —> Runners —> Expand;

gitlab外网和内网 gitlab nekoinverter_linux

  1. 进入安装了GitRunner服务的服务器;
  2. 配置Runner,执行:gitlab-runner register
Runtime platform                                    arch=amd64 os=linux pid=43 revision=a987417a version=12.2.0
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
${gitlab项目配置中显示的ip}
Please enter the gitlab-ci token for this runner:
${gitlab项目配置中显示的token}
Please enter the gitlab-ci description for this runner:
[bb6040f1cd04]: ${这个runner的说明}
Please enter the gitlab-ci tags for this runner (comma separated):
${这个runner需要运行哪些tag,比如maven,test,java等等标签}
Registering runner... succeeded                     runner=zpzZ-shs
Please enter the executor: docker-ssh, shell, ssh, virtualbox, docker+machine, custom, parallels, docker-ssh+machine, kubernetes, docker:
${这个runner需要运行在哪?docker或者shells等}
Please enter the default Docker image (e.g. ruby:2.6):
${选择docker之后,需要配置这个runner默认的根镜像}
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
  1. 注册完毕之后,刷新Gitlab项目页面,就可以看到刚才注册的Runner。

gitlab外网和内网 gitlab nekoinverter_git_02

3、配置Runner

由于刚刚只是根据流程配置了一些基本的信息,还有额外的参数要配置就需要修改对应的配置文件了。

可以直接修改映射到本地的配置文件: config.toml。每配置一个 runner 就会在配置文件中生成一个[[runners]]

# 文件的目录,根据安装方式的不同,目录也不同。
# yum安装目录:/etc/gitlab-runner/config.toml
# docker安装目录:配置文件映射的;

# 修改runner
[[runners]]
  name = "hello,spring boot!"
  url = "http://172.17.193.109:7780/"
  token = "u8_Y5rLQazUmBZar9eys"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "docker:latest"
    privileged = true  # 默认为 false,需改为 true。自动跳过health check。
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache","/usr/local/maven:/root/.m2"] # 修改cache目录。
    shm_size = 0

# 别的参数基本没有修改,只是修改了cache缓存目录,修改成了本地的maven。这样在处理依赖时可以直接使用本地的环境,并且可以用阿里云镜像源。

五、CI/CD的测试以及使用

1. 文件目录以及配置文件说明

├── Dockerfile	# 构建Docker镜像的配置文件
├── .gitlab-ci.yml	# 构建Gitlab CI/CD的配置文件
├── pom.xml		# 项目maven依赖
└── src		# 项目代码
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── demo
    │   │               └── DemoApplication.java
    │   └── resources
    │       └── application.properties
    └─────────────────────────────────────

2. 测试代码

  • DemoApplication.java
package com.example.demo;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@SpringBootApplication
@RestController
public class DemoApplication {

	@GetMapping("/")
	String home() {
		return "Hello i'm mengli!";
	}

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}
  • application.properties
server.port=11111

3. Dockerfile 文件修改

# Dockerfile的具体解释此处就不详解了
# 依赖的构建镜像
FROM maven:3.5-jdk-8
# 进入tmp目录
VOLUME /tmp
# 复制jar包
ADD target/demo-0.0.1-SNAPSHOT.jar app.jar
# 抛出11111端口号
EXPOSE 11111
# 需要执行的语句
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

4. .gitlab-ci.yml 文件修改

# 当前runner依赖的基础镜像
image: docker:latest
# 声明一些参数
variables:
  DOCKER_HOST: tcp://{dockerIp}:2375
  TAG: minerunner:v1
# 声明当前ci需要执行的步骤
stages:
  - package
  - develop
# 相当于创建一个全局函数
.tagsFlag: &tagsFlagDef # 创建一个锚,'tagsFlagDef'
  # 声明当前任务是在哪个runner下执行
  tags:
    - maven
  # 声明哪几个分支提交的时候,执行.
  only:
    - master
    - pro
# 同上
.imageFlag: &imageFlagDef # 创建一个锚,'imageFlagDef'
  image: maven:3.5-jdk-8
  <<: *tagsFlagDef
# 开始编写任务细则
# 这个名字无所谓,随便起
package:
  # 这个参数后面声明的就是上面stages里面声明的
  stage: package
  # 引入上面的函数
  <<: *imageFlagDef
  # 需要执行的操作
  script:
    - mvn clean package -Dmaven.test.skip=true
  artifacts:
    paths:
      - target/*.jar
# 部署
develop:
  stage: develop
  <<: *tagsFlagDef
  script:
    - docker build -t $TAG .
    - docker rm -f runnerdemo || true
    - docker run -d -p 11111:11111 --name runnerdemo $TAG

4.1 .gitlab-ci.yml 配置详解


是否必须

描述

script

必须

定义由Runner执行的shell脚本或命令

extends

非必须

定义此作业将继承的配置条目

image

非必须

需要使用的docker镜像,请查阅该文档

services

非必须

定义所需的docker服务,请查阅该文档

stage

非必须

定义一个工作场景阶段,默认是test

type

非必须

stage的别名,不赞成使用

variables

非必须

在job级别上定义的变量

only

非必须

定义job所引用的git分支

except

非必须

定义job所不适用的git分支

tags

非必须

定义job所适用的runner,tags为runner标签

allow_failure

非必须

允许任务失败,但是如果失败,将不会改变提交状态

when

非必须

定义了job什么时候执行,可以是on_success、on_failure、always和manual

dependencies

非必须

定义了该job依赖哪一个job,如果设置该项,可以通过artifacts设置

artifacts

非必须

工件,在依赖项之间传递的东西,类似cache,但原理与cache不同

cache

非必须

定义需要被缓存的文件、文件夹列表

before_script

非必须

覆盖在作业之前执行的脚本或命令

after_script

非必须

覆盖在作业之后执行的脚本或命令

environment

非必须

定义让job完成部署的环境名称

coverage

非必须

定义job设置代码覆盖率

retry

非必须

定义job失败后的自动重试次数

更具体的解释可以详见这篇博文:

4.2 更具体的配置文件

# 定义 stages(阶段)。任务将按此顺序执行。
stages:
  - build
  - test
  - deploy

# 定义 job(任务)
job1:
  stage: test
  tags:
    - XX #只有标签为XX的runner才会执行这个任务
  only:
    - dev    #只有dev分支提交代码才会执行这个任务。也可以是分支名称或触发器名称
    - /^future-.*$/ #正则表达式,只有future-开头的分支才会执行
  script:
    - echo "I am job1"
    - echo "I am in test stage"

# 定义 job
job2:
  stage: test    #如果此处没有定义stage,其默认也是test
  only:
    - master    #只有master分支提交代码才会执行这个任务
  script:
    - echo "I am job2"
    - echo "I am in test stage"
  allow_failure: true #允许失败,即不影响下步构建    

# 定义 job
job3:
  stage: build
  except:
    - dev #除了dev分支,其它分支提交代码都会执行这个任务
  script:
    - echo "I am job3"
    - echo "I am in build stage"
  when: always #不管前面几步成功与否,永远会执行这一步。它有几个值:on_success (默认值)\on_failure\always\manual(手动执行)

# 定义 job
.job4:    #对于临时不想执行的job,可以选择在前面加个".",这样就会跳过此步任务,否则你除了要注释掉这个jobj外,还需要注释上面为deploy的stage
  stage: deploy
  script:
    - echo "I am job4"

# 模板,相当于公用函数,有重复任务时很有用
.job_template: &job_definition  # 创建一个锚,'job_definition'
  image: ruby:2.1
  services:
    - postgres
    - redis

test1:
  <<: *job_definition           # 利用锚'job_definition'来合并
  script:
    - test1 project

test2:
  <<: *job_definition           # 利用锚'job_definition'来合并
  script:
    - test2 project

#下面几个都相当于全局变量,都可以添加到具体job中,这时会被子job的覆盖    

before_script:
  - echo "每个job之前都会执行"

after_script:
  - echo "每个job之后都会执行"

variables:    #变量
  DATABASE_URL: "postgres://postgres@postgres/my_database"  #在job中可以用${DATABASE_URL}来使用这个变量。常用的预定义变量有CI_COMMIT_REF_NAME(项目所在的分支或标签名称),CI_JOB_NAME(任务名称),CI_JOB_STAGE(任务阶段)
  GIT_STRATEGY: "none" #GIT策略,定义拉取代码的方式,有3种:clone/fetch/none,默认为clone,速度最慢,每步job都会重新clone一次代码。我们一般将它设置为none,在具体任务里设置为fetch就可以满足需求,毕竟不是每步都需要新代码,那也不符合我们测试的流程

cache:    #缓存
  #因为缓存为不同管道和任务间共享,可能会覆盖,所以有时需要设置key
  key: ${CI_COMMIT_REF_NAME}  # 启用每分支缓存。
  #key: "$CI_JOB_NAME/$CI_COMMIT_REF_NAME" # 启用每个任务和每个分支缓存。需要注意的是,如果是在windows中运行这个脚本,需要把$换成%
  untracked: true    #缓存所有Git未跟踪的文件
  paths:    #以下2个文件夹会被缓存起来,下次构建会解压出来
    - node_modules/
    - dist/

5. 提交测试

  1. 提交代码;
  2. 打开Gitlab项目界面 —> CI/CD;
  3. 随便点击一个进去就可以看见详细的构建过程。
  4. 忽略构建。
# 在commit的时候,在提交信息中添加 [ci skip] 或者 [skip ci] 就可以使此次提交不构建CI/CD
# 就好像上图中的最顶上那个,状态为: skippend
# ex:
git commit -m '测试一下忽略构建CI [ci skip]'
  1. 构建成功之后,访问测试。
# 访问
crul localhost:1111
# 返回
Hello i'm mengli!