0. 들어가며
Jenkins 컨테이너 내부에서 도커 명령어를 사용하려 할 때, "Docker command not found" 라는 출력 메시지를 맞닥뜨렸다.
.
각 컨테이너는 격리된 공간을 사용하니, 젠킨스 컨테이너 내부에는 도커가 없는 것이 당연했다. 그렇다면 어떻게 해야 도커가 설치되지 않은 컨테이너에서 도커를 사용할 수 있을까?
.
DinD 구조와 DooD 구조를 통해 컨테이너 내부에서 도커를 사용하는 전략을 살펴보자.
1. DinD(Docker in Docker)
1.1 DinD 구조
도커 컨테이너 안에서 또 다른 도커 데몬을 실행하는 구조.

1.2. DinD 구조의 문제
1.2.1. 보안상의 문제
- DinD를 구현하려면 호스트 컨테이너를
--privileged 옵션으로 실행해야 한다. 이 옵션은 컨테이너에게 호스트 시스템의 거의 모든 권한을 부여하는 것과 같다.
- 컨테이너 내부에서 악의적인 코드가 실행될 경우, 컨테이너의 격리 경계를 넘어 호스트 시스템의 커널에 접근하고 시스템 전체를 장악할 수 있는 심각한 보안 위협이 초래될 수 있다.
- 또한, 내부 도커 데몬도 호스트 도커 데몬과 커널을 공유함으로 내부 컨테이너에서 발생한 커널 패닉과 같은 문제가 호스트 시스템 전체에 영향을 줄 수 있다.
커널 패닉(kernel panic)
운영 체제가 치명적인 내부 오류를 감지하여 안전하게 복구가 불가능할 때 취하는 동작
1.2.2. 효율성의 문제
- DinD 환경의 내부 도커 데몬은 호스트 도커 데몬과 캐시를 공유하지 않는다. 따라서 매번 새로운 내부 도커 데몬이 생성되고, 이전에 사용했던 이미지 레이어 캐시를 재사용할 수 없게 된다.
- 이로 인해 매번 처음부터 모든 이미지 레이어를 다시 다운로드하고 빌드해야 하므로 빌드 시간이 길어지고, 불필요한 네트워크 및 스토리지 자원을 낭비하게 된다.
이미지 레이어 캐시
Dockerfile의 각 명령어를 실행할 때 생성된 중간 이미지 레이어를 저장하고, 동일한 명령어가 다시 실행될 때 캐싱된 레이어를 재사용하여 빌드 속도를 높이는 기술
1.2.3. 유지보수의 문제
- 관리를 할 때, 호스트 도커 데몬과 내부 도커 데몬, 두 개의 데몬을 모두 고려해야 한다.
- 또한 네트워크 문제나 스토리지 문제가 발생했을 때, 호스트와 내부 컨테이너 중 어느 곳의 문제인지 파악하는데 추가 비용이 발생한다.
2. DooD(Docker out of Docker)
2.1 DooD 구조
호스트의 도커 유닉스 소켓 파일을 컨테이너에 마운트하여 사용하는 구조.
.
컨테이너 내부에 도커 클라이언트(CLI)만 설치하고, 호스트의 도커 데몬을 사용한다. 도커 데몬 공유로 인해 DinD 구조의 한계를 보완할 수 있다.

2.2. DooD 구조의 장점과 한계
2.2.1. 장점
- 컨테이너를
--privileged 옵션으로 실행하지 않아, 불필요한 권한 부여를 방지한다.
- 호스트의 도커 데몬을 직접 사용하므로 이미지 레이어 캐시를 공유하여 빌드 속도가 빠르다.
- 컨테이너 내부의 컨테이너와 같은 복잡한 구조가 아니어서 관리에 용이하다.
2.2.2. 한계
--privileged 보다는 낫지만, docker.sock 파일을 마운트하는 것 역시 컨테이너가 호스트 도커 데몬을 제어할 수 있는 권한을 갖게 되므로 보안상 위험할 수 있다.
3. 느낀점
- 컨테이너의 설계 철학에 대해서 생각해볼 수 있었다. 완전히 독립된 VM과는 달리, 컨테이너는 프로세스 단위로 격리된 공간을 갖고 터미널을 공유한다. 이러한 차이로 인해 VM 보다 실행 속도는 빠르지만, 터미널을 공유하는 구조로 인해 보안과 권한에 신경쓰지 않으면 치명적인 문제가 발생할 수 있다는 것을 알게 되었다.