只要是人做的事,隨着重復執行次數的增加,難免引入失誤,所以現在強調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
