创建 GitLab Runner 使用CICD自动化部署容器

包括创建 GitLab Runner 的 Docker 命令和注册 Runner 的步骤,以及 .gitlab-ci.yml 文件的内容。
直接在宿主机上使用 Docker

  • 定义: 在宿主机上安装并使用 Docker 服务意味着 Docker daemon 直接在宿主机操作系统上运行。
  • 用途: 适用于任何需要构建、运行或管理 Docker 容器的场景。这是最常见的 Docker 使用方式。
  • 特权模式: 不需要特别的权限设置,因为 Docker daemon 已经作为系统服务运行。
  • 网络集成: 宿主机上的 Docker daemon 能够直接利用宿主机的网络栈,因此网络配置更加直接且高效。
  • 资源管理: 由于 Docker daemon 是直接运行在宿主机上的,因此没有额外的资源开销用于运行 Docker daemon 自身。

创建 GitLab Runner

创建config.toml

bash 复制代码
[root@k8s local]# docker exec -it gitlab-runner cat /etc/gitlab-runner/config.toml
concurrent = 1
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "docker"
  url = "http://192.168.0.3"
  id = 1
  token = "glrt-jjiRpadeKbwuLRasNVPogW86MQpwOjEKdDozCnU6Mg8.01.170obpunv"
  executor = "docker"

  [runners.cache]
    MaxUploadedArchiveSize = 0

  [runners.docker]
    tls_verify = false
    image = "maven:3.8.6-jdk-11"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
    shm_size = 0
    network_mtu = 0
    allowed_pull_policies = ["always", "if-not-present"]

首先,使用以下命令创建 GitLab Runner:

bash 复制代码
docker run -d --name gitlab-runner \
  --restart always \
  --privileged \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/local/daemon.json:/etc/docker/daemon.json \
  -v /usr/local/config.toml:/etc/gitlab-runner/config.toml \
  gitlab/gitlab-runner:latest

此命令做了以下几件事:

-d:后台运行容器。

--name gitlab-runner:指定容器名称为 gitlab-runner。

--restart always:设置重启策略为总是重启。

--privileged:赋予容器扩展权限,以便它可以管理宿主机的 Docker 守护进程。

-v /srv/gitlab-runner/config:/etc/gitlab-runner:挂载配置目录。

-v /var/run/docker.sock:/var/run/docker.sock:允许容器与 Docker 守护进程通信。

-v /usr/local/daemon.json:/etc/docker/daemon.json 和 -v /usr/local/config.toml:/etc/gitlab-runner/config.toml:挂载自定义配置文件

注册 GitLab Runner

bash 复制代码
docker exec -it gitlab-runner gitlab-runner register

然后按照提示输入以下信息:

GitLab 实例的 URL (例如 http://192.168.0.3)

GitLab 提供的注册令牌(可以从 GitLab 管理员界面获取)

描述 Runner

标签(如 docker)

Executor 类型(在这个例子中选择 docker)

.gitlab-ci.yml 示例

yaml 复制代码
image:
  name: maven:3.8.6-jdk-11
  pull_policy: if-not-present

variables:
  DOCKER_TLS_CERTDIR: ""
  IMAGE_NAME: "jvue:latest"
  DOCKER_CLIENT_TIMEOUT: 600
  COMPOSE_HTTP_TIMEOUT: 600

stages:
  - build
  - deploy

before_script:
  - echo "deb http://mirrors.aliyun.com/debian/ bullseye main contrib non-free" > /etc/apt/sources.list
  - echo "deb http://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free" >> /etc/apt/sources.list
  - echo "deb http://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free" >> /etc/apt/sources.list
  - until apt-get update; do sleep 5; done
  - until apt-get install -y --fix-missing docker.io; do sleep 5; done

build:
  stage: build
  tags:
    - docker
  script:
    - mvn clean package -DskipTests=true
    - docker build -t $IMAGE_NAME .
  timeout: 3h

deploy:
  stage: deploy
  tags:
    - docker
  script:
    - |
      docker stop my-springboot-app || true
      docker rm my-springboot-app || true
      docker run -d \
        --name my-springboot-app \
        --network bridge \
        -p 8080:8080 \
        -e SPRING_DATASOURCE_URL='jdbc:mysql://192.168.0.3:13306/jvue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8' \
        -e SPRING_DATASOURCE_USERNAME=root \
        -e SPRING_DATASOURCE_PASSWORD=12345678 \
        -e SPRING_REDIS_HOST=192.168.0.3 \
        -e SPRING_REDIS_PORT=16379 \
        -e SPRING_REDIS_DATABASE=0 \
        -e SPRING_REDIS_PASSWORD=12345678 \
        $IMAGE_NAME
  timeout: 3h

确保所有路径、变量、URL 和凭据都已正确设置,并且符合你项目的实际需求。这样,你就完成了从创建 Runner 到配置 .gitlab-ci.yml 文件的一整套流程。

Dockerfile 用于构建 Spring Boot 应用的镜像

FROM openjdk:11-jdk-slim

WORKDIR /app

COPY jvue-admin/target/*.jar app.jar

ENTRYPOINT ["java", "-jar", "app.jar"]

执行CICD流水线

确保所有路径、变量、URL 和凭据都已正确设置,并且符合你项目的实际需求。这样,你就完成了从创建 Runner 到配置 .gitlab-ci.yml 文件的一整套流程。

使用docker:20.10-dind

以在一个 Docker 容器内启动另一个 Docker 容器

docker:20.10-dind (Docker in Docker)

  • 定义: docker:20.10-dind 是一个 Docker 镜像,它包含了完整的 Docker 服务(即 Docker
    daemon)。这意味着你可以在一个 Docker 容器内启动另一个 Docker 容器。
  • 用途: 主要用于 CI/CD 管道中,在容器化环境中提供 Docker 构建能力。例如,在 GitLab CI 中,你可能需要在一个
    Docker 容器中构建 Docker 镜像。
  • 特权模式: 运行 docker:dind 容器时通常需要使用 --privileged 标志来给予额外权限,因为 Docker
    daemon 需要管理宿主机上的资源。
  • 网络隔离: docker:dind 容器内的 Docker daemon
    可能会有自己的网络命名空间,这意味着容器内部的网络配置可能会与宿主机不同。
  • 资源消耗: 使用 docker:dind 意味着你需要为 Docker daemon 分配额外的资源,这会增加一些开销。

关键差异点

  • 复杂性: 使用 docker:dind 增加了系统的复杂性,因为你现在有两个 Docker daemon
    实例------一个是宿主机上的,另一个是容器内的。而在宿主机上直接使用 Docker 则不需要处理这种复杂性。
  • 性能: 直接在宿主机上运行 Docker 通常会有更好的性能,因为减少了中间层(如容器化的 Docker daemon)带来的性能损耗。
  • 隔离性: docker:dind
    提供了一定程度的隔离性,这对于某些安全敏感的应用场景是有益的。然而,这也可能导致网络和其他方面的复杂性增加。
  • 部署灵活性: 使用 docker:dind 可以让你更容易地在不同的环境之间迁移你的 CI/CD 流程,因为它不依赖于宿主机的具体
    Docker 版本或配置。

修改关键点

  1. 移除宿主机 Docker 套接字的挂载:当你使用 docker:dind 时,你不应该再挂载宿主机的
    /var/run/docker.sock。相反,你应该让容器内部运行一个独立的 Docker 守护进程。
  2. 配置服务启动参数:你已经尝试在 [runners.service_args] 中配置了 Docker
    守护进程的启动参数。这是正确的方向,但需要确保这些参数适用于 docker:dind 的启动方式。
  3. 调整 GitLab Runner 配置文件:确保你的 GitLab Runner 配置正确地反映了你希望使用 docker:dind
    的意图,并且没有遗留的与宿主机 Docker 相关的配置。
bash 复制代码
[root@k8s local]# cat config.toml
concurrent = 1
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "docker"
  url = "http://192.168.0.3"
  id = 1
  token = "glrt-jjiRpadeKbwuLRasNVPogW86MQpwOjEKdDozCnU6Mg8.01.170obpunv"
  executor = "docker"

  [runners.cache]
    MaxUploadedArchiveSize = 0

  [runners.docker]
    tls_verify = false
    image = "docker:20.10-dind"  # 使用 docker:dind 作为基础镜像
    privileged = true           # 必须为 true 来允许 dind 正常工作
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/certs/client"]  # 注意这里不再挂载 /var/run/docker.sock
    shm_size = 0
    network_mtu = 0
    allowed_pull_policies = ["always", "if-not-present"]

  [runners.services]
    - name = "docker:20.10-dind"
      command = ["--registry-mirror=https://docker.mirrors.ustc.edu.cn", "--registry-mirror=https://mirror.iscas.ac.cn", "--host=unix:///var/run/docker.sock", "--host=tcp://0.0.0.0:2375", "--storage-driver=vfs", "--dns=8.8.8.8", "--dns=8.8.4.4", "--max-concurrent-downloads=10", "--max-download-attempts=5"]

修改.gitlab-ci.yml

yaml 复制代码
image:
  name: maven:3.8.6-jdk-11  # 使用较新的 JDK 和 Maven 版本,通常基于较新的操作系统
  pull_policy: if-not-present

services:
  - name: docker:20.10-dind
    alias: docker
    variables:
      DOCKER_TLS_CERTDIR: ""

variables:
  DOCKER_HOST: tcp://docker:2375  # 指定 Docker 守护进程地址
  DOCKER_CLIENT_TIMEOUT: 600
  COMPOSE_HTTP_TIMEOUT: 600
  IMAGE_NAME: "jvue:latest"

stages:
  - build
  - deploy

before_script:
  - echo "deb http://mirrors.aliyun.com/debian/ bullseye main contrib non-free" > /etc/apt/sources.list
  - echo "deb http://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free" >> /etc/apt/sources.list
  - echo "deb http://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free" >> /etc/apt/sources.list
  - until apt-get update; do sleep 5; done
  # 移除了 docker.io 的安装步骤,因为我们将使用 DinD

build:
  stage: build
  tags:
    - docker
  script:
    - mvn clean package -DskipTests=true
    - docker build -t $IMAGE_NAME .
    - docker push $IMAGE_NAME  # 如果你需要推送镜像到某个仓库,请取消注释此行
  timeout: 3h

deploy:
  stage: deploy
  tags:
    - docker
  script:
    - |
      docker stop my-springboot-app || true
      docker rm my-springboot-app || true
      docker run -d \
        --name my-springboot-app \
        --network bridge \
        -p 8080:8080 \
        -e SPRING_DATASOURCE_URL='jdbc:mysql://192.168.0.3:13306/jvue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8' \
        -e SPRING_DATASOURCE_USERNAME=root \
        -e SPRING_DATASOURCE_PASSWORD=12345678 \
        -e SPRING_REDIS_HOST=192.168.0.3 \
        -e SPRING_REDIS_PORT=16379 \
        -e SPRING_REDIS_DATABASE=0 \
        -e SPRING_REDIS_PASSWORD=12345678 \
        $IMAGE_NAME
  timeout: 3h
相关推荐
IT成长日记2 小时前
【自动化运维神器Ansible】Ansible常用模块之File模块详解
运维·自动化·ansible·file·常用模块
Reggie_L5 小时前
Eureka-服务注册,服务发现
云原生·eureka·服务发现
不念霉运6 小时前
2025 Gitee vs. GitLab:全面对比与选择指南
gitee·gitlab
feifeigo12319 小时前
自动化运维:从脚本到DevOps的演进
运维·自动化·devops
Freshman小白19 小时前
Fluent自动化仿真(TUI命令脚本教程)
自动化·脚本·仿真
深圳安锐科技有限公司19 小时前
基坑渗压数据不准?选对渗压计能实现自动化精准监测吗?
安全·自动化·自动化监测·大坝监测·渗压计
晴天彩虹雨19 小时前
统一调度与编排:构建自动化数据驱动平台
大数据·运维·数据仓库·自动化·big data·etl
贺贺丿20 小时前
Docker4-容器化企业级应用
linux·nginx·docker·云原生·eureka·tomcat·ssh
IT成长日记1 天前
【自动化运维神器Ansible】Ansible常用模块之Copy模块详解
运维·自动化·ansible·copy·常用模块、