【GitLab系列四】Dood与Dind究竟有什么区别

Gitlab CI中的Dood与Dind

在通过jenkins或Gitlab使用Docker容器化构建服务的时候,我们会遇到两种构建的方式,分别是DIND与DOOD,这两种的构建的方式却有着很大的差异,接下来分别介绍两种构建方式的区别:

Dood

相信很多人会认为dind就是通过挂载卷的方式通过-p /var/run/docker.sock:/var/run/docker.sock挂载到容器内,通过docker engine与这个被挂载进来的docker.sock进行通信,其实这种方式是DOOD

Dind

既然知道了以往我们认为的dind被纠正为Dood了,那dind究竟是什么,实际上dind指的是在一个安装有Docker engine的容器内以特权模式和与之--linkdocker daemon进行通信,并在容器内构建新的Docker镜像。解释起来感觉很绕口,下面我们通过gitlab runnerdocker executor来逐一验证这些概念。

下面是一张dind与dood构建方式的区别,仅供参考:

image-20200911112522658

经过上图,基本上了解了dood与dind之间的区别,现在我们先运行一个通过docker container运行的gitlab-runner,同时注册其的执行器为docker方式:

docker run --rm -t -i -v /etc/gitlab-runner:/etc/gitlab-runner --name gitlab-runner gitlab/gitlab-runner register \
  --executor "docker" \
  --docker-image alpine:3 \
  --url "https://code.devopsman.cn/" \
  --registration-token "PROJECT_REGISTRATION_TOKEN" \
  --description "share-platform01" \
  --tag-list "p01" \
  --run-untagged \
  --locked="true"

这里需要了解一下docker executor的运行方式:

  • 创建.gitlab-ci.ymlservice指令声明的 容器
  • 然后创建用于缓存cache的容器
  • 创建 build 容器并且关联到所有通过service指令创建的容器,使其可以通过主机名进行通信
  • 将job里面声明的shell指令发送到启动后的build容器内
  • 执行 job片段内声明的指令
  • 检出代码: /builds/group-name/project-name/
  • 执行 .gitlab-ci.yml 中定义的步骤.
  • 检查脚本执行后的状态码,如果非 0 则构建失败.
  • 清理 build 和 service 容器.

在大致的了解docker executor的工作流程之后,我们修改gitlab-runner的配置文件,修改后gitlab-runner会自动加载更新后的配置

[[runners]]
  name = "share-platform01"
  url = "https://code.devopsman.cn"
  token = "AHjrbxtH8_cNyHZtG8KH"
  executor = "docker"
  privileged = true
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
  [runners.docker]
    tls_verify = false
    image = "busybox"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0

在该配置文件中,增加了privileged=true的指令,让gitlab-runner容器拥有特权模式,而后我们在一个node.js的项目中,添加一个.gitlab-ci.yml文件

image: docker:stable

services:
  - docker:19.03.7-dind

variables:
  DOCKER_HOST: tcp://docker:2375
  DOCKER_TLS_CERTDIR: ""

stages:
  - build
  - test
  - deploy

before_script:
  - docker login -u${DOCKER_REGISTRY_USER} -p${DOCKER_REGISTRY_PASSWORD} ${DOCKER_REGISTRY_ADDRESS}

BuildImages:
  stage: build
  script: 
    - docker build -t registry.cn-beijing.aliyuncs.com/devopsman/marionxue-ops:${CI_PROJECT_NAME} .
    - docker push registry.cn-beijing.aliyuncs.com/devopsman/marionxue-ops:${CI_PROJECT_NAME}
  only:
    - master

TestImage:
  stage: test
  script:
    - mkdir -pv /logs/${CI_PROJECT_NAME}
    - if [ $(docker ps -qa --filter name=${CI_PROJECT_NAME}) ];then docker rm -f ${CI_PROJECT_NAME};fi
    - docker run -d --restart=always --name ${CI_PROJECT_NAME} -v /logs/nodedemo:/logs/${CI_PROJECT_NAME} -e NODE_ENV=production --net=host registry.cn-beijing.aliyuncs.com/devopsman/marionxue-ops:${CI_PROJECT_NAME}
    - sleep 5
    - docker ps -as
    - docker ps -a

这个项目的.gitlab-ci.yml文件,会触发share-platform01这个runner运行一个新的容器,并且使用含有docker二进制的docker:stable为基础镜像,同时创建一个运行有docker daemon的容器与其关联,这样既可在gitlab-runner的容器内使用docker pullbuildpush等与docker daemon通信的命令。同时在gitlab-runner内拉取的镜像和构建的中间产物都存在与gitlab-runner容器内,与宿主机上是完全隔离的。这也适用与多环境的同时测试。

这就是Dind方式的构建,这里要注意的是Dind使用过程中,文件系统挂载问题

下面我们介绍一下Dood方式的构建,在gitlab-runner配置文件上有部分的区别:

[[runners]]
  name = "share_runner_01"
  url = "https://code.devopsman.cn"
  token = "wiyyzkYq9BHhG4cCQHWu"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "busybox:latest"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

这里通过volumes将宿主机上的/var/run/docker.sock挂载到了gitlab-runner容器内,但实质上是与宿主机上的docker daemon通信,而在构建过程中拉取的镜像和中间镜像都存在宿主机上,这样虽然可以高效的利用上了Docker的镜像缓存,但是也因为不同的构建环境造成镜像文件过多等后期的磁盘存储问题。

Dind/Dood在K8s上的使用

Dood & k8s

apiVersion: v1 
kind: Pod 
metadata: 
    name: dood 
spec: 
    containers: 
      - name: docker-cmds 
        image: docker:1.12.6 
        command: ['docker', 'run', '-p', '80:80', 'httpd:latest'] 
        resources: 
            requests: 
                cpu: 10m 
                memory: 256Mi 
        volumeMounts: 
          - mountPath: /var/run 
            name: docker-sock 
    volumes: 
      - name: docker-sock 
        hostPath: 
            path: /var/run

Dind & k8s

apiVersion: v1 
kind: Pod 
metadata: 
    name: dind 
spec: 
    containers: 
      - name: docker-cmds 
        image: docker:1.12.6 
        command: ['docker', 'run', '-p', '80:80', 'httpd:latest'] 
        resources: 
            requests: 
                cpu: 10m 
                memory: 256Mi 
        env: 
          - name: DOCKER_HOST 
            value: tcp://localhost:2375 
      - name: dind-daemon 
        image: docker:1.12.6-dind 
        resources: 
            requests: 
                cpu: 20m 
                memory: 512Mi 
        securityContext: 
            privileged: true 
        volumeMounts: 
          - name: docker-graph-storage 
            mountPath: /var/lib/docker 
    volumes: 
      - name: docker-graph-storage 
        emptyDir: {}
云原生生态圈版权声明:
作者:云原生生态圈
文章标题: 【GitLab系列四】Dood与Dind究竟有什么区别
链接:https://devopsman.cn/archives/122
来源:云原生生态圈
投稿联系: cloud.native@qq.com 文章版权归作者所有,未经允许请勿转载。
THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录