[도커] Docker in Docker?

DongGu·2021년 4월 21일
1

https://itnext.io/docker-in-docker-521958d34efd
를 이해하기 위한 노력의 일환으로 작성한 글입니다.

This short article is based on a blog post by Jérôme Petazzoni: Using Docker-in-Docker for your CI or testing environment? Think twice.(https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/)

Docker in Docker?

이 문서에서 살펴본 질문은 다음과 같다. '도커가 설치된 도커 컨테이너'를 실행하는 경우, 도커 컨테이너 내에서 도커를 실행할 수 있나요? 예를 들어, 도커 인스턴스 두 개가 서로 완전히 독립되어 있는 상태에서 이미지를 끌어당기고 구축하거나 다른 컨테이너를 실행할 수 있나요?

대답은 'Yes'지만, low level의 기술적 문제를 많이 일으키므로 권장되지 않는다. 이 문제들은 도커가 운영체제에서 작동하는 방식과 연관되어 있다. 이 내용에 대해선 원글의 작성자가 참고한 글에 잘 설명되어 있다.

좋은 소식은 도커 컨테이너 안에 도커를 사용할 수 있는, 권장되는 방법이 있다는 것이다. 도커 컨테이너에는 두 도커 인스턴스가 서로 독립적이지는 않지만 이러한 문제를 우회하는 방법이 있습니다.

이 접근 방식을 통해, 도커가 설치된 컨테이너는 자체적인 도커 데몬을 실행하지 않고, 호스트 시스템의 도커 데몬에 연결한다. 즉, 컨테이너와 호스트 시스템에 Docker CLI가 있지만 둘 다 동일한 Docker 데몬에 연결된다. 언제든지 시스템에서 실행 중인 Docker 데몬은 호스트 시스템에서 실행 중인 데몬이다.

이를 위해 다음 bind mount(바인딩 마운트) 옵션을 사용하여 Docker가 설치된 Docker 컨테이너를 시작할 수 있다.
v /var/run/docker.sock:/var/run/docker.sock

예를 들어 docker 이미지(도커를 설치한)를 사용할 수 있다.
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock docker

그리고 나서 당신이 실행시킨 도커 컨테이너 안에서, 다음과 같은 도커 명령어를 실행해보라.
docker image
docker ps

아웃풋을 관찰하라. 호스트 시스템에서 이러한 명령을 실행할 때와 결과물은 동일하다.

방금 시작한 컨테이너의 Docker 설치와 비슷하며, 아무 것도 처리되지 않은 이미 일부 이미지가 캐시되고 일부 컨테이너가 실행되고 있습니다. 이는 이미 호스트 시스템에서 실행 중인 Docker 데몬과 대화하기 위해 컨테이너에 Docker CLI를 연결했기 때문입니다.

즉 컨테이너 내부에 이미지를 끌어다 놓으면 호스트 시스템에도 이 이미지가 표시될 것이다.(그 반대도 마찬가지). 컨테이너 내에서 컨테이너를 실행하는 경우, 이 컨테이너는 실제로 호스트 시스템에서 실행 중인 모든 컨테이너(Docker가 실행 중인 컨테이너 포함)에 대한 "sibling"이 된다.

처음에는 짜증날 것이다.(짜증난다...) 컨테이너 내부의 Docker 설치가 호스트 시스템에서 완전히 캡슐화되어 있으면 좋을 것 같다. 그러나 대부분의 사용 사례에는 완전한 캡슐화가 필요하지 않으며, 도커 컨테이너 내에서 Docker를 사용해야 할 때마다 이 해결 방법이 적합하다.

그런데 도커 컨테이너 안에 있는 도커를 언제 이용해야 하나요?

When do you need it?

도커 컨테이너에서 도커를 작동하는 것에 관한 질문은 젠킨스 같은 CI/CD를 사용할 때 빈번하게 발생한다.

젠킨스에서는 파이프라인 단계의 모든 명령이 지정한 에이전트에서 실행된다. 이 에이전트는 도커 컨테이너일 수 있다. 따라서 빌드 단계에서 명령 중 하나가 Docker 명령(예: 이미지 구축)인 경우 Docker 컨테이너 내에서 Docker 명령을 실행해야 한다.

게다가 젠킨스 자체는 도커 컨테이너로 운영될 수 있다. 도커 에이전트를 사용하는 경우 젠킨스 도커 컨테이너 내에서 도커 컨테이너를 시작한다. Jenkins 파이프라인에 Docker 명령도 있는 경우 중첩된 "Dockers"이 3중으로 연결되는 수준이 됩니다. 그러나 위의 접근법에서 이 모든 도커들은 하나의 동일한 도커 데몬을 사용하며, 같은 시스템에 있는 여러 데몬의 모든 어려움 (이 경우에는 3개)은, 그렇지 않으면, 우회한다.

이를 달성하기 위해 당신이 해야할 것은 도커 컨테이너를 다음 명령어와 같이 시작하는 것이다. -v /var/run/docker.sock:/var/run/docker.sock

Real Docker in Docker

원한다면 진짜 도커 속의 도커를 사용할 수 있다. 도커에 새끼를 튼 도커 인스턴스(완전히 서로 캡슐화된)를 말한다. dind(Docker in Docker)라는 도커 이미지 태그를 아래와 같이 쓰면 된다.
docker run --privileged -d docker:dind

이 접근 방법은 원작자가 참고한 포스트에 상세히 설명되어있다. 하지만 이렇게까지 할 필요 없다.

profile
코딩하는 신방과생

0개의 댓글