GitLab CI-CD 学习笔记
概述
1. CI/CD
CI(持续集成)指开发人员一天内进行多次合并和提交代码操作,并通过自动化测试,完成构建
CD(持续部署)指每次代码更改都会自动部署到对应环境
CI/CD 结合在一起,可以加快开发团队交付成果的效率,减少时间成本
2. Gitlab-CI/CD
gitlab-ci 是 gitlab8.0 之后自带的一个持续集成系统,中心思想是每一次 push 到 gitlab 就会触发一次脚本执行,脚本内容包括测试、编译、部署等一系列内容
gitlab-ci 的脚本需要 gitlab-runner 来执行,代码 push 之后,webhook 检查到代码变化,就会触发 gitlab-ci,分配到各个 Runner 来运行相应的脚本
gitlab-ce
1. 安装 gitlab-ce
gitlab 有 ce 和 ee 两个版本,ce 是社区版,开源免费,ee 是企业版,需要付费
下面以 Ubuntu18.04.6 为例,安装 gitlab-ce
安装依赖软件
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
添加 gitlab 软件源镜像
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
安装 gitlab-ce
sudo apt-get install gitlab-ce
如果命令行能看到 Gitlab 的 Logo 打印,就说明安装成功了
打开 gitlab 配置文件
vim /etc/gitlab/gitlab.rb
为了能在浏览器访问 gitlab,还需要配置 gitlab 的访问地址和端口
# ip:port 改成自己的,也可以用域名
external_url 'http://192.168.66.100:82'
重载配置并重启
gitlab-ctl recofigure
gitlab-ctl restart
在浏览器输入 http://192.168.66.100:82 即可访问 gitlab,当然了,前提是你的端口要放开

初始用户名为 root,初始密码记录在 /etc/gitlab/initial_root_password 文件,密码有效期为 24 小时,建议登录后尽快修改密码
登录以后,就可以创建项目了,其余的基本的 git 操作这里就不赘述了
2. 其他问题
gitlab-ctl recofigure 过程,有可能出现卡在 ruby_block[wait for logrotate service socket] action run 的情况,解决办法如下:
-
ctrl + c 强行结束
-
运行
systemctl restart gitlab-runsvdir -
再次运行
gitlab-ctl recofigure
安装结束以后,访问 web 端报 502,最可能的原因是端口被占用了,需要修改端口
vim /etc/gitlab/gitlab.rb
# 修改为没有被使用的端口即可
puma['port'] = 9091
gitlab-runner
1. 安装 gitlab-runner
下面以 Ubuntu18.04.6 为例,安装 gitlab-runner
添加 gitlab 软件源镜像
curl https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
安装 gitlab-runner
sudo apt-get install gitlab-runner
2. gitlab-runner 注册
首先获取 gitlab-ci 的 token:项目主页->Setting->CI/CD->Runners Expand

使用命令注册 gitlab-runner
gitlab-runner register
按照步骤输入:
- GitLab instance URL:如上图所示 URL
- registration token:如上图所示 Token
- description:关于该 Runner 的描述
- tags:用于标记该 Runner,后续需要使用这个 tag 来指定 gitlab-runner
- optional maintenance note:没搞懂有啥用,随意写
- Enter an executor:选择执行器,gitlab-runner 提供了许多执行器,可用在不同场景中运行构建,这里选择 shell
完成以后,刷新页面,即可在 Runners Expand 看到新增了一个 Runner

3. 简单示例
下面我们简单测试一下 Runner 是否能正常运行,随意新建一个 SpringBoot 项目

在根目录下创建一个 .gitlab-ci.yml 文件,这里只是简单输出一段语句
stages:- deploydeploy-job:tags:- prodstage: deployscript:- echo "hello world!!!"
push 到 gitlab 后,会发现脚本已经自动执行了,绿勾代表执行成功

点击绿勾,在下方 Pipeline 点击 deploy-job 可以查看执行过程


pipeline 语法
1. job & script
.gitlab-ci.yml 文件中可以定义一个或多个作业(job),每个作业独立执行,必须有唯一的名称(不能使用关键字)以及包含一个 script,这里定义了三个作业 build、test、deploy,script 可以是 shell 命令
build:script: - echo "build"
test:script: - echo "test"
deploy:script: - echo "deploy"- echo "finish"
2. before_script & after_script
before_script 用于定义一个命令,在每个作业运行之前运行,before_script 失败将导致整个作业失败,其他作业不再执行,如果在作业中定义了 before_script,则该作业不会运行全局的 before_script
after_script 用于定义一个命令,在每个作业运行之后运行,作业失败不影响 after_script 的运行,如果在作业中定义了 after_script,则该作业不会运行全局的 after_script
before_script:- echo "before script"
build:before_script: - echo "before script in buildjob"script: - echo "build"after_script:- echo "before script in buildjob"
test:script: - echo "test"
deploy:script: - echo "deploy"- echo "finish"after_script:- echo "after script"
3. stages & stage
用于定义作业可以使用的阶段,并且是全局定义的,同一阶段的作业并行运行,不同阶段按顺序执行
before_script:- echo "before script"stages:- build- test- deploybuild:before_script: - echo "before script in buildjob"stage: buildscript: - echo "build"after_script:- echo "before script in buildjob"
test:stage: testscript: - echo "test"deploy:stage: deployscript: - echo "deploy"- sleep 5after_script:- echo "after script"
4. .pre & .post
.pre 始终是整个 pipeline 的第一个运行阶段,.post 始终是整个 pipeline 的最后一个运行阶段,无法修改,用户自定义的 stage 则在这两者之间,如果一个 pipeline 仅包含 .pre 和 .post,则不会创建 pipeline
before_script:- echo "before script"stages:- build- test- deploycodescan:stage: .prescript: - echo "codescan"build:before_script: - echo "before script in buildjob"stage: buildscript: - echo "build"after_script:- echo "before script in buildjob"
test:stage: testscript: - echo "test"deploy:stage: deployscript: - echo "deploy"- sleep 5after_script:- echo "after script"
5. variables
定义变量,可以定义 pipeline 变量、job 变量,job 变量优先级最高
before_script:- echo "before script"variables:DOMAIN: example.comstages:- build- test- deploycodescan:stage: .prescript: - echo "codescan"build:before_script: - echo "before script in buildjob"stage: buildscript: - echo "build"- echo "$DOMAIN"after_script:- echo "before script in buildjob"
test:stage: testscript: - echo "test"deploy:stage: deployscript: - echo "deploy"- sleep 5after_script:- echo "after script"
6. tags
用于指定特定的 job 在特定的 runner 运行,如果 job 不指定 tags,则默认在共享的 runner 运行
windows_job:stages: - buildtags:-windowsscript:- echo "windows job"linux_job:stages: - buildtags:-linuxscript:- echo "linux job"
7. allow_failure
allow_failure 表示是否允许作业失败,默认值 false 不允许失败,改为 true 后,如果该作业失败也不会被阻塞
job1:stage: testscript: - "..."allow_failure: true
8. when
when 用于控制作业运行:
- on_success:前面阶段的所有作业成功才执行该作业,默认 on_success
- on_failure:前面阶段出现失败时执行
- always:总是执行作业
- manual:手动执行作业
- delayed:延迟执行作业
job1:stage: testscript: - "..."when: delayed # 表示延迟30s执行start_in: "30"
9. retry
配置作业失败后重试作业的次数
job1:stage: testscript: - "..."retry: 2
也可以精确匹配到某一错误,即出现某一错误时才重试
job1:stage: testscript: - "..."retry: max: 2when: - script_failure # 脚本失败时重试
10. timeout
作业级别的超时可以超过项目级别的超时,但不能超过 Runner 特定的超时
job1:stage: testscript: - "..."timeout: 3h
11. parallel
配置要并行运行的作业的实例数,此值必须大于等于 2 并小于等于 50,这将创建 N 个并行运行的同一作业实例
job1:stage: testscript: - "..."parallel: 5
12. rules
rules 允许按顺序评估单个规则,直到匹配为止:
-
if:如果条件匹配,多条件匹配可以使用 && ||
variables:DOMAIN: example.comjob1:stage: testscript: - "..."rules: # DOMAIN值匹配,则手动运行,否则- if: '$DOMAIN == "example.com"'when: manual- if: '$DOMAIN == "example2.com"'when: delayedstart_in: '5'- when: on_success -
changes:指定文件发生变化
job1:stage: testscript: - "..."rules:- changes: - fimeName # 文件名when: manual- when: on_success -
exists:指定文件存在
job1:stage: testscript: - "..."rules:- exists: - fimeName # 文件名when: manual- when: on_success
13. workflow-rules
workfolw 关键字适用于整个管道,并确定是否创建管道
variables:DOMAIN: example.comworkflow:rules:- if: '$DOMAIN == "example.com"'when: always # 默认always,可以设置never- when: never
14. cache
存储编译项目时所需的运行时依赖项,指定项目工作空间中需要在 job 之间缓存的文件或目录
全局 cache 定义在 job 之外,针对所有 job 生效,job 中的 cache 优于全局
cache:paths: # 在全局定义缓存- my/filesjob:script: "..."cache:key: job # 为缓存设置唯一key,会为该job分配一个独立的cachepaths: # 在job中定义缓存,缓存target目录下的所有.jar文件,该缓存将覆盖全局缓存- target/*.jar# policy: pull # pull:不下载缓存,push不上传缓存,默认会在job执行之前下载缓存,并在结束之后上传缓存
15. artifacts
用于指定作业成功或失败时应附加到作业的文件或目录的列表,可在 Gitlab UI 中下载
build:script:- mvn packageartifacts:name: "$ARTIFACTS_NAME" # 指定所创建的制品名称,默认为artifacts,下载为artifacts.zippaths:- target/*.jarwhen: always # 制品创建条件,on_success:作业成功时创造制品,on_failure:作业失败时创建制品,always:总是创建制品expire_in: 1 week # 制品有效期,从存储到gitlab开始算起,默认30天
16. dependencies
获取当前阶段之前的制品
build:stage: buildscript:- mvn packageartifacts:name "$ARTIFACTS_NAME"paths: - target/*.jardeploy:dependencies:- buildstage: deployscript: - ... # 部署制品
17. needs
可以让作业无需按照阶段顺序运行,下述的例子表示:deploy-a 在 build-a 完成之后就可以执行,deploy-b 在 build-b 完成之后就可以执行
stages:- build- deploybuild-a:stage: buildscript: - ...build-b:stage: buildscript: - ...deploy-a:stage: deployscript:- ...needs: ["build-a"]deploy-b:stage: deployscript:- ...needs: ["build-b"]
18. include
可以引入外部 yaml 文件,使用合并功能可以自定义和覆盖本地定义的 CI/CD 配置
local
引入同一存储库的文件,使用相对于根目录的完整路径进行引用,必须保证走到同一分支
假设有 ci/localci.yml 文件
stages:- deploydeploy-job:stage: deployscript: ...
在 .gitlab-ci.yml 引入 ci/localci.yml 文件,如果存在相同名称的作业,它们的配置会进行合并,并且原文件 .gitlab-ci.yml 的配置优先生效
include:local: "ci/localci.yaml"stages:- build- test- deploybuild-job:stage: buildscript: ...test-job:stage: testscript: ...
file
引入其他项目的 yaml 配置
include:project: demo/demo-java-serviceref: masterfile: .gitlab-ci.yml
template
引入官方提供的模板,可以访问 https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates 查看有哪些模板
include:template: Auto-DevOps.gitlab-ci.yml
remote
引入远程文件
include:remote: "https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml"
19. extends
继承作业配置,相同配置覆盖,不同则继承
.tests:script: mvn teststage: testonly:refs:- tagstest-job:extends: .testsscript: mvn clean testonly:variables:- $RSPEC
最终得到的作业配置如下
test-job:stage: testscript: mvn clean testonly:variables:- $RSPECrefs:- tags
20. trigger
当 gitlab 从 trigger 定义创建的作业启动时,将创建一个下游管道,允许创建多项目管道和子管道:
-
多项目管道:跨多个项目设置流水线,以便一个项目的管道可以触发另一个项目的管道
stagging:variables:ENVIROMENT: stagging # 该变量会传递给下游管道,如果上下游定义了相同名称的变量,上游变量将优先stage: deploytrigger:project: demo/demo-java-service # 指定下游项目的完整路径branch: master # 指定项目的分支名称strategy: depend # 将自身状态从触发的管道合并到源作业 -
父子管道:同一项目的管道可以触发一组同时运行的子管道
子管道 ci/child.yml
stages:- buildchild-build-job:stage: buildscript: ...父管道
stages:- deploystagging:stage: deploytrigger:include: ci/child.ymlstrategy: depend21
21. image
首先注册一个工作类型为 docker 的 runner,只要使用该类型的 runner,所有运行操作都会在容器中运行
gitlab-runner register \--non-interactive \--executor "docker" \--docker-image alpine:latest \ # 默认使用该镜像--url "http://192.168.1.200:30088/" \--registration-token "JRzzw2j1Ji6aBjwvkxAv" \--description "docker-runner" \--tag-list "docker" \--run-untagged="true" \--locked="false" \--access-level="not_protected"
默认注册 runner 会指定一个基础镜像,如果全局指定 image 则所有作业使用该镜像创建容器并运行,如果全局未指定 image,则查看 job 中是否有指定,有则按照 job 指定的镜像创建容器并运行,否则使用默认镜像
image: maven:3.6.3-jdk-8 # 全局定义...deploy-job:stage: deploytags:- dockerscript: ...image: maven:3.6.3-jdk-8 # 局部定义
22. services
工作期间运行的另一个 Docker 服务镜像,将其 link 到 image 定义的 Docker 镜像,这样可以在构建期间访问该服务镜像
...services:- name: mysql:latestalias: mysqlbuild-job:stage: buildtags:- dockerscript: ...image: maven:3.6.3-jdk-8 # 局部定义
23. environment
可用于在 gitlab ui 追踪作业运行情况,
deploy-job:stage: deploytags:- dockerscript: ...environment:name: production # 应用名称url: http://www.baidu.com # 应用地址
相关文章:
GitLab CI-CD 学习笔记
概述 1. CI/CD CI(持续集成)指开发人员一天内进行多次合并和提交代码操作,并通过自动化测试,完成构建 CD(持续部署)指每次代码更改都会自动部署到对应环境 CI/CD 结合在一起,可以加快开发团…...
K8S安装
1.创建三台centos虚拟机 使用的官方最小镜像安装 CentOS-7-x86_64-Minimal-1804.iso 建议最小硬件配置:2核CPU、2G内存、20G硬盘 master配置详情 node1和node2配置详情 三台虚拟机在安装centos的时候在网络IPV4指定DHCP,配置IPV4固定地址,保证可以访问…...
【C++】模板初阶STL简介
今天,你内卷了吗? 文章目录一、泛型编程二、函数模板(显示实例化和隐式实例化)1.函数模板格式2.单参数模板3.多参数模板4.模板参数的匹配原则三、类模板(没有推演的时机,统一显示实例化)1.类模…...
备战蓝桥杯第一天【二分查找无bug版】
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
Java集合中的Map
MapMap接口键 值 对存储键不能重复,值可以重复Map三个实现类的存储结构HashMap:Hash表链表红黑树结构 线程不安全TreeMap: 底层红黑树实现HashTable:hash表链表红黑树 线程安全HashMapHashMap常用方法HashMap<String,String>…...
【java】springboot项目启动数据加载内存中的三种方法
文章目录一、前言二、加载方式2.1、 第一种:使用PostConstruct注解(properties/yaml文件)。2.2、 第二种:使用Order注解和CommandLineRunner接口。2.3、 第三种:使用Order注解和ApplicationRunner接口。三、代码示例3.…...
【GO】29.go-gin支持ssl/tls,即https示例
本文为演示采用自签名证书一.生成证书通过openssl工具生成证书1.1 安装opensslmacos通过brew安装brew install openssl1.2 生成跟证书私钥openssl genrsa -out ca.key 40961.3 准备配置文件vim ca.conf内容如下[ req ] default_bits 4096 distinguished_name req_disti…...
逻辑仿真工具VCS的使用-Makefile
Gvim写RTL code,VCS仿真,Verdi看波形,DC做综合下约束,Primetime做STA,Spyglass做异步时序分析。 VCS全称Verilog Computer Simulation ,VCS是逻辑仿真EDA工具的编译源代码的命令。要用VCS做编译仿…...
信息系统安全技术
一、信息安全的有关概念 1. 属性2. 四个安全层次※3. 信息安全保护等级※4. 安全保护能力的等级※ 二、信息加密、解密与常用算法 1. 对称加密2. 非对称加密3. Hash函数4. 数字签名5. 认证 三、信息系统安全 1. 计算机设备安全2. 网络安全3. 操作系统安全4. 数据库安全5. 应用系…...
【数据结构】最小生成树(Prim算法,普里姆算法,普利姆)、最短路径(Dijkstra算法,迪杰斯特拉算法,单源最短路径)
文章目录前置问题问题解答一、基础概念:最小生成树的定义和性质(1)最小生成树(Minimal Spanning Tree)的定义(2)最小生成树(MST)的性质二、如何利用MST性质寻找最小生成树…...
Session与Cookie的区别(一)
从我刚开始学程序时这一题就常出现在面试考题里,一直到现在都还是能看见这个问题。 这个问题重要吗?我觉得蛮重要的。因为 Session 所代表的是「状态」,如果没有了状态,一大堆功能都会失效。 对于工程师来说必须去理解什么是 Sess…...
【Java】重载和重写的区别
重载(Overload) 在同一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同…...
AcWing 第 90 场周赛
目录A、首字母大写B、找数字C、构造字符串A、首字母大写 原题链接:AcWing 4806. 首字母大写 签到题。 #include <bits/stdc.h>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);string s;cin >> s;s[0] toupper(s[0]);…...
刚刚,体验了一把Bing chat很爽
文章目录刚刚,体验了一把Bing chat很爽你能做啥?与chatgpt有什么不同?以下是Bingchat的 10个新功能1⃣️在网上搜索结果2⃣️摘要链接3⃣️对话助手4⃣️向您发送实际信息,正确的链接5⃣️在单个查询中执行多个搜索6⃣️玩冒险游戏…...
牛客网Python篇数据分析习题(二)
1.现有一个Nowcoder.csv文件,它记录了牛客网的部分用户数据,包含如下字段(字段与字段之间以逗号间隔): Nowcoder_ID:用户ID Level:等级 Achievement_value:成就值 Num_of_exercise&a…...
如何用Python打包好exe文件,并替换图标
前言 Python打包?打包exe文件?怎么操作? ok,今天我来分享分享,教你们如何打包号文件,顺便还来展示一下,如何替换好图标 首先把你的代码准备好,尽量不要中文路径,容易报…...
NFC概述摘要
同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 原理来说,NFC和Wi-Fi类似,利用无线射频技术来实现设备间通信。NFC的工作频率为13.5…...
Python-项目实战--贪吃蛇小游戏(1)
1.贪吃蛇游戏规则贪吃蛇游戏规则如下:1.1开始和结束贪吃蛇初始出现在游戏窗口的左上角位置,体长共有3节游戏过程中,一旦蛇头撞到了窗口的边缘或者身体的其他部位,游戏结束游戏过程中,点击游戏窗口的关闭按钮,或者按下ESC键可以直接退出游戏一…...
vscode sftp从linux服务器下载文件至本地:No such file or dictionary【已解决】
在服务器跑完程序需要下载数据的时候报错: [warn] ENOENT: no such file or directory, open /home/LIST_2080Ti/.ssh/config load /home/LIST_2080Ti/.ssh/config failed 完整报错内容如下: [02-10 08:38:47] [info] config at /home/LIST_2080Ti {&q…...
详解指针(2)(初阶版)
前言:内容包括:指针运算,指针和数组,二级指针,指针数组 详解指针(1)(点击即跳转) part 1:指针运算 1 指针-整数 以如下代码为例:初始化数组内容…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
