在容器化的持續交付過程中,經常涉及到使用自己定制的鏡像運行代碼、測試等。如果這些鏡像需要每次手動更新,不妨將這些鏡像的打包與發布流程也加入CI/CD流程:
對鏡像:
- 鏡像的Dockerfile/依賴文件發生改動
- 自動build鏡像
- 自動push到鏡像倉庫
對原有CI/CD流程:
- 代碼發生改動
- 從鏡像倉庫拉取最新鏡像
- 運行單元測試
以下內容就是如何實現鏡像的持續交付。
注冊docker hub賬號
官方docker hub地址:https://hub.docker.com/
注冊你的賬號。
當然,也可以自己搭建一個私有倉庫,過程與推送到官方倉庫一樣,不贅述。
注冊gitlab-runner
詳細的注冊過程參考:gitlab-ci 持續集成完整實踐 “Gitlab CI 基本配置”一節。
重點關注如下幾個配置項:
- 指定executor為“docker”
- 指定tag為“docker”
添加.gitlab-ci.yml
腳本
可以直接選擇Dockerfile的yml模版,稍作修改即可。
image: docker:stable
services:
- docker:dind
before_script:
- docker login -uityoung -p<PASSWORD>
build:
stage: build
script:
- docker build -t "ityoung/gradle:3.3" .
- docker push ityoung/gradle:3.3
only:
- master
tags:
- docker
- 指定鏡像為
docker:stable
,有關docker的操作都在本鏡像中,如build, push等 - 指定services:
docker:dind
,啟動dockerd并被docker:stable連接作為docker daemon - 指定runner:添加
tags:docker
,為注冊runner時指定的tag - 修改login的賬號與密碼為自己的!
services指定docker:dind不是必須的。由于docker:stable執行入口不包含啟動dockerd的操作,而docker:dind執行入口僅包含啟動dockerd的操作,因此使用docker:dind作為services可以使docker:stable快速連接docker daemon而不用考慮如何啟動dockerd。具體解釋見參考[1]
問題解決
docker:dind
服務啟動失敗
按照上述操作,有可能出現以下警告:
*** WARNING: Service runner-118b6b82-project-10-concurrent-0-docker-0 probably didn't start properly.
Health check error:
ContainerStart: Error response from daemon: Cannot link to a non running container: /runner-118b6b82-project-10-concurrent-0-docker-0 AS /runner-118b6b82-project-10-concurrent-0-docker-0-wait-for-service/service
Service container logs:
2018-09-10T06:02:08.161544784Z mount: permission denied (are you root?)
2018-09-10T06:02:08.161686312Z Could not mount /sys/kernel/security.
2018-09-10T06:02:08.161695928Z AppArmor detection and --privileged mode might break.
2018-09-10T06:02:08.164169464Z mount: permission denied (are you root?)
*********
出現的原因在于,在你的宿主機使用root用戶安裝docker(執行docker命令需要加上sudo),這種情況下,需要配置runner的privileged
為true。
gitlab-runner的配置文件在宿主機上的默認位置為/srv/gitlab-runner/config/config.toml
,直接修改該文件中的配置項即可。
無法登錄HTTPS的Docker倉庫
以Harbor為例,在啟用HTTPS后,登錄需要證書才可完成。但在試過將證書放置在docker:stable
鏡像的/etc/docker/certs.d/<domain>/
目錄下,仍然無法登錄,提示x509: certificate signed by unknown authority。
最后在參考[4]的一個回答中得到解決方法并成功登錄,即:
將證書放置于docker:dind
鏡像的/etc/docker/certs.d/<domain>/
目錄下。
實際上,提供docker daemon的就是該鏡像,證書理應放在該鏡像中。被兩個"docker in docker"鏡像搞迷糊了。
參考
[1] Role of docker-in-docker (dind) service in gitlab ci, Stack Overflow
[2] Push images to Docker Cloud, Docker Docs
[3] Unable to build docker image from .gitlab-ci.yml using shared runner, gitlab.com
[4] Getting x509: certificate signed by unknown authority when talking to docker registry, gitlab.com