写在前面
本文的目的有2点:
1、是使用一个他人都无权访问的项目(gitlab-deployment
),来集中控制所有需要通过gitlab-runner
部署的项目。
2、针对所有需要部署的项目中的.gitlab-ci.yml
文件,尽可能简化、复用、最小化改动及最大的自定义灵活度配置。
控制部署项目的思路是:
用一个项目仓库集中定义gitlab-runner
所需配置文件,并且增加gitlab-runner
执行器来进行必要的配置文件覆盖动作,保证当此gitlab-deployment
项目代码一提交就能被其他gitlab-runner
立即应用。
以下是gitlab-deployment
控制部署的项目.gitlab-ci.yml
文件内容:
#声明变量,指定当前docker化的gitlab-runner执行器容器名称
#相对于当前项目的文件路径,这里是gitlab-runner相关的文件夹
#指定gitlab-runner文件夹下各种阶段配置文件存放的文件
#指定在docker化的gitlab-runner执行器容器中的路径,后续需要把一些文件放到这里
variables:
GITLAB_CI_DOCKER_NAME: gitlab-runner
GITLAB_CI_PROJECT_NAME: gitlab-runner
GITLAB_CI_PATH_YML: docker/static
GITLAB_CI_CONF_PATH_YML: /home/gitlab-runner
stages:
- cp_gitlab_ci
cp_gitlab_ci:
stage: cp_gitlab_ci
script:
- docker cp $GITLAB_CI_PROJECT_NAME/$GITLAB_CI_PATH_YML $GITLAB_CI_DOCKER_NAME:$GITLAB_CI_CONF_PATH_YML
- echo "static:"`ls -a $GITLAB_CI_CONF_PATH_YML/static`
然后使劲在这个项目的文件夹下写脚本吧,一提交,ci
会自动同步。
就像这样:
使劲写脚本的思路:
将原来的脚本使用了抽象模式进行了重构。
主要抽象层为:
ci
过程抽象- 公共
ci
抽象 - 编译/打包抽象
- 虚拟化抽象
- 部署抽象
一、ci
过程抽象
定义一个项目进行ci的通用流程,这个抽象理论上能适应所有类型的项目ci
过程。
这里我拿java
项目举例,.gitlab-ci.yml
内容如下:
#最高级别的变量声明,会覆盖其他地方的变量声明
variables:
# MAVEN_CLI_OPTS: settings.xml #不使用默认的仓库进行编译打包,使用当前项目源代码中的settings.xml文件作为私服仓库
PROJECT_NAME: test #项目名
PROJECT_LAUNCH_PORT: 8080 #项目启动的端口
PROJECT_DOCKER_PORT: 8081 #docker服务端口
#使用一个他人都无权访问的项目进行集中配置装载
include:
- project: deployment/gitlab-deployment
ref: master
file: /gitlab-runner/docker/static/.gitlab-ci-common.yml
- project: deployment/gitlab-deployment
ref: master
file: /gitlab-runner/docker/static/.gitlab-ci-maven.yml
- project: deployment/gitlab-deployment
ref: master
file: /gitlab-runner/docker/static/.gitlab-ci-docker.yml
- project: deployment/gitlab-deployment
ref: master
file: /gitlab-runner/docker/static/.gitlab-ci-docker-run.yml
#前脚本,这里手动指定jdk版本,不指定就使用默认的
before_script:
- export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
- export JRE_HOME=${JAVA_HOME}/jre
- export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
#定义通用ci流程
stages:
- build_compile_code
- build_docker
- build_clean
- run_docker
二、公共ci
抽象
将通用的部分抽离出来,高度复用。
.gitlab-ci-common.yml
variables:
COMMIT_TIME: $(git show -s --format=%ct $CI_COMMIT_SHA)
cache:
key: maven-ci-cache
paths:
- .m2/repository
- target/*.jar
这个文件内容我就不说明了,不清楚的看前一篇博客gitlab-runner使用pipeline自动构建发布springboot项目
三、编译/打包抽象
顾名思义,这是对源代码编译成具体的文件的过程,我拿maven
举例,根据项目技术类型不同,在第一步的ci
过程抽象中对应替换此文件的include
即可。
以下是.gitlab-ci-maven.yml
文件的内容:
variables:
MAVEN_CLI_OPTS: "/home/gitlab-runner/static/settings.xml"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
maven_build_compile_code:
stage: build_compile_code
script:
- mvn -s $MAVEN_CLI_OPTS clean compile package -Dmaven.test.skip=true -P sit
- echo "target:"`ls target`
maven_build_clean:
stage: build_clean
script:
- mvn -s $MAVEN_CLI_OPTS clean
这个文件内容我也不说明了,不清楚的看前一篇博客gitlab-runner使用pipeline自动构建发布springboot项目
四、虚拟化抽象
将单编译或者多编译进行虚拟化,这个虚拟化可能是多种方式的。
我这里以在执行器中虚拟化成docker
镜像举例。
.gitlab-ci-docker.yml
build_docker:
stage: build_docker
script:
- docker build . -t $PROJECT_NAME:$CI_COMMIT_SHORT_SHA
五、部署抽象
根据第四步虚拟化的方式和程度不同,还有部署的情况不同(多节点,单机、灰度等)这里可以进行适当调整。
我这里以主机docker
方式举例。
.gitlab-ci-docker-run.yml
run_docker:
stage: run_docker
script:
- docker stop $PROJECT_NAME || true
- docker rm $PROJECT_NAME || true
- docker run --name $PROJECT_NAME -p $PROJECT_DOCKER_PORT:$PROJECT_LAUNCH_PORT --privileged=true -d $PROJECT_NAME:$CI_COMMIT_SHORT_SHA
这个文件内容我也不说明了,不清楚的看前一篇博客gitlab-runner使用pipeline自动构建发布springboot项目
抽象过程总结
- 对于要部署的项目:只需要将
ci
过程抽象的.gitlab-ci.yml
内容按需替换即可,对项目本身没有多余入侵;对于自定义的仓库及编译环境也有很好的切换支持。 - 对于编译/打包环节:不同的技术栈项目,只需要对应写一个编译/打包阶段的
yml
文件即可。 - 对于虚拟化环节:不同的技术栈的虚拟化稍微有一点点区别,不同的虚拟化方式又有一点点区别,但是只需要写一次虚拟化
yml
即可按情况引用。 - 对于部署环节:不同的虚拟化方式,部署也对应不同,一次对应
yml
部署文件编写即可后续按需复用。 - 在此结构上,可以方便的增加,减少,修改所需阶段,实时生效
对于复杂多分发的及其他的模式的虚拟化或者编译打包,我没精力都写一遍,各位看官举一反三把,我相信看得懂的人,肯定觉得我这篇是水文,这篇文章本质上只是表达了一种新的玩法;看不懂的,我写再多也是看不懂。得了收工。
评论区