目录
前言
主要用来记录自已怎么通过gitlab-cicd实现自动化部署
通过git代码来触发自动更新
具体的参考资料如下:
主要的视频链接如下:
GitLab CI/CD系列教程
以下博客知识点大部分来源于该b站视频知识(非常不错,推荐)
关于下面的技术点中遇到的错误以及实战遇到的错误
都可看我这篇博客知识:
Gitlab CI/CD中的yml遇到的错误分析含解决方法(全)
1. 技术知识
1.1 docker安装gitlab
可以使用公司的gitlab或者官方的gitlab的平台(使用公司平台上的gitlab比较简单,下面实战的情况我也会讲到)
个人的话也可 通过docker安装gitlab
如果通过docker安装gitlab,具体安装如下:
sudo docker run --detach \
--hostname 域名
--publish 443:443 --publish 80:80 --publish 222:22 \
--name gitlab \
--restart always \
--volume /srv/gitlab/config:/etc/gitlab \
--volume /srv/gitlab/logs:/var/log/gitlab \
--vlolume /srv/gitlab/data:/var/opt/gitlab \
gitlab /gitlab-ce:last
关于以上命令的部分讲解:
detach是后台运行,
宿主机的端口号:容器端口号
restart always自动会重启
目录的映射,本地配置或者查看等等(保存在本地)
容器被删除或者清空就没有了,所以挂载到本地是不错的选择
执行上面的命令之后
通过docker container ls -a
通过docker logs -f gitlab 即可查看其启动的日志,-f的参数是实时日志的意思
如果要让域名解析成功,要添加一个云解析也就是dns解析,才可通过域名进行访问
否则只能进行服务器的ip进行访问
关于gitlab的项目推送以及拉取
可看我之前对git的讲解文章:
1.2 docker安装gitlab-runner
前言知识:
两大要素分别为gitlab-runner的环境,以及.gitlab-ci.yml的配置文件书写
cicd就是持续集成以及持续的部署
持续集成就是提交一个分支的时候会去检查代码模块一条流水线pipeline有多个stages,每个stages有多个jobs(任务是流水线最小的单元)
这些任务都是在gitlab-runner在跑,gitlab-runner就是一个软件,就是给流水线提供一个运行环境
一句话总结:要配置cicd的自动话部署,就要设置一个gitlab-runner的环境
yml文件就是流水线的任务以及执行任务
安装gitlab-runner的命令方式如下:
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
具体配置文件就是启动的名字,以及宕机可重启,挂载文件,拉取的版本方式等等
执行启动之后可通过docker ps查看
怎么将gitlab以及gitlab-runner联系在一起
在gitlab中的设置中就可看到runners,通过查看runner就可看到其url以及token
执行命令如下:
docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
--non-interactive \
--executor "docker" \
--docker-image alpine:latest \
--url "https://git-cc.nie.netease.com/" \
--registration--token "xxx" \
--description "runner05-4000-git-cc-1" \
--tag-list "docker" \
--run-untagged="ture" \
--locked="false" \
--access-level="not_protected"
具体其配置参数如下:
tag就是运行的runner,需要使用没有标签的tag-list
executor就是执行器,可通过docker或者k8s等等
1.3 .gitlab-ci.yml编写
关于这部分内容的书写可看这个up主相关系列的内容(超赞)
.gitlab-ci.yml关键词概览解析(一)
一般放在根目录文件下
- image 指定使用node的基础环境变量
- stages 指定三个阶段,(lint-code验证前端代码,前端代码没有lint可以不用这个)
- cache (项目名称,缓存的路径)
如果不指定stages的话,默认是test
stages:
- line code
- install
- build
- deploy
- clean
job 0:
stage: install
script: echo 'intall'
job 1:
stage: build
script: echo 'build'
job 2:
stage: deploy
script: echo 'deploy'
linecode是验证代码
script主要是执行脚本,每个任务都要进行script,每个任务都是一个单行的脚本输出,如果要执行多行的脚本,则通过如下:(retry 是重试次数,放在script执行)
script:
- echo 'deploy'
- echo ‘xx’
如果两个任务都是一样的,并不是并发执行,而是按照顺序的执行
每一个流水线只有一个执行,主要为了减少消耗,如果要配置的话,通过gitlab-runner进行配置多任务执行
另外几个常用的关键字
- images:指定一个镜像作为基础的运行环境
- tags:关键词指定runner,tags的取值范围在该项目中可见的runner tags中
- only/except:限定当前任务执行的条件
- when:在某些特殊情况或者出现故障进行运行
- cache:当前工作环境目录中的一些文件,用于各个任务初始化的时候进行恢复
具体的执行命令如下:(下面的命令都进行了注释)
执行的script要使用npm,所以一开始要引入node的这个包,alpine为精简版的格式版本
image: node:alpine
stages:
- install
- build
- deploy
cache:
key :vitepro # 代表缓存的版本,因为每个阶段都会把这个生成的包删除,所以定义一个全局变量来缓存这个cache包
paths: # 代表缓存的包名,前端的依赖包都是node_modules,具体看你项目生成的包
- node_modules
- html # 此处可不加,主要为了说明缓存的paths是一个数组,可以多缓存多个,这样进行缓存
job_install:
stage: install
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- npm install
job_build:
stage: build
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- npm run build
only:
- release # 指定的是一个分支,在master的分支会看不到这个任务,执行的时候被隐藏起来不被看到
job_deploy:
stage: deploy
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- echo 'deploy'
when: manual # 此处配置成一个手动的内容,可加可不加
1.4 使用docker部署前端项目
先修改一个docker的配置文件
docker 要配置一个目录卷,如果不配置的话就会出错,主要在runner配置文件里配置
具体配置方式如下:
vim /src/gitlab-runner/config/config.toml
文件中主要的代码讲解,以及每个runner的配置,找到runner的配置
多少个流水线
多久检查一次流水线
在volumes的配置,配置docker的配置,多一个映射的配置
找到runner的name名字
修改下面的volumes,增加一些容器
主要参数如下:
/usr/bin/docker:/usr/bin/docker,/var/run/docker.sock:/var/run/docker.sock
添加的界面如下:
配置完成之后开始下面的步骤:
前面的gitlab以及gitlab-runer已经执行了
主要是yml文件的书写
此处讲解一下ym文件的书写:
image: node:alpine
stages:
- install
- lint-code
- build
- deploy
cache:
key :vitepro # 代表缓存的版本,因为每个阶段都会把这个生成的包删除,所以定义一个全局变量来缓存这个cache包
paths: # 代表缓存的包名,前端的依赖包都是node_modules,具体看你项目生成的包
- node_modules
job_install:
stage: install
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- npm install
job_build:
stage: build
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- npm run build
job_deploy:
stage: deploy
image: docker #下面有运行到docker,所以要引入docker的镜像
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- docker build -t xx . #产生这个镜像
- if [ $(docker ps -aq --filter name==xx-container) ]; then docker rm -f xx-container;fi # 判断当前有没有这个容器
- docker run -d -p 15599:15599 --name xxxx
如果npm install的包比较多,可以通过重试次数或者缓存进行优化等等
-t 后面接的是镜像名称
本地可能已经有了这个容器,所以要提前判断是否有这个容器并且进行删除
docker build -t xx .这一步要成功的话,要编写一个Dockerfile文件
主要的文件格式如下:
FROM node:latest as builder
WORKDIR /app
COPY package.json .
RUN npm install -- registry==http://registry.npm.taobao.org
COPY . .
RUN npm run build
FROM nginx:latest
COPY -- from=builder /app/dist /usr/share/nginx/html
1.5 使用阿里云oss部署前端项目
oss的介绍以及创建bucket
oss本身就是服务器,本身可以设置静态网站的托管,以及cdn的加速,绑定域名等等
通过创建Bucket设置项目,存储项目的文件
将文件上传到oss服务器
可以使用命令行工具ossutil、图像化工具ossbrowser、数据迁移工具ossimport等
image: node:alpine
stages:
- install
- lint-code
- build
- deploy
cache:
key :vitepro # 代表缓存的版本,因为每个阶段都会把这个生成的包删除,所以定义一个全局变量来缓存这个cache包
paths: # 代表缓存的包名,前端的依赖包都是node_modules,具体看你项目生成的包
- node_modules
job_install:
stage: install
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- npm install
job_build:
stage: build
tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
script:
- npm run build
artifacts:
paths:
- dist/ # 存储起来生成制品,每个任务都可使用
job_deploy_oss:
stage: deploy
tags:
- vite
script:
- wegt htttp://gosspublic.alicdn.com/ossutil/1.6.18/ossutil64 # 下载到这个目录
- chmod 755 ossutil64 #给这个权限赋值
- ./ossutil64 config -e ${endpoint} -i ${accessKeyID} -k ${accessKeySecret} -L CH --loglevel debug -c ~/.ossutilconfig
- ./ossutil64 -c ~/.ossutilconfig cp -r -f dist oss://xxx/
when: manual
关于这个命令的补充说明- ./ossutil64 config -e ${endpoint} -i ${accessKeyID} -k ${accessKeySecret} -L CH --loglevel debug -c ~/.ossutilconfig
将其文件配置好权限之后写入到oss的一个配置文件中
- endpoint是区域地址,是oss的一个地址
- accessKeyID是阿里云内的所有资源
- accessKeySecret是密钥
后面的具体参数L是选择语言,选择ch为utf-8,loglevel是日志等级,-c为配置文件
./ossutil64 -c ~/.ossutilconfig cp -r dist oss://xxx/, cp上传到oss文件
c是指定配置文件,cp是上传文件,r是递归上传,f为强制覆盖原有的文件(如果不加这个参数,修改代码自动部署更新不成功)
跟上面的代码模块不同之处在于这里还有一个生成制品
artifacts:
paths:
- dist/ # 存储起来生成制品,每个任务都可使用
主要为了后续每个任务都使用到,也节省了时间
1.6 变量的注入以及使用
比如账号密码的使用不让别人看到
可以通过yml文件中通过variables定义
通过pipeline中预定义使用变量或者在项目中设置变量
这些变量可以设置key value或者文件格式
流水线中设置变量定义
variables:
MT_VAR: " my name is manongyanjiuseng"
log_var:
script:
- echo $MT_VAR
项目中设置变量
可通过pipeline中设置key value(变量不可使用空格,要大于8个,不可和cicd的一些变量冲突)
protect variable 主要是master分支不可使用
mask可以进行遮罩
项目中的书写如下:
log_project_var:
script:
- echo $NAME
类似前面所讲到的docker部署前端项目
通过存储镜像或者容器设置成变量存储,只需要修改一次即可
导出所有变量可以通过export进行输出
get_all_var:
script:
- export
变量的使用可以 如下:url name inclued 制品名称 镜像名称等等
1.7 流水线的类型以及触发方式
流水线的基本类型:
基本流水线、DAG流水线、多项目流水线、父子流水线以及合并请求流水线
流水线的触发方式有:
推送代码、定时触发(在设置中的schedule)、url触发以及手动触发
DAG流水线可以挂平台,测试部署的时候会有不一样的依赖平台
例子:
stages:
- build
- test
- deploy
image:alpine
build_a:
stage: build
script:
- echo 'build_a'
build_b:
stage: test
needs: [build_a]
script:
- echo 'build_b'
test_a:
stage: test
needs: [build_a]
script:
- echo 'test_a'
test_b:
stage: test
needs: [build_b]
script:
- echo 'test_b'
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo 'deploy_a'
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo 'deploy_b'
其DAG的流水线具体如下:
needs表明依赖什么任务的流水线
父子流水线:(标准的gitlab流水线就是父子)
stages:
- test
- triggers
- deploy
testjob:
stage: test
script: echo 'test'
trigger_a:
stage: triggers
trigger:
include: a/.gitlab-ci.yml # 当前项目包括另外的流水线
rules: # 修改这个文件就会触发
- changes:
- a/*
trigger_b:
stage: triggers
trigger:
include: b/.gitlab-ci.yml
rules:
- changes:
- b/*
先执行上游的流水线,在执行下游的流水线
多项目流水线(微服务流水线,想要拆成多项目,也就是同时发版),由入口流水线触发其他任务的流水线
stages:
- test
- triggers
- deploy
testjob:
stage: test
script: echo 'test'
trigger_a:
stage: triggers
trigger:
include: a/.gitlab-ci.yml # 当前项目包括另外的流水线
rules: # 修改这个文件就会触发
- changes:
- a/*
trigger_b:
stage: triggers
trigger:
include: b/.gitlab-ci.yml
rules:
- changes:
- b/*
trigger_b:
stage: deploy
trigger:
project: root/plain_html # 触发什么项目
branch: master
strategy: depend # 触发流水线会在这个任务上显示出来
合并流水线:
合并的时候做一些验证,主要加一些参数
具体如下:
only:
- merge_requests
流水线触发的方式:
curl -X POST \
-F token=xx \
-F ref=master \
http://gitlab.yuming
其他的方式在gitlab cicd 的设置中 都可看到
1.8 ssh远程服务器部署
关于ssh访问GitHub
之前我也写过一篇文章
也可参考此处:
GitHub中配置ssh来clone以及pull等(图文版本解释)
生成公钥和密钥
ssh-keygen -t rsa -b 2048 -C "zhanghao"
# 复制公钥到服务器上,找到当前路径
scp -r id_ras.pub zhanghao@ip:/root/.ssh/authorized_keys
将其密钥保存在cicd设置中
yml文件的书写:
image: node:latest
stages:
- install
- build
- deploy
cache:
key:
files:
- package-lock.json # 锁定依赖包的版本
paths:
- node_modules
.set-tags: &set-tags # 定义一个锚点
tags:
- vite
install _job:
<<: *set-tags #之后引用锚点,将其引入这里
stage: install
script: npm install
deploy_job:
<<: *set-tags
stage: build
script: npm run build
artifacts:
paths:
- dist
#把这个制品恢复到下面
deploy-job:
<<: *set-tags
stage: deploy
#执行script前 执行before_script安装一些环境
before_script:
- 'which ssh-agent || ( yum update -y && yum install openssh-client git -y)'
- eval $(ssh-agent -s)
- echo "SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan 服务器ip >> ~./ssh/host # 保存在host的目录
- chmod 644 ~/.ssh/host
script:
- echo 'start scp'
- scp -r dist root@ip:/usr/local/www # 本机的工作目录上传到服务器
关于该文件,其实官方的代码模块也有此讲解
1.9 流水线调试手段
关键词:release、timeout以及rousource_group
interruptible 新的流水线被触发了,旧的流水线就会被取消,保留最新的流水线
有利于防止资源的消耗,自动的取消达到一个良好的环境
前提是勾选gitlab中的这个选项(搭配使用)
yml文件的书写:
stages:
- install
- build
- deploy
install_job:
stage: install
script:
- echo 'start'
- sleep 60
- echo 'end '
interruptible: true # 默认是false
build_job:
stage: build
script:
- echo 'start'
- sleep 60
- echo 'end '
interruptible: true
create_release: # 把长生的镜像放到release
image: registry.gitlab.com/gitlab-org/release-cli:latest
stage: build
script: echo 'start'
release:
tag_name: $CI_COMMIT_TAG #名称如果没有的话会自动设置tag_name
only:
- tags # 在项目的仓库中打了tags的时候就会执行这个
deploy:
stage: deploy
environment:
name: staging
script:
- echo 'start '
- sleep 120
resource_group:prod # 配置了字符串
- timeout:时间如果运行太久的话会自动被取消
- resource_group:限定并发任务,避免了部署任务的不可控
调出debug设置
已经确定你在服务器上安装了gitlab-runner
所以只需要在配置文件中添加如下设置:
vim /srv/gitlab-runner/config/config.toml
增加如下设置:
[session_server]
listen_adress = "[::]:8093"
advertise_adress = 'ip:8093'
session_timeout = 1800
之后在pipeline的时候出错就会有debug
部署冻结:(此时间不可部署)确保环境的安全
在设置中添加限制时间
在yml文件中添加如下代码:
deploy:
stage: deploy
environment:
name: staging
script:
- echo 'start '
- sleep 120
resource_group:prod # 配置了字符串
rules:
- if: $CI_DEPLOY_FREEZE == null # 如果时间为空或者不在这个范围才可部署
2. docker部署前端项目(内网)
以下代码自已写的
(运行时间4分钟),可大致参考
自带的gitlab,所以没有通过docker安装gitlab
只需要在服务器上安装gitlab-runner来了解gitlab即可
通过docker安装gitlab-runner,输入与gitlab搭配的桥梁的url以及token桥梁
所以需要将其gitlab-runner的配置文件中的auth写入
variables:
DOCKER_AUTH_CONFIG: '{"auths": {"$AUTH_USER": {"auth": "$AUTH_KEY"}}}'
# 此处用内网的镜像 是因为docker的镜像有拉取限制
image: 内网域名/mirror_docker.io/library/node:latest
stages:
- install
- build
- deploy
cache:
key: xx# 项目名称,这个可以随意,如果不取系统会默认给你一个key
paths:
- node_modules ##指定缓存路径
job_install:
stage: install
tags:
- xx-docker # 指定运行的runner,此处在gitlab中的设置 runner可查看
script:
- npm install
job_build:
stage: build
tags:
- xx-docker
script:
- npm run build
job_deploy:
stage: deploy
image: 内网域名/mirror_docker.io/library/docker:stable-dind
tags:
- xx-docker
script:
- docker build -t xx.
- if [ $(docker images -q -f dangling=true) ]; then docker rmi $(docker images -q -f dangling=true); fi
- if [ $(docker ps -aq --filter name=xx-container) ]; then docker rm -f $(docker ps -aq --filter name=xx-container);fi
- docker run -d -p 8082:80 --name xx-container xx# 使用新的容器
- echo 'start deploy'
关于上面文件中的build -t代码模块的执行
主要通过Dockerfile进行编译:
FROM node:latest as build
WORKDIR /xx
COPY package.json .
RUN npm install --registry=http://registry.npm.taobao.org
COPY . .
RUN npm run build
From nginx:latest
COPY --from=build /xx/build /usr/share/nginx/html
以上代码模块是打通内网的镜像
通过服务器ip地址:8082地址访问
如果是打通外网,则还需要配置域名以及dns解析