笔者个人理解: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. 钉钉获取第三方token时提示签名时间戳参数超时的处理方法

    今天在更新平台功能时,碰到一个问题,从钉钉跳转到平台,始终不能成功.查看日志发现,出现了 签名时间戳参数超时 的错误. 想着没有动过相对应的代码,应该不是代码的问题. 查询官方文档,没有给出明确的答复 ...

  2. Java笔记第八弹

    设置和获取线程名称 //方法 void setName(String name);//将此线程的名称更改为等于参数name String getName();//返回此线程的名称 public sta ...

  3. Android studio手机界面的显示

    终于显示出来啦! 前几天因为SDK的地址错误一直不显示,现在终于显示出来啦! 关于报错原因的话,我也不太清楚是咋解决的,就改了改Android studio软件里面下载SDK的地址,就出来啦!(只要报 ...

  4. Spring--案例:测试业务层接口万次执行效率

    案例来袭 这样,并不能够分辨出哪个的效率是哪个 可以利用pjp进行这样的操作: 结果:

  5. 基于声网 Flutter SDK 实现多人视频通话

    前言 本文是由声网社区的开发者"小猿"撰写的Flutter基础教程系列中的第一篇.本文除了讲述实现多人视频通话的过程,还有一些 Flutter 开发方面的知识点.该系列将基于声网 ...

  6. Activiti 7 启动流程实例

    首先,考虑下面这样一个流程图 主要的流程定义如下: <process id="demo" name="demo" isExecutable="t ...

  7. 主板芯片组驱动和Win系统版本互相关联

    主板芯片组驱动和Win系统版本互相关联,过早的系统安装较新版的芯片组驱动,或者较新版本的操作系统安装旧版的芯片组驱动,都可能导致系统不稳定蓝屏.解决方案就是安装最新的芯片组驱动和最新版的操作系统.

  8. 改善与提高linux系统的音质

    当初装Linux系统的时候,我就发现了,deepin和ubuntu的linux平台音质和Windows平台下的音质不一样.硬件参数没变,歌曲音频文件相同的情况下,linux播放歌曲的时候动态和音乐细节 ...

  9. 保持唯一性,请停止使用【python3 内置hash() 函数】

    问题: 如图,用hash() 筛重时竟然出现了重复. 如下图: hash字符串时,同一窗口的是一致的,不同窗口结果竟然不同. 原因: python的字符串hash算法并不是直接遍历字符串每个字符去计算 ...

  10. kubernetes核心实战(一)--- namespace

    kubernetes核心实战 1.资源创建方式 命令行创建 yaml文件创建 2.namespace 命名空间(namespace)是Kubernetes提供的组织机制,用于给集群中的任何对象组进行分 ...