笔者个人理解:gitlab-runner 安装后就是一个监听状态的 runner,而通过 gitlab-runner register 注册的“实例”其实只是预定义的配置节,当消息抵达后,gitlab-runner 根据消息内容选择相应的配置节启动执行线程。为了方便阐述和理解,本文也将每个配置节/执行线程称为 runner 实例

runner executor

runner 实例的执行环境,一般用的较多的是 shelldocker,这两者的区别无需赘述。

让人困惑的是其它一些 executor:比如 Docker-SSHDocker-SSH+machine(从 GitLab Runner 10.0 开始, Docker-SSH 和 Docker-SSH+machine executors 被废弃了,并且将在后续某个版本中移除);还有 Docker machine,这个概念原本是 Docker 提出的,但是后面被 Docker 弃用了,GitLab 为了向前兼容保留了下来,也可以不用细究。

对于 docker executor 来说,runner 执行 job 的流程如下(摘自官网):

  1. The runner starts a Docker container using the defined entrypoint. The default from Dockerfile that may be overridden in the .gitlab-ci.yml file.
  2. The runner attaches itself to a running container.
  3. The runner prepares a script (the combination of before_script, script, and after_script).
  4. The runner sends the script to the container’s shell stdin and receives the output.

显然,第 1 步要启动容器,如果 runner 本身是以 docker 容器方式安装运行的,那么就涉及到 Docker-in-Docker 的概念了。

Docker-in-Docker

有些时候,我们需要在容器内部执行 docker 指令,一般有两种方式:

  1. 挂载宿主机 docker 环境。启动容器时挂载 /var/run/docker.sock,这样在容器内执行 docker 指令其实就等同于在容器外(宿主机中)执行 docker 指令。比如 docker build 构建一个镜像,该镜像并不存在于容器内部,而是在宿主机中。所以该方法并不是严格意义上的 docker in docker
  2. 容器内部有自己的一套 docker 环境。使用 docker:dind 镜像,可以直接使用它作为主容器,或是作为其它容器的服务容器(其它容器与之通信)。它在 docker 镜像(该镜像只包含客户端指令集)基础上安装了 Docker Daemon,因此可作为独立的 docker 环境使用,是真正意义上的 docker in docker。然而,除非你真正需要在容器内嵌套容器,或者某些场景下无法使用第 1 种方式,否则还是建议避免使用该方式。

这两种方式需要执行指令的容器处于 privileged mode,有一定的安全风险(privileged=true 将使得容器内 root 拥有宿主 root 的权限,否则只是宿主机上的普通用户),因此市面上又出现了一种 Using Nestybox sysbox Docker runtime 的方法,感兴趣的朋友请查阅参考资料,此处按过不表。

in gitlab-runner

如前所述,以 docker 方式安装 runner,且 executor 采用 docker,那么就要 Docker-in-Docker。因为 runner 只是启动新容器,不要求启动的容器在 runner 容器内部,我们可以采用第 1 种方式,如下:

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 \ # 挂载 socket
gitlab/gitlab-runner:latest

另外,如果 docker executor 在 CI/CD job 中涉及到 docker 指令,那么也要 Docker-in-Docker。关键步骤如下:

  1. 注册 runner 实例,并配置其启动的容器为 privileged mode(注意配置的是每次 job 执行时启动的容器,而 runner 所在的容器,且 runner 并不一定是 docker 形式)。
sudo gitlab-runner register -n \
--executor docker \
--docker-image "docker:20.10.16" \
--docker-privileged \ # privileged mode
--other arguments
  1. 接下来,可以选择任一种方式实现 Docker-in-Docker:

    • config.toml 中增加卷映射 volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
    • 或者在 .gitlab-ci.yml 中指定 docker:dind 如:
    services:
    - docker:20.10.16-dind

TLS 配置

如果在第 2 步采用 docker:dind 方式,那么由于涉及到容器间通信,需要选择是否启用 TLS。

若是,则在注册 runner 实例时,增加一个参数 --docker-volumes "/certs/client", 也可手动编辑 config.toml,增加卷映射 volumes = ["/certs/client", "/cache"];然后在 .gitlab-ci.yml 中设置变量 DOCKER_TLS_CERTDIR: "/certs"

若否,则在 .gitlab-ci.yml 中设置变量 DOCKER_TLS_CERTDIR: ""DOCKER_HOST: tcp://docker:2375

TLS 若未正确配置,会报 Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running? 错误。

参考资料

How To Run Docker in Docker Container 3 Easy Methods

gitlab-runner 中的 Docker-in-Docker的更多相关文章

  1. gitlab runner使用docker报错(x509: certificate signed by unknown authority)定位

    如果gitlab runner使用docker,docker是普通配置,配置好后,runner就可以正常执行任务了. 另外一个环节Docker配置了tls加密连接,添加runner后,runner的配 ...

  2. k8s Gitlab CI/CD 之自动编译Docker镜像并推送到指定的Registry

    环境介绍: 说明 节点 ip 系统 Gitlab Server git.ds.com 10.0.1.179 CentOS 7.5.1804 Gitlab Runner   10.0.1.178 Cen ...

  3. .NetCore中的程序通过Docker在CentOS中部署

    基础说明 安装Docker过程就略过了 创建一个Asp.Net Core程序 启用Docker支持,会生成Dockerfile文件,接下来看下这个文件,当然不同的版本生成的具体可能不一致 FROM m ...

  4. CentOS7系列--5.2CentOS7中配置和管理Docker

    CentOS7配置和管理Docker Docker是操作系统级别的虚拟化工具,它能自动化布署在容器中的应用 1. 安装Docker 1.1. 安装Docker相关软件 [root@server1 ~] ...

  5. docker微服务部署之:四、安装docker、docker中安装mysql和jdk1.8、手动构建镜像、部署项目

    docker微服务部署之:三,搭建Zuul微服务项目 1.Centos7安装Docker 详见:Centos7安装Docker 2.Docker中安装jdk1.8 详见:使用Docker构建jdk1. ...

  6. pycharm中创建并设置docker解释器

    在Windows上使用Docker的其中一个目的是使其与PyCharm结合,形成Python代码的解释器,避免重复的Python解释环境搭建的问题,同时保持Windows开发环境和部署环境所用的Pyt ...

  7. 在Ubuntu中安装Docker和docker的使用

    1.在Ubuntu中安装Docker 更新ubuntu的apt源索引 sudo apt-get update 安装包允许apt通过HTTPS使用仓库 sudo apt-get install \ ap ...

  8. Jenkins在Pod中实现Docker in Docker并用kubectl进行部署

    Jenkins在Pod中实现Docker in Docker并用kubectl进行部署 准备工作 安装Jenkins Jenkins的kubernetes-plugin使用方法 说明 Jenkins的 ...

  9. 不同network中的两个docker容器

    1. 创建docker网络 docker network create --subnet 172.18.0.1/16 test docker network ls 2. 创建两个容器指定docker ...

  10. 在ubuntu server中安装和配置docker

    经过一段时间针对不同版本的学习,现在总结当前最新的安装配置过程(应该也是比较简单的) 如果不清楚什么是docker,请参考 https://www.docker.com/ 准备工作 建议在安装之前运行 ...

随机推荐

  1. Python内置函数:enumerate

    enumerate(sequence, [start=0]) enumerate单词本身翻译为列举.枚举. 官方说明: enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组 ...

  2. 换个脑袋,做个小练习------四则运算系统的随机出题的jsp实现

    四则运算出题系统网页界面的实现(别期待,只有俩操作数) index.jsp <%@ page contentType="text/html;charset=UTF-8" la ...

  3. ASP.NET Core使用filter和redis实现接口防重

    背景 日常开发中,经常需要对一些响应不是很快的关键业务接口增加防重功能,即短时间内收到的多个相同的请求,只处理一个,其余不处理,避免产生脏数据.这和幂等性(idempotency)稍微有点区别,幂等性 ...

  4. Linux & 标准C语言学习 <DAY9_2>

    一.进程映像     程序:存储在磁盘上的可执行文件(二进制文件.脚本文件)     进程:正在系统中运行的程序     进程映像:进程的内存分布情况         text(代码段):       ...

  5. 【AI 全栈 SOTA 综述 】这些你都不知道,怎么敢说会 AI?【语音识别原理 + 实战】

    章目录 前言语音识别原理   信号处理,声学特征提取   识别字符,组成文本   声学模型   语言模型   词汇模型语音声学特征提取:MFCC和LogFBank算法的原理实战一 ASR语音识别模型 ...

  6. 从头开始——重新布置渗透测试环境的过程记录(From Windows To Mac)

    因为疫情和工作的原因,2022年整整一年我基本没有深度参与过网络安全和渗透测试相关的工作. 背景:之前因为使用习惯,一直使用的是ThinkPad X1 Extreme,可联想的品控实在拉胯,奈何Thi ...

  7. swagger-ui 导出离线文档md格式

    <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger ...

  8. C# 通过StreamWriter输出的TXT流文件,前缀带EF BB BF

    好久没有动笔写博客了,这个小天地被我闲置的放了好久好久,接下来要慢慢捡起来了. 备注:通过C#的StreamWriter类输出一个TXT流文件,供下位机工程师使用,发现打开的16进制文件中,默认添加了 ...

  9. vue 展开收起的过渡效果

    做的一个项目当中需要做一个组件,传入数组,用v-for生成表单,可以展开和收起,展开收起时需要有过渡的效果 在vue里面提供了<transtion></transtion>和& ...

  10. C#泛型的逆变协变(个人理解)

    前编 一般来说, 泛型的作用就类似一个占位符, 或者说是一个参数, 可以让我们把类型像参数一样进行传递, 尽可能地复用代码 我有个朋友, 在使用的过程中发现一个问题 IFace<object&g ...