一、安装GitLab(单独)
1. yum源安装
这个方法比较方便,傻瓜式安装即可
-
配置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
-
更新yum缓存
yum clean && yum makecache
-
安装,默认安装最新版本
yum install -y gitlab-ce
2. Docker安装
-
下载镜像,默认案子最新版
docker pull gitlab/gitlab-ce
-
运行镜像,指定需要映射出的端口
# -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。
- 修改
/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端口
-
重启GitLab
# yum源 gitlab-ctl start # docker docker restart gitlab
二、安装GitRunner(单独)
-
获取rpm安装包
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
-
安装
yum install -y gitlab-ci-multi-runner
-
设置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
的性能。
这也就是为什么不推荐使用这种办法安装。
-
配置文件
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。
-
运行:
docker-compose -f docker-compose up -d --build
四、GitLab配置GitRunner以及使用
1. 创建一个项目
略
2. 注册Runner
- 打开创建好的项目;Setting —> CI/CD —> Runners —> Expand;
-
进入安装了GitRunner服务的服务器;
-
配置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!
-
注册完毕之后,刷新Gitlab项目页面,就可以看到刚才注册的Runner。
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失败后的自动重试次数 |
更具体的解释可以详见这篇博文:https://segmentfault.com/a/1190000011881435
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. 提交测试
-
提交代码;
-
打开Gitlab项目界面 —> CI/CD;
-
随便点击一个进去就可以看见详细的构建过程。
-
忽略构建。
# 在commit的时候,在提交信息中添加 [ci skip] 或者 [skip ci] 就可以使此次提交不构建CI/CD
# 就好像上图中的最顶上那个,状态为: skippend
# ex:
git commit -m '测试一下忽略构建CI [ci skip]'
- 构建成功之后,访问测试。
# 访问
crul localhost:1111
# 返回
Hello i'm mengli!