只要是人做的事,随着重复执行次数的增加,难免引入失误,所以现在强调IaC(基础架构即代码)。笔者目前的工作与之息息相关,目标是构建一条 CI/CD流水线,将项目编译、测试、打包、发布自动化,选型时根据公司现状,决定用GitLab CI 实现。
本文主要是记录了通过GitLab CI 构建项目的容器镜像时遇到的一个小问题:使用dind(docker in docker)时,需要配置registry-mirror。
一、选用的组件
1、GitLab Runner
GitLab Runner 是配合GitLab CI使用的,是一个执行构建脚本的东西,而GitLab CI就是这些Runner 的管理中心,所有 Runner 都要在GitLab-CI里面登记注册,并且表明自己是为哪个GitLab 项目服务的。当项目发生变化时,GitLab CI就会通知相应的 Runner 执行构建脚本。
GitLab Runner 的安装可以有多种方式,比如二进制 、Docker,由于构建过程往往是较为消耗资源的,所以笔者选择了Docker方式,并且安装在k8s集群中,方便管理以及动态扩容。
2、dind(docker in docker)
由于Runner被Docker化运行在真实的物理机上,当需要在Docker化的Runner里构建项目镜像时就涉及到"Docker run Docker"的问题,官方给出了几种解决方案,大家可以根据实际情况做出选择。笔者这篇文章记录了试验“docker in docker”方案时遇到的问题。
docker in docker有风险,需了解清楚再决定是否使用。
二、注意点
- docker in docker需要开启特权模式。
- 在Docker v19.03或更高版本中,默认开启TLS,需要额外配置,可参考https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled。
- dind支持通过command配置参数,如registry-mirror。
三、配置
1、GitLab Runner
配置文件:/etc/gitlab-runner/config.toml ,主要是“privileged = true”配置项,开启特权模式,从而可以使用dind。当然开启需谨慎,笔者只是试验用,并未真正用在正式环境。
concurrent = 10
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "share-runner-k8s"
url = "http://$ip/"
token = "$token"
cache_dir = "/cache"
[runners.kubernetes]
bearer_token_overwrite_allowed = false
privileged = true #重要!!!开启特权模式,才可以正常使用dind。
service_account = "gitlab-runner"
2、.gitlab-ci.yml
build_docker_image:
stage: build_image
variables:
DOCKER_HOST: tcp://localhost:2375
image: docker:18.06.3-git #指定v19.03之前的版本,以便避开TLS配置(试验使用,正式环境请使用高版本开启TLS)。
services:
- name: docker:18.06.3-dind
command: ["--registry-mirror=http://$ip:$port/"] #通过command可以配置额外参数。
script:
- build_docker_image
only:
- branches
tags:
- share-runner-k8s