gitlab-runner 的 executors 之 docker


gitlab-runner 的 executors 之 docker

兩種使用方式

docker-in-docker

sudo gitlab-runner register -n \
   --url https://gitlab.com/ \
   --registration-token REGISTRATION_TOKEN \
   --executor docker \
   --description "My Docker Runner" \
   --docker-image "docker:stable" \
   --docker-privileged
  • 以上命令將注冊一個使用docker:stable鏡像的 Runner,它使用privileged模式啟動構建和服務容器。這也是使用docker-in-docker模式必須使用的設置

  • 注意:通過--docker-privileged啟用特權模式,禁用容器的所有安全機制,並將主機暴露在權限提升中,這可能導致容器中斷。更多信息查看 Docker 官方文檔運行時特權和 linux 功能

  • 上面的命令得到對應配置文件如下

 [[runners]]
   url = "https://gitlab.com/"
   token = TOKEN
   executor = "docker"
   [runners.docker]
     tls_verify = false
     image = "docker:stable"
     privileged = true
     disable_cache = false
     volumes = ["/cache"]
   [runners.cache]
     Insecure = false
image: docker:latest

services:
  - docker:dind

build:
  stage: build
  script:
    - docker build -t test .
  • 缺點和不足如下:
    • 使用 docker-in-docker 時,每個作業都處於干凈的環境中,沒有過去的歷史記錄。並發任務執行正常,因為每個構建都有自己的 Docker 引擎實例,因此它們不會相互沖突。但這也意味着工作可能會變慢,因為沒有層緩存
    • 默認情況下,docker:dind 使用的--storage-driver vfs 是最慢的形式。要使用其他驅動程序,請參閱 使用 overlayfs 驅動程序
    • 由於 docker:dind 容器和運行器容器不共享其根文件系統,因此任務的工作目錄可用作子容器的安裝點。例如,如果您要與子容器共享文件,則可以在/builds/$CI_PROJECT_PATH 其下創建子目錄並將其用作掛載點(有關更詳細的說明,請查看問題#41227

使用 Docker 套接字綁定

  • 另一種方法是綁定/var/run/docker.sock到容器中,以便 Docker 在該映像的上下文中可用
  • 注意:如果在使用 GitLab Runner 11.11 或更高版本時綁定 Docker 套接字,則無法再將其 docker:dind 用作服務,因為也會對服務進行卷綁定,從而使這些服務不兼容

  • Runner 注冊命令如下
sudo gitlab-runner register -n \
   --url https://gitlab.com/ \
   --registration-token REGISTRATION_TOKEN \
   --executor docker \
   --description "My Docker Runner" \
   --docker-image "docker:stable" \
   --docker-volumes /var/run/docker.sock:/var/run/docker.sock
  • 以上命令將注冊一個使用docker:stable鏡像的 Runner。注意:他是用的是 Runner 本身的 Docekr 守護程序,而 docker 命令生成的任何容器都是 Runner 的兄弟,而不是 Runner 的子節點。
  • 上面的命令得到對應配置文件如下
 [[runners]]
   url = "https://gitlab.com/"
   token = REGISTRATION_TOKEN
   executor = "docker"
   [runners.docker]
     tls_verify = false
     image = "docker:stable"
     privileged = false
     disable_cache = false
     volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
   [runners.cache]
     Insecure = false
  • 對應的.gitlab-ci.yml例子如下
image: docker:stable

before_script:
  - docker info

build:
  stage: build
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests
  • 可以看到,這個模式不需要使用服務,直接通過套接字通信。此模式也是有一些需要注意的地方:
    • 由於是共享 docker 守護程序,項目的操作會真實產生影響。比如項目如果運行docker rm -f $(docker ps -a -q),那么將會刪除所有容器
    • 並發可能會有沖突,比如創建相同的名稱的容器
    • 由於創建的容器是 Runnner 的兄弟,所以文件與目錄的共享是在主機上下文完成,而不是構建容器上下文

總結

  • 選擇兩種方式都各有好壞,可根據實際情況進行選擇。這里還是推薦用第二種,因為第一種真的很干凈,所以很慢
  • 做好權限管理和控制,避免危險的腳本
  • 還有一點是,指定鏡像版本的時候,最好指定具體的版本。比如使用第一種模式,引入服務docker:dind,最好使用docker:18.09.8-dind。避免鏡像拉取策略,每次拉取最新的鏡像,導致實際是docker:19.0-dind,與安裝的 docker 版本不符,發生一些意想不到的錯誤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM