GitLab CI/CD
(Continuous Integration/Continuous Deployment
)是 GitLab
提供的一种持续集成和持续部署的解决方案。它可以自动化软件的构建、测试和部署过程,以便开发者更快地、更频繁地发布可靠的产品。
整体过程如下图所示:
首先需要在目标机器上部署 Runner
服务,并注册到 gitLab
中,然后在项目中编写 .gitlab-ci.yml
文件,并执行流水线规则,当开发人员提交代码到远程仓库时,根据 .gitlab-ci.yml
文件配置信息,通知 Runner
执行相关脚本等 ,其中会涉及到几个核心特征如下:
Pipeline:一系列按照特定顺序执行的作业。这些作业可以被分配到不同的阶段,每个阶段都会按照定义的顺序依次执行。如果一个阶段中的所有作业成功完成,那么就会执行下一个阶段。
Jobs and Stages:构成 pipeline
的基本单元,每个作业都包含一系列的脚本命令。阶段则是用来组织作业的方式,它允许你控制作业的执行顺序。
Runners:执行作业的服务器。Runner
可以在各种环境中安装和使用,包括 Linux, Windows, Docker, Kubernetes
等。
Artifacts:由作业生成的文件,可以在作业结束后保留下来。你可以在之后的作业中使用这些 artifacts
,或者直接从 GitLab
下载。
Environment and Deployment:GitLab CI/CD
允许定义多个环境,例如测试环境、预生产环境和生产环境,然后在这些环境中部署你的应用。
.gitlab-ci.yml:GitLab CI/CD
的配置文件,定义了 pipeline
中的所有作业和阶段。
下面通过GitLab CI/CD
持续集成/部署 SpringBoot
项目以演示整个的使用过程。
其中 SpringBoot
项目通过 docker
运行并采用 docker-compose
管理,因此需要保证服务器端环境已经部署好了 docker
和 docker-compose
,由于是 java
项目,jdk
也要事先准备完成。
关于 GitLab
的部署可以参考下面这篇文章:
使用 docker-compose 搭建私服 Gitlab
这里先创建一个 SpringBoot
项目,并编写好测试接口:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/t1")
public String t1(){
return "this is server >>> t1 ";
}
}
由于采用 docker
运行,所以在项目根目录创建 Dockerfile
文件,内容如下:
FROM java:8
MAINTAINER bxc
WORKDIR /app
ADD target/test-project-0.0.1-SNAPSHOT.jar /app/app.jar
CMD ["java", "-jar", "app.jar","--spring.profiles.active=pro"]
在 gitlab
上创建项目 test-project
:
将刚刚创建好的 SpringBoot
项目 push
到 test-project
中:
Runner
可以部署在目标机器上,也就是最终运行服务的机器上,也可以是单独的机器通过 ssh
控制目标机器部署服务。
安装 Runner
:
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash
yum install gitlab-runner
首先到 GitLab
test_project
项目下设置下的 CI/CD
下:
找到 Runners
点击展开:
将上面红框中的数据记录下来,等下注册时需要使用。
再次回到部署 Runner
的服务器中,执行下面指令:
gitlab-runner register
按照提示的步骤输入上述相关信息:
GitLab
服务器的 URL
,上面图片中的第二点。Runner
的令牌,上面图片中的第三点。Runner
的描述,用于在 GitLab UI
中识别你的 Runner
。Runner
。当你在 .gitlab-ci.yml
文件中定义作业时,可以指定需要哪些标签的 Runner
来执行这个作业,这里我的 tags
为:runner
。Runner
的额外信息,比如配置详情、负责维护的人、最后一次更新或维护的日期等。Runner
如何执行 CI/CD
作业。GitLab Runner
支持多种 Executor
,包括 shell, docker, ssh, virtualbox
等,我这里选择 shell
的形式。操作完后可以到 gitlab
上刷新页面查看是否注册成功:
由于是基于 Maven
管理的 SpringBoot
依赖,因此需要在 Rnner
的机器上部署 Maven
:
下载 maven
包 :
https://maven.apache.org/download.cgi
将下载的安装包上传至服务器中,这里我是 /opt/maven
下
解压安装包:
tar -zxvf apache-maven-3.9.5-bin.tar.gz
在 conf/settings.xml
增加阿里镜像源:
<mirror>
<id>alimavenid>
<name>aliyun mavenname>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
<mirrorOf>centralmirrorOf>
mirror>
将 maven
命令添加到环境变量中:
vi /etc/profile
追加以下内容:
export MAVEN_HOME=/opt/maven/apache-maven-3.9.5
export PATH=$MAVEN_HOME/bin:$PATH
刷新配置
source /etc/profile
测试查看maven
版本
mvn -v
在 SpringBoot
项目根目录创建 .gitlab-ci.yml
文件,先测试下打印 hello world
,内容如下:
stages:
- deploy
deploy-job:
tags:
- runner
stage: deploy
script:
- echo "hello world"
提交代码至远程仓库:
git add .
git commit -m 'ci'
git push
到 gitlab
中刷新查看:
这里绿色的对号表示已经执行成功了 .gitlab-ci.yml
中的定义,可以点击进去查看:
点击 deploy-job
可以查看执行结果:
由于是采用 docker-compose
管理运行 SpringBoot
项目,这里在根目录创建 docker-compose.yml
,内容如下:
version: '2.0'
services:
test-project:
restart: always
image: test-project:1.0
container_name: test-project
ports:
- "8080:8080"
networks:
- test
networks:
test:
修改 .gitlab-ci.yml
文件,增加打包部署的脚本:
stages:
- deploy
deploy:
tags:
- runner
stage: deploy
script:
- pwd
- mvn clean package
- docker-compose down
- docker build -t test-project:1.0 .
- docker-compose up -d
提交至远程仓库:
到 gitlab
中查看:
点击可以看到运行的日志:
如果在打包镜像的时候报下面错误:
Couldn’t connect to Docker daemon at http+docker://localhost - is it running?
在安装 Runner
的时候会默认创建一个 gitlab-runner
用户,该用户需要有操作 docker
的权限 :
为 gitlab-runner
用户授权:
sudo usermod -aG docker gitlab-runner
重启 docker
:
sudo systemctl restart docker
然后再重新运行流水线。
流水线运行结束后到机器上docker ps
查看是否有 test-project
容器:
容器已经启动了,可以通过浏览器访问测试接口:
http://ip:8080/test/t1
下面再创建一个测试接口 t2
:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/t1")
public String t1(){
return "this is server >>> t1 ";
}
@GetMapping("/t2")
public String t2(){
return "this is server >>> t2 ";
}
}
提交代码到远程仓库:
等待流水线构建成功:
访问 t2
测试接口:
http://ip:8080/test/t2
成功访问到 t2 测试接口。