持续集成实现方案
GitLab Runner
它是一个轻量级的执行器,用于将你的构建、测试和部署作业运行在你的 CI/CD 环境中;
以 Ubuntu 系统示例,下面演示了提交 Java 代码时,自动编译打包、构建镜像并运行容器的过程;
基本步骤为: 构建 GitLab Runner 镜像-> 为 GitLab 中项目注册 Runner -> 提交代码触发 Runner -> 编译并构建项目镜像 -> 自动运行
环境准备
提示
安装 GitLab Runner 时版本号最好和 GitLab 保持一致,以免发生兼容性问题;
- 创建工作目录
/usr/local/docker/runner - 创建构建目录
/usr/local/docker/runner/environment - 下载 jdk-8u202-linux-x64.tar.gz 并复制到
/usr/local/docker/runner/environment - 下载 apache-maven-3.6.1-bin.tar.gz 并复制到
/usr/local/docker/runner/environment - 新建
daemon.json到/usr/local/docker/runner/environment,输入如下内容
// registry-mirrors 加速器,可登录自己的阿里云查看
// insecure-registries 私服地址
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.2.103:5000"]
}Dockerfile
在 /usr/local/docker/runner/environment 目录下创建 Dockerfile,基于 gitlab-runner 构建自己的镜像,使镜像支持 Java 编译环境
FROM gitlab/gitlab-runner:11.1.0
MAINTAINER Zjx <986379932@qq.com>
# 修改软件源(注意不同系统、版本会有差异,以下以 Ubuntu 22.04 为例,详见Linux 修改数据源章节)
RUN echo 'deb https://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb https://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb https://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb https://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse' > /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse' > /etc/apt/sources.list && \
apt-get update -y && \
apt-get clean
# 安装 Docker 客户端 (不同系统略有差别,详见Docker章节在docker容器中安装docker)
COPY daemon.json /etc/docker/daemon.json
RUN curl -O https://download.docker.com/linux/debian/dists/bullseye/pool/stable/amd64/docker-ce-cli_24.0.6-1~debian.11~bullseye_amd64.deb && \
dpkg -i ./docker-ce-cli_24.0.6-1~debian.11~bullseye_amd64.deb && \
systemctl daemon-reload && \
systemctl restart docker
# 安装 Java
RUN mkdir -p /usr/local/java
WORKDIR /usr/local/java
COPY jdk-8u202-linux-x64.tar.gz /usr/local/java
RUN tar -zxvf jdk-8u202-linux-x64.tar.gz && \
rm -fr jdk-8u202-linux-x64.tar.gz
# 安装 Maven
RUN mkdir -p /usr/local/maven
WORKDIR /usr/local/maven
#RUN wget https://raw.githubusercontent.com/topsale/resources/master/maven/apache-maven-3.6.1-bin.tar.gz
COPY apache-maven-3.6.1-bin.tar.gz /usr/local/maven
RUN tar -zxvf apache-maven-3.6.1-bin.tar.gz && \
rm -fr apache-maven-3.6.1-bin.tar.gz
# COPY settings.xml /usr/local/maven/apache-maven-3.6.1/conf/settings.xml
# 配置环境变量
RUN echo 'export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.1' > /etc/profile && \
echo 'export PATH=$MAVEN_HOME/bin:$PATH:$HOME/bin' > /etc/profile && \
echo 'export JAVA_HOME=/usr/local/java/jdk1.8.0_202' > /etc/profile && \
echo 'export JRE_HOME=/usr/local/java/jdk1.8.0_202/jre' > /etc/profile && \
echo 'export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib' > /etc/profile && \
echo 'export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin' > /etc/profile && \
source /etc/profile
WORKDIR /构建 gitlab-runner 镜像
- docker-compose.yml
在 /usr/local/docker/runner 目录下创建 docker-compose.yml
version: "3.8"
services:
my-gitlab-runner:
# 根据environment目录中的 Dockerfile 来启动所构建的镜像
# 根据 Dockerfile 配置,构建的 my-gitlab-runner 镜像会支持 Java 和 docker 相关指令;
build: ./environment
restart: always
container_name: my-gitlab-runner
# 允许容器在主机系统上拥有更高的权限,可能会影响到安全性
privileged: true
volumes:
- /usr/local/docker/runner/config:/etc/gitlab-runner
# 挂载主机docker套接字,实现容器docker客户端和主机通信
- /var/run/docker.sock:/var/run/docker.sock- 运行
docker compose up -d注册 Runner
将一个 Runner 连接到 GitLab 项目中,使其可以执行项目中定义的 CI/CD 作业( 注册成功后,若项目根路径下包含.gitlab-ci.yml,提交项目 GitLab Runner 会自动触发流水线)。
- 查看项目 Runner token
在 GitLab 中进入项目目录,在项目设置中找到CI/CD选项,展开Runner设置即可查看当前项目的 Runner 信息,包含 url 和注册令牌,可用于注册 Runner
- 注册
# my-gitlab-runner为容器名,gitlab-runner register表示执行的脚本命令
# 若有多个GitLab项目,重复注册即可
docker exec -it my-gitlab-runner gitlab-runner register
# 输入 url
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://192.168.75.146:8080/
# 输入 注册令牌
Please enter the gitlab-ci token for this runner:
1Lxq_f1NRfCfeNbE5WRh
# 输入 Runner 的说明
Please enter the gitlab-ci description for this runner:
可以为空
# 设置 Tag,可以用于指定在构建规定的 tag 时触发 ci,可以为空
Please enter the gitlab-ci tags for this runner (comma separated):
deploy
# 这里选择 true ,可以用于代码上传后直接执行
Whether to run untagged builds [true/false]:
true
# 这里选择 false,可以直接回车,默认为 false
Whether to lock Runner to current project [true/false]:
false
# 选择 runner 执行器,这里我们选择的是 shell
Please enter the executor: virtualbox, docker+machine, parallels, shell, ssh, docker-ssh+machine, kubernetes, docker, docker-ssh:
shell项目中实现持续集成
- 项目结构示例
每个项目可以新建一个 DockerFile 文件,为当前项目构建镜像;再通过 docker-compose.yml运行镜像
my-app/
├── docker/
│ ├── docker-compose.yml
│ └── DockerFile
├── src/
│ ├── main/
│ │ ├── java/
│ │ └── resources/
├── target/
│ └── my-app-1.0.0-SNAPSHOT.jar
├── .gitlab-ci.yml
└── pom.xml- DokcerFile
DockerFile 中,文件的相对路径为 DockerFile 所在路径;这里无需关心怎么会有my-app-1.0.0-SNAPSHOT.jar,因为他是通过下文.gitlab-ci.yml中创建的;
FROM openjdk:8-jre
MAINTAINER Zjx <986379932@qq.com>
# 安装dockerize工具;作用是等待容器内的某些依赖项就绪后,再启动应用程序。这个工具通常用于等待一些外部依赖(比如其他服务、数据库等)可用后再启动应用程序,以确保容器内的应用程序不会启动失败或在没有准备好的情况下运行。
ENV DOCKERIZE_VERSION v0.7.0
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
RUN mkdir /usr/local/myapp
COPY my-app-1.0.0-SNAPSHOT.jar /usr/local/myapp/app.jar
# 等待配置中心就绪后再启动本项目
ENTRYPOINT ["dockerize", "-timeout", "5m", "-wait", "http://192.168.75.128:8888/my-app/prod/master", "java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/usr/local/myapp/app.jar", "--spring.profiles.active=prod"]
EXPOSE 8084- docker-compose.yml
version: "3.8"
services:
my-app:
restart: always
image: 192.168.2.103:5000/my-app:v1.0.0
container_name: my-app
ports:
- 8084:8084- .gitlab-ci.yml
.gitlab-ci.yml文件配置如下;因为我们为 GitLab Runner 配置了 Java 编译环境和 docker,所以流水线中可以直接运行nvm、docker等指令;推送代码后, GitLab Runner 会将最新代码保存到服务器/home/gitlab-runner/builds/下的某个特定目录中,因此无需关心拉取代码;相对的,流水线的开始目录为项目根目录
# 定义阶段
stages:
- my_build
- push
- run
- clean
# 构建镜像
my_build:
stage: my_build
script:
- mvn clean package
# 将jar包拷贝诶到项目的docker路径下
- cp target/my-app-1.0.0-SNAPSHOT.jar docker
- cd docker
# 使用项目中的DockerFile构建镜像
- docker build -t 192.168.2.103:5000/my-app:v1.0.0 .
only:
- master
- dev
# 推送到镜像私服
push:
stage: push
script:
# push后面跟仓库地址+镜像名+tag
- docker push 192.168.2.103:5000/my-app:v1.0.0
only:
- master
- dev
# 运行镜像
run:
stage: run
script:
- cd docker
- docker-compose down
# 使用项目中的docker-compose.yml运行镜像
- docker-compose up -d
only:
- master
- dev
clean:
stage: clean
script:
- docker rmi 虚悬镜像
only:
- master
- dev在容器中成功构建镜像后,为啥在宿主机中会有这个镜像?
挂载主机 Docker 守护程序的套接字文件
docker.sock,这样容器内的 Docker 客户端就能够通过这个套接字与宿主机上的 Docker 守护程序进行通信,如容器内使用docker ps可显示主机镜像,容器内使用docker build构建镜像主机中也直接可见。 详见在 doker 容器中安装 docker
Jenkins + GitLab + Maven
以下是简要的概述,具体操作可能会根据项目的需求和配置略有不同
- 设置 GitLab 仓库: 确保你的项目托管在 GitLab 上,并拥有合适的访问权限。
- 配置 Webhook: 在 GitLab 项目设置中,配置 Webhook 以通知 Jenkins 有关代码的变更。
- 安装和配置 Jenkins: 在 Jenkins 的插件管理中,安装与 GitLab 和 Maven 相关的插件;在 Jenkins 全局配置中,设置 Git 和 Maven 的安装路径,确保 Jenkins 能够找到这些工具。
- 创建 Jenkins Job: 创建一个新的 Job,选择“构建一个自由风格的项目”或“流水线”作为项目类型。配置 Jenkins 根据代码的变更触发构建,可以选择 Webhook 触发或定时触发等方式。 添加构建步骤,选择 Maven 构建,并指定 Maven 的 goals,比如 clean install。 在构建完成后,可以配置后续的操作,比如部署到服务器、发送通知等。
- 测试和部署
- 观察和改进

