docker + gitlab + gitlab-runner + CI/CD配置记录

832 阅读2分钟

结合了很多篇网上的配置文章,最后搞定了整套流程的部署,本人配置环境为centos7,4C8G。不建议4G以下的云服务器安装。

1. docker、docker-compose安装

参照官网:

docs.docker.com/engine/inst…

安装完成后输入 docker -v 显示具体版本号即可,docker-compose同理

image.png

具体安装不再赘述。

2. gitlab安装

  1. 拉取gitlab镜像 docker pull gitlab/gitlab-ce:latest
  2. 自己选择一个目录创建挂载文件夹 mkdir -p /usr/local/src/gitlab/{config,logs,data}
  3. 启动gitlab,这里采用的是docker-compose的启动方式
version: '3'
services:
    web:
        image: 'gitlab/gitlab-ce:latest'
        container_name: 'gitlab'
        restart: always
        hostname: 'host' #此处为ip或域名
        environment:
          GITLAB_OMNIBUS_CONFIG: |     # environment的配置也可以启动后在挂载的config目录下gitlab.rb中找到,修改后记得重启
            external_url 'http://hostname:9080'  #ip或域名 port默认是80,改为其他任意端口号 
            gitlab_rails['gitlab_shell_ssh_port'] = 9022  #ssh协议端口
            gitlab_rails['time_zone'] = 'Asia/Shanghai'
        ports:
                - '9080:9080' #访问端口号
                - '9443:443' #HTTPS
                - '9022:22' #HTTP
        volumes:
            - '$GITLAB_HOME/config:/etc/gitlab' #这边的GITLAB_HOME如果没有export全局变量的话也可以用自己的本地路径替换 例如 /usr/local/gitlab
            - '$GITLAB_HOME/logs:/var/log/gitlab'
            - '$GITLAB_HOME/data:/var/opt/gitlab' 
                    

注意docker-compose.yml文件的格式问题,可以找在线yml网站查看一下格式是否正确。

在yml目录下执行 docker-compose up -d 第一次启动耗时比较久,5,6分钟。启动后状态如下:

image.png

如果上面compose中的environment没有写的话,记得要去data下的rb文件中找到对应注释掉的代码并填写以上三个对应的东西。

启动后就可以访问本地化的gitlab了。 账号是root,密码问题可以看这个文章(可以自己找到挂载文件对应文件夹下复制密码,也可以直接通过sql改密码) cloud.tencent.com/developer/a…

3.gitlab-runner 安装

  1. 拉取镜像文件 docker pull gitlab/gitlab-runner:latest
  2. 同样用docker-compose.yml进行构建
version: "3"
services:
  gitrunner:
    image: 'gitlab/gitlab-runner:latest'
    container_name: "gitlab-runner"
    restart: always
    volumes:
      - './config:/etc/gitlab-runner'
      - './cache:/tmp/cache'
      - './ssl:/etc/gitlab-runner/certs/'
      - '/usr/bin/docker:/usr/bin/docker'
      - '/var/run/docker.sock:/var/run/docker.sock'

根据自己需要修改挂载文件配置后 docker-compose up -d

  1. 启动后进入容器内 docker exec -it 容器名 bash
  2. 运行注册命令 gitlab-runner register
# gitlab地址
Enter the GitLab instance URL (for example, https://gitlab.com/):
http://ip/
 
# token
Enter the registration token:
XXXXX-XXXXX-XXXXX
 
Enter a description for the runner:
demo-runner
 
# gitlab-runner标签名称tag
Enter tags for the runner (comma-separated):
build,deploy
 
# 选择执行gitlab-runner的执行程序。因为我要用docker实现自动部署,所以输入docker
Enter an executor: custom, docker-ssh, parallels, kubernetes, docker, shell, ssh, virtualbox, docker+machine, docker-ssh+machine:
docker
 
# 如果选择docker作为执行程序,那要定义一个默认镜像的名称
Enter the default Docker image (for example, ruby:2.6):
alpine:latest

生成后就可以在管理界面下图所示位置找到该runner了

image.png

  1. 修改Runner配置文件 到之前挂载的gitlab-runner下的config文件夹下的config.toml

image.png

之前有输入问题也可以在这边重新再修改

我们需要修改这边的volume配置,修改结果如runners1所示:分别是挂载了宿主机的sock文件和Maven的缓存。 同时增加一行配置,方式Runner重复拉取镜像

pull_policy="if-not-present"

最后重启Runner

4. 私有化docker镜像仓库

我们打包项目生成镜像文件一般也需要自己存起来,这时候就需要打开docker registry功能了,这里顺带提一下如何打开registry。

安装并启动,没有的镜像docker会自动拉取

docker run -d -v /usr/local/src/docker/gitlab/data/registry:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true -p 5000:5000 --restart=always registry

安装后,可以尝试http://<服务器IP>:5050/v2/_catalog 如果返回空的json,说明启动成功了,此时镜像库是空的。

我们再回到之前gitlab的gitlab.rb中,修改如下几个参数

registry_external_url 'http://ip:5000'
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "ip"
gitlab_rails['registry_port'] = "5000"
gitlab_rails['registry_path'] = "/src/gitlab/data/gitlab-rails/shared/registry" #这个参数要注意一下,根据自己之前gitlab的挂载位置进行修改
gitlab_rails['registry_api_url'] = "http://ip:5000"

配置完后刷新gitlab

我们随便找个项目,点进去查看一下容器库

image.png

上图就是给项目配置镜像库的方法了。

现在我们再来试一下配置一个自己的Maven仓库,方便其他项目打包的时候使用

我们首先给docker-runner服务器上配置一下打开/etc/docker/damon.json 然后追加下列语句后重启docker

{
    "insecure-registries" : [ "hostname.cloudapp.net:5000" ]
}

Docker 默认不允许非 HTTPS 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制

找一个文件下分别创建Dockerfile和settings.xml.(这里的Dockerfile是不需要后缀的,否则后面会构建失败)

  • Dockerfile
FROM maven:3.6.0-jdk-8-alpine
COPY 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>
            #这边配置阿里云mirror或者公司私有mirror即可
        </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>

两个文件都创建好后,创建一个项目去构建镜像。(这里因为我随便用了一个仓库为了展示没有配置镜像库的样子,大家可以改为maven)

image.png

执行后再回到gitlab看,就有我们推送的镜像了。

image.png

访问之前的/v2/_catalog也能看到对应的镜像

image.png

5.项目配置CI/CD

回到正题,我们随便创建一个springboot项目,在根目录分别创建Dockerfile(用来启动项目)和.gitlab-ci.yml(用来编排整个CI过程)

  • Dockerfile
FROM openjdk:8-jdk
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
  • .gitlab-ci.yml
# 全局脚本,会运行在各个阶段的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: 124.221.55.213:5000/root/maven:latest
  # 属于上面定义的哪一个阶段
  stage: compile
  # 是否允许失败,允许的话如果当前阶段运行失败还会继续执行下一个阶段
  allow_failure: false
  # 只在哪个分支生效
  only:
    - main
  # 这里就是你要选择哪个runner来执行了,填写我们创建runner时候指定的标签
  tags:
    - demo-tag
  # 运行脚本
  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:stable
  stage: build
  script:
    # 这里的变量会自动获取你当前推送代码的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_NAME
  only:
    - main
  tags:
    - demo-tag
运行:
  image: docker:stable
  stage: run
  script:
    - 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 8080:8080 $IMAGE_FULL_NAME
  only:
    - main
  tags:
    - demo-tag

代码提交到指定CI运行的分支,这时候流水线就会自动启动了。

image.png

参考的文章地址: juejin.cn/post/684490…