本文详细介绍如何在Linux系统使用Docker安装Gitlab、Gitlab-Runner,并通过一个SpringBoot项目来演示CICD
本文需要掌握一点Linux和Docker的基础知识和命令,不熟悉的建议先去了解这两块的内容哦
一、安装Gitlab
1、拉取镜像并启动
由于服务器的80
端口可能被占用,所以这里我们改成了其他端口来启动
docker run -d -p 2443:443 -p 5678:80 -p 2222:22 --name gitlab --restart always -v/srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /src/gitlab/data:/var/opt/gitlab docker.io/gitlab/gitlab-ce
2、修改配置文件
提示:等待docker运行gitlab一小段时间后在操作,否则可能出现文件找不到
修改gitlab.yml文件
vim /src/gitlab/data/gitlab-rails/etc/gitlab.yml
找到如下配置,修改host为你服务的IP或者域名(不能加http://
),修改完毕后保存退出
gitlab: # 这里要将host设置为你gitlab所在的服务器IP或者域名 host: 172.20.9.3 port: 80 https: false
修改gitlab.rb文件
vim /srv/gitlab/config/gitlab.rb
找到external_url
,默认是被注释的,要打开,并填写暴露出去的http://ip:port
,IP
一定要和gitlab.yml
文件配置的相同,port
为你启动时指定的,我们这里使用5678
作为端口;最后加上ssh协议下使用的IP和端口(这里的端口是你启动时指定的,我们这里是2222
),最后保存并退出
external_url 'http://172.20.9.3:5678'gitlab_rails['gitlab_ssh_host'] = '172.20.9.3'gitlab_rails['gitlab_shell_ssh_port'] = '2222'
停止并移除之前启动的gitlab
# 停止并移除之前启动的GitLab容器docker rm -f gitlab
重新启动gitlab
这里要将容器端口改为5678
docker run -d -p 2443:443 -p 5678:5678 -p 2222:22 --name gitlab --restart always -v/srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /src/gitlab/data:/var/opt/gitlab docker.io/gitlab/gitlab-ce
等待一段时间,就可以访问了,首次需要更改root
账户的密码
二、安装Gitlab-Runner
可以在项目中或者项目组中以及全局配置中找到Runner
配置的地方,全局配置仅限GitLab的管理员账号才有权限
项目中
项目中配置的Runner只对当前项目有效
这时候我们展开,就能看到这个设置Runner的区域项目组中
只对这个项目组内的所有项目生效
这个和在项目中一样,都需要展开,往下拉就能看到手动设置Runner的区域全局配置
所有项目都可以一起使用
全局配置在右边就能直接看到手动设置Runner的区域1、拉取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
2、进入Runner容器内
docker exec -it gitlab-runner bash
3、运行以下命令
gitlab-runner register
输入Gitlab实例的地址
地址是你手动设置Runner区域里面的URL
> Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com ) http://xxx
输入token
token是你手动设置Runner区域里面的令牌
> Please enter the gitlab-ci token for this runner xxx
输入Runner的描述
> Please enter the gitlab-ci description for this runner [hostname] my-runner
输入与Runner关联的标签
标签是为了让后期在CI脚本中指定选择某个或者多个Runner,这里我们设置他的标签为
test
,你们可以设置其他的> Please enter the gitlab-ci tags for this runner (comma separated):test
输入Runner的执行器
由于我们都是基于Docker,所以这里选择执行器为Docker
> Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell: docker
设置执行器的版本
> Please enter the Docker image (eg. ruby:2.1): alpine:latest
退出容器
exit
通过以上命令后,就创建成功runner啦,这时候我们去GitLab中我们创建Runner的区域刷新就能看到了
4、修改Runner配置文件
vim /srv/gitlab-runner/config/config.toml
找到
volumes
配置,修改结果为如下,分别是挂载了宿主机docker的sock文件和Maven的缓存,减少拉取Jar包的时间消耗,其中"/data/.m2/:/.m2/"
这块为Maven的Jar包存放地址,左边为宿主机目录,右边为容器内的Jar包存储路径,这个需要根据自己使用的Maven镜像而定提示:如何构建Maven镜像请翻到文章末尾
volumes = ["/cache","/var/run/docker.sock:/var/run/docker.sock","/data/.m2/:/.m2/"]
在
volumes
配置下方增加一行配置,防止Runner重复拉取镜像pull_policy = "if-not-present"
最后重启Runner
docker restart gitlab-runner
三、创建SpringBoot项目测试CICD
这里就不演示如何创建项目了,不会SpringBoot的自行去学习,这里只展示
.gitlab-ci.yml
文件1、在项目根目录创建个
Dockerfile
FROM openjdk:8-jdkCOPY target/*.jar ci-demo.jarEXPOSE 7777ENTRYPOINT ["java","-jar","ci-demo.jar"]
2、项目根目录创建
.gitlab-ci.yml
文件下面脚本中出现了
172.20.9.3:5001/root/maven:latest
镜像,这块是我们手动构建的Maven镜像,如何构建请前往文章第四部分拓展知识查看# 全局脚本,会运行在各个阶段的script前,如果某个阶段里面存在before_script,那么以那个阶段里的为主before_script:# 这里定义了打包成功后的Docker镜像名称,每一次提交代码后构建成功的镜像名称都是唯一的- export IMAGE_FULL_NAME=${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA}# 定义CI执行的阶段,这里可以自己根据情况定义多少个阶段stages:- compile- build- run# 定义全局变量variables:PROJECT: "ci-demo"# 这里定义了Maven的jar包存放地址,与我们构建maven私服的时候设置的存放地址一致MAVEN_REPO: "/.m2"编译:# 当前阶段的执行镜像,这是我们自己构建的镜像image: 172.20.9.3:5001/root/maven:latest# 属于上面定义的哪一个阶段stage: compile# 是否允许失败,允许的话如果当前阶段运行失败还会继续执行下一个阶段allow_failure: false# 只在哪个分支生效only: - master# 这里就是你要选择哪个runner来执行了,填写我们创建runner时候指定的标签tags: - test# 运行脚本script: - mvn -Dmaven.repo.local=$MAVEN_REPO clean package -Dmaven.test.skip=true# 因为是Maven编译,所以会有Jar包产物,这里定义产物的过期时间artifacts: name: $PROJECT expire_in: 7 days paths: - target/*.jar构建镜像:image: docker:stablestage: buildscript: # 这里的变量会自动获取你当前推送代码的gitlab用户和密码以及仓库地址 - docker login --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY # 这里的变量就是我们全局配置定义的了 - docker build -t $IMAGE_FULL_NAME . - docker push $IMAGE_FULL_NAME - rm -rf target - docker rmi $IMAGE_FULL_NAMEonly: - mastertags: - test运行:image: docker:stablestage: runscript: - CONTAINER_NAME=$(docker ps -aq --filter name=$PROJECT) - echo $CONTAINER_NAME - if [[ -n "$CONTAINER_NAME" ]]; then docker rm -f $CONTAINER_NAME; fi - docker run -d --name $PROJECT -p 7777:7777 $IMAGE_FULL_NAMEonly: - mastertags: - test
3、将项目提交到Gitlab仓库即可
编写好脚本后,提交代码到master分支,因为我们在CI脚本里只指定了master分支生效,
第一次CI执行的时候会比较慢
,因为需要拉取基础镜像和jar包
CI脚本执行完毕后,我们可以去runner所在服务器进行查看容器是否启动成功,由于我们项目设置了一个接口,所以我们直接尝试访问接口地址看看是不是正常返回,如果返回了就是执行成功了,没有正常返回的话,就需要自己通过docker logs -f <容器名>
查看日志了
建议:最好使用内网环境的基础镜像
,否则可能导致CI执行时间过长,比如CI脚本中运行阶段的基础镜像docker:stable
还有Dockerfile文件里的基础镜像JDK
。拉取时间的长短受服务器性能和网络影响。
该项目Demo可以前往GitHub查看
四、拓展知识
1、开启GitLab中Docker镜像仓库
首先我们先找台服务器启动一个Docker registry镜像仓库
docker run -d -v /data/registry:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true -p 5001:5000 --restart=always --name registry registry:2
过了一会后通过浏览器访问http://<服务器IP>:5051/v2/_catalog
,会返回一个空的JSON,这是因为我们还没推送镜像上去。
在Gitlab中开启Docker镜像仓库,可以直接通过Gitlab中的用户项目权限进行镜像权限控制,非常方便快捷。registry_external_url
和gitlab_rails['registry_api_url']
替换为你的镜像仓库地址,registry_path
、registry_host
修改为对应的地址和IP
registry_external_url 'http://172.20.9.3:5001'gitlab_rails['registry_enabled'] = true gitlab_rails['registry_host'] = "172.20.9.3"gitlab_rails['registry_port'] = "5001"gitlab_rails['registry_path'] = "/src/gitlab/data/gitlab-rails/shared/registry"gitlab_rails['registry_api_url'] = "http://172.20.9.3:5001"
配置完刷新配置
docker exec -it gitlab gitlab-ctl reconfigure
这时候我们随便找到一个项目,点进去查看一下容器库
右边的就是如何通过docker提交镜像到该项目了
提示:由于我们这边没有配置HTTPS,所以需要给Docker增加如下配置,需要登陆镜像仓库的机子都需要给配上,我们这里是通过runner去打包和启动项目,那么就需要在runner所在服务器的docker进行配置了
# 打开文件vim /etc/docker/daemon.json# 将下面的配置追加到已有的配置中"insecure-registries":["xxx:5000"]
最终的效果如下第一行
配置好后重启Docker
systemctl restart docker
2、构建自己的Maven镜像
以下两个文件要放到同一个目录里面
Dockerfile
FROM maven:3.6.0-jdk-8-alpineCOPY settings.xml /usr/share/maven/ref/
Maven配置文件(settings.xml)
<?xml version="1.0" encoding="UTF-8"?><settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <!--改为你的Jar包存放目录--> <localRepository>/.m2</localRepository> <mirrors> <mirror> <id>mynexus</id> <name>company nexus</name> <url>更改为你的Maven仓库地址,可以是阿里的私服,也可以是公司内部的私服</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <profiles> <profile> <id>jdk18</id> <activation> <jdk>1.8</jdk> <activeByDefault>true</activeByDefault> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> </profiles></settings>
两个文件创建好之后,通过控制台进入到该目录,尝试构建镜像并上传,本文直接采用GitLab开启Docker镜像仓库,因此这里,我们先去Gitlab创建一个叫Maven的项目,然后查看他的容器库
依次执行框框里的命令,这里需要配置docker镜像仓库地址到你要执行这个命令的机子哦,如果你是在本地,那么就是给本地电脑的docker加上配置了
docker login 172.20.9.3:5001 docker build -t 172.20.9.3:5001/root/maven . docker push 172.20.9.3:5001/root/maven
执行完毕后我们回到Gitlab查看一下,这时候就有我们推送的镜像了