Docker 아키택처와 Dind, Dood - g-market/b-shop-backend GitHub Wiki

Docker 아키택처와 Dind, Dood

  • 이번 프로젝트를 수행하며 CI 단계에서 만났던 문제를 해결하며 새로 알게된 개념에 대해 소개
  • 주제는 Docker Architecture, Dind, DooD

Trouble

  • gitlab runner로 CI 파이프라인을 만들고 통합테스트를 위해 TestContainers를 사용
  • TestContainers로 생성된 MySql, redis 컨테이너와 연결이 안됨…
  • gitlab runner를 Docker out of Docker 형태로 Host Machine에서 컨테이너를 실행해서 발생하는 오류

Solution : Dind 컨테이너!


Docker 아키택처

  • Docker in docker, Docker out of docker를 이해하기 위해서는 먼저 도커의 아키택처가 어떻게 구성되어있는지 이해해야한다. image

  • 도커는 도커 데몬이라는 서비스와, 도커 클라이언트라는 서비스 간 rest api 통신으로 작동된다.

  • 우리가 터미널 shell로 입력하는 모든 명령어는 docker client를 통해 API 명령어 형태로 docker daemon으로 전달되어서 실행된다. (/var/run/docker.sock)

도커 데몬(daemon)

리눅스 기반의 OS 에 도커를 설치하고 다음과 같은 명령어를 입력해보자

ps aux | grep dockerd

image

도커 데몬이 백그라운드 프로세스로 돌고있는 것을 확인할 수 있다.

docker daemon은 Docker API를 처리하고 image, container, network, volume등 과 같은 docker object를 관리한다.

아래와 같은 명령어로 도커 데몬의 통신 방법을 바꿔줄 수 있다. 이렇게 설정하면 현재 접속해있는 머신의 데몬에 외부에서 명령어를 전달할 수 있다.

dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

도커 클라이언트(client)

which docker

image

도커 클라이언트는 일반적으로 다음 단계를 통해 클라이언트와 통신한다.

  1. 사용자가 docker ps와 같은 도커 명령어를 입력
  2. /usr/bin/docker/var/run/docker.sock 유닉스 소켓을 사용해 도커 데몬에게 명령어 전달
  3. 도커 데몬은 이 명령어를 파싱하고 명령어에 해당하는 작업 수행
  4. 수행 결과를 도커 클라이언트에 반환하고 사용자에게 결과 출력

DooD(Docker out of Docker)

  • 도커 Host 머신위에 자신과 동일한(sibling) 관계의 Docker container 생성
  • 아래 그림에서 container2, container3는 container1에 종속되지 않고 Host 머신에 종속

image

  • 이는 도커 호스트와 container1의 데몬이 소켓형태로 통신할 수 있기때문
  • DooD형태로 container1에서 다른 컨테이너를 생성하기 위해서는 다음과 같이 /var/run/docker.sock 을 볼륨으로 마운트 해줘야한다.
docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Dind(Docker in Docker)

  • 도커 Host 머신에 새로운 컨테이너가 생성되는 것이 아닌 컨테이너 내부에 또 다른 격리된 컨테이너가 생성되는 형태
  • Container1(dind 컨테이너)위에 container4, container5 가 생성된다.
  • Dind 컨테이너가 독립적인 docker daemon 프로세스를 실행하고 있음

image

Dind를 사용하기 위한 이미지, 옵션 설정이 필요

  • privileged : 도커 컨테이너는 기본적으로 Unpriviledged 모드로 생성이 됨, priviledged 모드로 컨테이너를 실행하게 되면 Container 안에서 Host의 리눅스 커널 기능을 모두 사용할 수 있다.
docker run --privileged –it –d --name some-docker -e docker:dind

주의!

  • privileged 모드로 실행시키면 시스템의 모든 장치에 접근할 수 있으며 커널 기능 대부분 수행이 가능하기 때문에 보안이슈가 있다.
  • 도커에서는 privileged 모드를 사용하는 Dind 형태를 권고하지 않음

[참고]

https://junstar92.tistory.com/169

https://velog.io/@weekbelt/도커데몬Docker-Daemon

Docker-DinD,-DooD