본문 바로가기

카테고리 없음

docker in docker (dind) 원리

gitlab runner를 사용해서 CI-CD를 하다보니 도커 안에서 도커를 빌드하고 푸쉬하는 경우가 생겼다.

runner 의 executor가 docker이기 때문에 다양한 이미지를 쓸수 있는데 docker 이미지 또한 쓸수 있다.

CI-CD를 하다보면 CI를 할때 도커를 빌드하고 푸쉬하는 과정이 생기기 마련인데 이때 완전히 격리된 환경에서 푸쉬하고 싶을때 이렇게 dind 방식을 쓸수 있다. 두번째 방법으로는 호스트 docker deamon을 쓰는 방식이 있는데 이 포스팅에서는 첫번재만 다룬다.

이럴때 쓸수있는 방법이 docker in docker (dind) 방법이다.

 

그림으로 보면 다음과 같다.

 

 

바깥에 있는 docker는 Runner의 docker 즉 러너가 설치된 서버의 docker이고 안쪽의 docker:git 와 docker:dind는 CI 과정에서 Runner가 생성한 컨테이너의 도커이다. docker:git은 Client 로서 컨테이너 안쪽에서도 도커 명령어를 평소처럼 쓰게끔 해주는 기능이고 docker:dind은 컨테이너에서 작성한 도커 명령어가 실행될수 있도록 deamon을 제공하는 기능을 수행한다. 그림과 같이 완전히 격리된 상태이고 만약 바깥쪽 Runner의 docker deamon을 쓰고 싶다면 러너 설정에서 볼륨마운팅을 해줘야 한다. ( 앞서 설명한 두번째 방법 )

 

volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]

 

dind 방식에서는 격리된 상태로 안쪽의 deamon을 쓰기 때문에 볼륨 마운팅은 안하지만 대신 아래와 같이 러너 설정을 해줘야 한다.

 

privileged = true

 

위 그림을 gitlab-ci.yml로 표현하면 다음과 같다.

 

# Define a template for build&push jobs
.build_push_template: &build_push_definition
  stage: build_push
  image: docker:git
  variables:
    DOCKER_TLS_CERTDIR: ""  # Docker TLS 인증서 디렉토리 비활성화
    DOCKER_DRIVER: overlay2
  services:
    - name: docker:dind
      command:
        - /bin/sh
        - -c
        - |
          echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/my-ca.crt \
          && update-ca-certificates \
          && dockerd-entrypoint.sh || exit 1
  script:
    - docker info
    - docker build -t <image:tag> <address of Dockerfile>
    - docker push <image:tag>
  only:
    - main

 

Runner의 설정은 다음 과 같다.

 

# 병렬 처리할 쓰레드 수
concurrent = 6
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "runner"
  url = <your_gitlab_address>
  id = 5
  token = <token>
  token_obtained_at = 2024-07-29T02:21:44Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "ubuntu"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    # 도커 볼륨 매핑
    volumes = ["/cache"]
    shm_size = 0
    network_mtu = 0