cicd 的概念和优势
GitLab CI/CD 是一个使用持续方法进行软件开发的工具。
使用持续的软件开发方法,您可以不断地构建、测试和部署迭代代码更改。这个迭代过程有助于减少基于错误或失败的以前版本开发新代码的机会。使用这种方法,从开发新代码到部署新代码,您将努力减少人为干预,甚至根本不进行干预。
环境搭建
-
gitlab 安装服务器要求 2核4g
-
需要安装的包
node
安装依赖、打包nginx
web 项目部署必须「正向代理、方向代理、负载均衡等等」、 GitLab 也会用到 Nginx(默认自动安装)git
自动化部署,拉取代码gitlab-runner
配合gitlab CI/CD使用的应用程序(runner 可以安装在别的服务器上)
安装node
下载和解压
bash
# 下载安装包,需要哪个版本,在url中修改就可以了
wget https://nodejs.org/dist/v12.9.0/node-v12.9.0-linux-x64.tar.xz
# 解压
tar xf node-v12.9.0-linux-x64.tar.xz
# 复制
cp -rf /root/node-v12.9.0-linux-x64 /usr/local/node
编辑配置
bash
# 打开编辑配置文件
vim /etc/profile
# 在文件的最后,加上下面的内容
export PATH=$PATH:/usr/local/node
重载系统配置文件
bash
source /etc/profile
安装git
Ubuntu 和 CentOs 下载有区别,目前以Ubuntu为例子
bash
#
sudo apt update
sudo apt install git
git --version
安装gitlab
bash
下载
wget --content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/ubuntu/jammy/gitlab-ce_16.2.2-ce.0_amd64.deb/download.deb
# 解压
sudo dpkg -i gitlab-ce_16.2.2-ce.0_amd64.deb
修改配置文件
bash
vim /etc/gitlab/gitlab.rb
修改一下信息
- external_url 可以是域名,或者服务器IP,可以加端口,加端口时确保自己开放了对应的端口
bash
external_url 'http://60.204.142.73:1874'
bash
#重载配置文件,需要的时间比较长
sudo gitlab-ctl reconfigure
机器加上端口号

bash
# 启动gitlab服务
sudo gitlab-ctl start
gitlab常用命令
bash
# 启动gitlab服务
sudo gitlab-ctl start
# gitlab服务停止
sudo gitlab-ctl stop
# 重启gitlab服务
sudo gitlab-ctl restart
访问配置的地址 http://60.204.142.73:1874
- 默认用户名是root
- 密码在**
/etc/gitlab/
initial_root_password** 目录下 iV/KSiLgCl8YkRfl8AXbzKBJg05MyUHGOm1jQyz6EU0= - gitlab 代码在服务器存储路径
/var/opt/gitlab/git-data
至此,成功搭建gitlab

安装gitlab-runner
gitlab-runner 安装我放在了另一台服务器上,CentOs(也需要像上面步骤一样安装git node)
nginx
bash
yum install -y nginx
systemctl start nginx.service
配置nginx
配置后执行 nginx -s reload
nginx 命令
nginx -s reload
重启
安装runner
gitlab-runner 下载目录 /usr/local/bin/gitlab-runner
gitlab-runner 安装目录 /home/gitlab-runner
bash
# 下载
wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
# 分配运行权限
chmod +x /usr/local/bin/gitlab-runner
# 创建用户
useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
# 安装
gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
# 运行
gitlab-runner start
注册 Shell Executor 类型 runner

bash
# 注册 runner
gitlab-runner register
# 输入 gitlab 的访问地址
http://60.204.142.73:1874
# 输入 runner token,把开 http://60.204.142.73:1874/admin/runners 页面查看
49suDNTBzztDQ-kzvQY6
# runner 描述,随便填
测试webpack-vue项目部署
# runner tag
shellrunner
# 输入(选择) shell
shell
查看注册的runner

runner token 获取

gitlab-runner是如何工作的
新建项目,上传到搭建的gitlab

查看项目对应的runner

配置.gitlab-ci.yml文件
yml
stages: # List of stages for jobs and their order of execution
- build
- deploy
build-job:
stage: build
script:
- npm install
- npm run build
查看pipeline


可以看到 runner先去拉取gitlab代码 放到/home/gitlab-runner/builds/ks_UxGnW/0/root/test-cice-myserver/
目录下,然后执行yml对应的script
ks_UxGnW
是对应的runner名称
到服务器查看runner目录
我们看到了执行
npm install
生成的node_modules
和build
目录
完善yml
yml
stages: # List of stages for jobs and their order of execution
- build
- deploy
build-job:
stage: build
script:
- npm install
- npm run build
artifacts:
paths:
- "build/"
pages:
stage: deploy # Set this new job to run in the `deploy` stage
script:
- mv build/ public/
artifacts:
paths:
- "public/"



上面看到,即使执行了npm install 但是并没有存储下来,第二次jop 删除了生成的文件
Removing build/
Removing node_modules/
由此我们了解了gitlab-runner是如何工作的
学习gitlab-ci.yml配置
到此,CICD 环境已经搭建完成了
基本概念
pipelines是持续集成、交付和部署的顶级组件。
pipelines包含两部分:
- Jobs:定义具体要做什么,例如编译,测试
- Stages,定义jobs的执行顺序。
配置.gitlab-ci.yml
后,会触发CI,执行pipeline
jobs
Pipeline配置始于job。job是. gitlab-ci. yml 文件中最基本的元素。

yml 语法
只有了解了yml的语法我们才能进行进一步的配置。
关键字:
- 全局关键字(配置pipeline使用)
关键字 | 说明 |
---|---|
default | job的自定义默认值 |
include | 从其他 YAML 文件导入配置 |
stages | pipeline 的阶段名称和顺序 |
variables | 为pipeline中所有job定义CI/CD变量, |
workflow | 控制pipeline执行的类型 |
yml
# default 示例
default:
image: ruby:3.0
- job关键字
关键字 | 说明 |
---|---|
after_script | 覆盖作业后执行的一组命令 |
allow_failure | 允许作业失败。失败的作业不会导致流水线失败。 |
artifacts | 成功时附加到作业的文件和目录列表 |
cache | 应在后续运行之间缓存的文件列表 |
coverage | 给定作业的代码覆盖率设置 |
dast_configuration | 在作业级别使用来自DAST配置文件的配置 |
dependencies | 通过提供要从中获取产物的作业列表,来限制将哪些产物传递给特定作业。 |
environment | 作业部署到环境的名称 |
except | 控制何时不创建作业 |
extends | 此作业继承自的配置条目 |
image | 使用docker镜像 |
inherit | 选择所有作业继承的全局默认值 |
interruptible | 定义当新运行使作业变得多余时,是否可以取消作业。 |
needs | 在 stage 顺序之前执行的作业 |
only | 控制何时创建作业 |
pages | 上传作业的结果,与 GitLab Pages 一起使用。 |
parallel | 应该并行运行多少个作业实例。 |
release | 指示运行器生成 release 对象。 |
resource_group | 限制作业并发 |
retry | 在失败的情况下可以自动重试作业的时间和次数 |
rules | 用于评估和确定作业的选定属性以及它是否已创建的条件列表 |
script | 由 runner 执行的 Shell 脚本。 |
secrets | 作业所需的 CI/CD secret 信息。 |
services | 使用 Docker 服务镜像。 |
stage | 定义作业阶段。 |
tags | 用于选择 runner 的标签列表。 |
timeout | 定义优先于项目范围设置的自定义作业级别超时。 |
tags | 用于选择 runner 的标签列表。 |
trigger | 定义下游流水线触发器。 |
variables | 在作业级别定义作业变量。 |
when | 何时运行作业 |
gitlab-ci.yml 实战配置
artifacts
用于存储构建生成的结果,例如编译后的二进制文件、测试报告、构建产物等。Artifacts 是在作业级别生成并存储的,它们在作业完成后,可以供其他作业或管道阶段使用。Artifacts 可以被下载、浏览和保存在 GitLab 服务器上。
- 定义每个作业的产物
- 同一流水线后期的后续作业可以使用产物
- 不同的项目不能共享产物
- 默认情况下,产物会在30天后过期。您可以自定义到期时间
- 如果启用了保留最新产物,则最新的产物不会过期。
- 使用依赖来控制哪些作业获取工件。
下面的配置是把打包之后的产物 build提供给后面的作业使用
yml
stages: # List of stages for jobs and their order of execution
- build
- deploy
build-job: # job的名称,自定义
stage: build # job所处的阶段
script: # 执行的脚本
- npm install
- npm run build
artifacts: # 作业的产物
paths:
- "build/"
pages:
stage: deploy # Set this new job to run in the `deploy` stage
script:
- cp -rf build/* /usr/web/test-cicd-myserver/ # 将打包后的文件放到对应的目录下
这是一个完整的部署配置
访问 http://150.158.75.248:3000/ 会看到部署的页面
cache
cache
是用于缓存构建过程中的依赖项,例如依赖库、依赖的软件包等。缓存是在不同的 CI/CD 作业之间共享的,以便加快构建过程的速度。当一个作业完成时,可以将特定的文件或目录缓存下来,以便在后续的作业中重复使用。当下一个作业执行时,它可以从缓存中检索所需的依赖项,而不是重新从头构建这些依赖项。Cache 是存储在 GitLab 服务器上的,并在作业级别进行管理。
yml
stages: # List of stages for jobs and their order of execution
- install_dependencies
- build
- deploy
install_dependencies:
stage: install_dependencies
cache:
key: node_modules_cache
paths:
- node_modules/
script:
- npm install
build-job:
stage: build
cache:
key: node_modules_cache
paths:
- node_modules/
script:
- npm run build
artifacts: # 产物
paths:
- "build/"
pages:
stage: deploy # Set this new job to run in the `deploy` stage
script:
- cp -rf build/* /usr/web/test-cicd-myserver/
缓存存在/home/gitlab-runner/cache/root/test-cice-myserver/
目录下
第一次提交代码,runner执行的时候没有发现缓存,会继续执行npm isntall
下载依赖。当下次提交代码后,runner检测到有cache,不会再执行npm install
脚本,节省发布时间
对比下没缓存和有缓存花费的总时间
下载依赖,build,都在同一个阶段只想
无缓存
yml
stages: # List of stages for jobs and their order of execution
- install_build
install_build:
stage: install_build
script:
- npm install
- npm run build
- cp -rf build/* /usr/web/test-cicd-myserver/
执行时间
有缓存
yml
stages: # List of stages for jobs and their order of execution
- install_build
install_build:
stage: install_build
cache:
key: node_modules_cache_v2
paths:
- node_modules/
script:
- npm install
- npm run build
- cp -rf build/* /usr/web/test-cicd-myserver/

由于项目是一个刚创建的项目,里面依赖的node包很少,所以看起来有缓存和无缓存差距不大,但是当项目越来越大,依赖的插件越来越多,缓存还是很有必要的
清除缓存

artifacts 和 cache 的区别
artifacts
paths
关键字确定将哪些文件添加到作业产物中。 文件和目录的所有路径都相对于创建作业的仓库。
yml
build-job:
stage: build
script:
- npm run build
artifacts: # 产物
paths:
- "build/"
cache
cache:paths
选择要缓存的文件或目录
es: 缓存binaries下.apk后缀的文件和。config文件
yml
rspec:
script:
- echo "This job uses a cache."
cache:
key: binaries-cache
paths:
- binaries/*.apk
- .config
- cache:key 给缓存一个唯一的标识(没有设置默认值为default) es:
yml
cache-job:
script:
- echo "This job uses a cache."
cache:
key: binaries-cache-$CI_COMMIT_REF_SLUG
paths:
- binaries/
key值不能包含:
-
/符号或者 二进制
-
The
/
character, or the equivalent URI-encoded%2F
. -
Only the
.
character (any number), or the equivalent URI-encoded%2E
. -
cache:key:files 定义在一个或两个文件改变时重新生成
缓存存放的位置
docs.gitlab.com/ee/ci/cachi...
注册docker runner

yml
yml
stages: # List of stages for jobs and their order of execution
- install_build
install_build:
stage: install_build
# cache:
# key: node_modules_cache_v2
# paths:
# - node_modules/
script:
- npm install
- npm run build
- cp -rf build/* /usr/web/test-cicd-myserver/
tags:
- docker
因为服务器上没有安装docker,所有报错了。
centos 安装docker
job

因为脚本是在docker中执行的,找不到
/usr/web/test-cicd-myserver/
所以要换一种办法将dist包上传到服务器
配置 服务器gitlab-runner runner配置
bash
vim /etc/gitlab-runner/config.toml

这样操作 docker容器里的 /builds/root/test-cicd-myserver 目录,服务器/usr/web/test-cicd-myserver也会同步
yml
bash
stages: # List of stages for jobs and their order of execution
- install_build
install_build:
image: node:14
stage: install_build
script:
- npm install
- npm run build
- echo $DEV_DEPLOY_HOST
- rm -rf /builds/root/test-cicd-myserver/*
- cp -r build/* /builds/root/test-cicd-myserver/
tags:
- docker

可以看到部署成功
上面使用了shell 和 docker 两种不同的runner,但是可以看到,runner 和部署后的dist包都是在同一台服务器上,但我们很多情况下是需要部署多台服务器,所以我们可以用先登录要部署的服务器,然后上传文件到目标服务器即可。
配置免密登录
本地生成一对秘钥

拿到秘钥,将它添加到gitlab 变量里面,分别命名为私钥 SSH_PRIVATE_KEY 和 公钥SSH_PUBLIC_KEY
配置 DEV_DEPLOY_HOST 自己要部署项目的服务器ip或域名 配置 ETC_HOSTS 值 StrictHostKeyChecking no 设置known_hosts新增公钥时不提示
另外配置SSH_CONFIG

配置yml
ba'sh
stages: # List of stages for jobs and their order of execution
- install_build
before_script:
# 配置ssh,添加私钥,设置known_hosts新增公钥时不提示
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- echo "$SSH_PUBLIC_KEY" > ~/.ssh/id_rsa.pub && chmod 644 ~/.ssh/id_rsa.pub
- echo "$SSH_CONFIG" >> ~/.ssh/config
- echo "$ETC_HOSTS" >> /etc/hosts
- cat ~/.ssh/known_hosts
install_build:
image: node:14
stage: install_build
# cache:
# key: node_modules_cache_v2
# paths:
# - node_modules/
script:
- npm install
- npm run build
# 执行脚本 DEV_DEPLOY_HOST 为cicd预设变量
- bash scripts/deploy.sh $DEV_DEPLOY_HOST
tags:
- docker
scripts/deploy.sh
basg
#!/bin/bash
set -e
cd `dirname $0` && cd ..
echo $0
pwd
# D_HOST='[email protected]'
# [email protected]
D_HOST=$1
NOW=`date "+%Y%m%d_%H%M%S"`
PACKAGE_NAME="$NOW.tar.gz"
PACKAGE_DIR_SOURCE="build"
PACKAGE_DIR="test-cicd-myserver"
MY_PATH="/usr/web/"
D_PATH="/usr/web/"
# 修改文件名build(打包生成的)为test-cicd-myserver(服务器部署的文件目录名字),然后压缩,压缩后的文件名是当前时间命名的
mv $PACKAGE_DIR_SOURCE $PACKAGE_DIR && tar -zcf $PACKAGE_NAME $PACKAGE_DIR
# 上传压缩包到服务器/usr/web/目录下
scp $PACKAGE_NAME "$D_HOST:$D_PATH"
# 登录服务器,进入/usr/web/目录,删除旧的test-cicd-myserver ,解压缩上传的文件,至此新的打包内容就上传到了服务器
ssh "$D_HOST" "cd $D_PATH && rm -rf $PACKAGE_DIR && tar -zxf $PACKAGE_NAME && echo $PACKAGE_NAME successfully deployed!"
运行遇到问题,这是 让我们请教下chart-gpt

于是做出一下修改
bash
stages: # List of stages for jobs and their order of execution
- install_build
before_script:
# 配置ssh,添加私钥,设置known_hosts新增公钥时不提示
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- echo "$SSH_PUBLIC_KEY" > ~/.ssh/id_rsa.pub && chmod 644 ~/.ssh/id_rsa.pub
- echo "$SSH_CONFIG" >> ~/.ssh/config
- echo "$ETC_HOSTS" >> /etc/hosts
# 解决Host key verification failed.问题
- ssh-keyscan 150.158.75.248 >> ~/.ssh/known_hosts
- cat ~/.ssh/known_hosts
install_build:
image: node:14
stage: install_build
# cache:
# key: node_modules_cache_v2
# paths:
# - node_modules/
script:
- npm install
- npm run build
# 执行脚本 DEV_DEPLOY_HOST 为cicd预设变量
- bash scripts/deploy.sh $DEV_DEPLOY_HOST
tags:
- docker
从新运行,可以看到成功啦

小总结
初次写这么长的文章,感觉写的逻辑有些混乱,自己对cicd 也不是非常熟悉,但这都是自己实际操作一遍写出的文章。
如果有同学看不懂或者写的不对地方,可随意指出,我一定改正。
参考文章
GitLab CI/CD 自动化部署入门 ,手把手教你搭建 ------ 从安装 Linux 到 GitLab 自动化部署
ubantu 安装gitlab www.jianshu.com/p/6cd5eecd8... cloud.tencent.com/developer/a...