본문 바로가기

Linux(Centos or RHEL)/docker

DinD, DooD..?

아래의 글들을 참조하여 작성하였습니다.

https://aidanbae.github.io/code/docker/dinddood/

https://blog.nestybox.com/2019/09/14/dind.html

 

 

DinDDooD...?

DinDDooD는 반대되는 용어입니다. 이 방법들은 Continuous Integration(CI) 파이프라인에서 사용하거나, 도커를 이용한 개발의 테스트 환경(호스트에서 사용하는 도커 버전이 아닌 다른 버전을 이용하는 것 등등)을 구축할 수 있습니다.

 


DinDDocker in Docker의 약어로, 도커 컨테이너 내부에 호스트 도커 데몬과는 별개의 새로운 도커 데몬을 실행시키는 것입니다. 새로 실행된 도커 데몬 컨테이너에, 새로운 도커 클라이언트 컨테이너를 이용하여 명령을 내리는 것이 가능합니다. 새로 생성된 도커 환경은 컨테이너 환경이기 때문에, 테스트 후의 정리가 꽤나 간편합니다. 하지만 설정하는 방법이 약간은 불편합니다.

그림1 DinD 구조

 

DinD 이용하기 위해서는 새로운 도커 데몬 컨테이너를 실행시킬 때, --privileged 옵션을 이용할 필요가 있습니다. 이 옵션은 컨테이너가 호스트 머신의 대부분의 권한을 얻을 수 있게 해줍니다.

 

docker run privileged 옵션 : https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

 

하지만 이 방법은 보안상으로 아주 좋지 않은 환경을 만듭니다... 예를들면, 거의 대부분의 장치들에 접근이 가능하여, 호스트의 ”/boot“를 컨테이너에서 마운트 하여, initramfs, 부트로더를 수정하거나 삭제하는 등등의 작업을 할 수도 있습니다...

(1) https://www.linux.com/audience/devops/lazy-privileged-docker-containers/

(2) https://brauner.github.io/2019/02/12/privileged-containers.html

(3) https://containerjournal.com/topics/container-security/why-running-a-privileged-container-is-not-a-good-idea/

 

 

DinD로 도커 데몬을 실행하는 방법은 아래와 같이 실행하면 됩니다.

https://www.caktusgroup.com/blog/2020/02/25/docker-image/

https://serverfault.com/questions/993610/docker-in-docker-cannot-connect-to-the-docker-daemon-at-tcp-docker2375

 

 

step 1. 도커 데몬 컨테이너 실행

$ docker run --privileged it d --name some-docker -e DOCKER_TLS_CERTDIR="" docker:dind

 

 

step 2. 도커 클라이언트 컨테이너를 실행하여 도커의 버전 확인 및 테스트용 alpine 컨테이너 실행

$ docker run rm --link some-docker:docker docker version

$ docker run rm --link some-docker:docker docker run it d alpine

$ docker run rm --link some-docker:docker docker ps -a

 

 


DooDDocker Out Of Docker의 약어로, 호스트 도커 데몬이 사용하는 소켓을 공유하여 도커 클라이언트 컨테이너에서 컨테이너를 실행시키는 것입니다. 새로 실행시킨 컨테이너는 도커 클라이언트 컨테이너와 sibiling 관계를 가집니다. 따라서 테스트 환경이 도커 호스트 환경과 일치하는 것을 알 수 있습니다. 호스트와 도커 이미지를 공유한다든지 등등이 있습니다.

 

그림2 DooD 구조

실행 방법은 간단합니다. 아래와 같이 호스트의 도커 소켓을 컨테이너에 마운트 시켜주면 됩니다.

$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock docker

 

이 방법은 도커 클라이언트 컨테이너에 --privileged 옵션을 주지 않았기 때문에 DinD보다는 안전합니다. 하지만, 컨테이너의 격리에 문제가 조금 있습니다. 예시로는 아래와 같은 것들이 있습니다.

 

(1) 컨테이너의 이름 충돌 : 도커 클라이언트 컨테이너에서 컨테이너 실행 명령을 내릴 때, 컨테이너의 이름이 호스트에서 실행한 컨테이너의 이름과 겹치면 실행이 불가합니다.

 

(2) 마운트 경로 : 도커 클라이언트 컨테이너에서 새로운 컨테이너를 bind mount를 이용하여 만들 때, 호스트의 파일 경로를 기준으로 해야됩니다.

 

(3) 포트 맵핑 : 포트 맵핑 또한 호스트 레벨에서 하기 때문에, 포트가 충돌이 일어날 가능성이 있습니다.

 

하지만, DinD보다는 권장되는 방법입니다.

DinD의 문제점에 대한 링크 : https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/