[Docker] 컨테이너 내부에서 Docker 사용하기 - DinD, DooD

hwwwa·2023년 4월 2일
3

Docker 컨테이너 내부에서 Docker 사용하기


개발환경

  • Ubuntu 20.04 LTS
  • Docker 23.0.2


Docker 아키텍처


Docker는 크게 Docker Daemon, Docker Client, Docker Registry로 분리되어 있습니다.


Docker Daemon (dockerd)

  • Docker Host라고 부르기도 합니다.
  • Docker API 요청을 수신하고 이미지, 컨테이너, 네트워크, 볼륨 등의 도커 오브젝트를 관리합니다.

Docker Client (docker)

  • Docker 서버와 통신하기 위한 가장 중요한 기능을 수행합니다.
  • docker run 명령어 수행 시 Docker Client가 해당 명령어를 REST API Call로 변환하여 Docker Daemon(dockerd)로 전송합니다.

Docker Registry

  • Docker 이미지를 저장하는 저장소 역할을 합니다.
  • default로 퍼블릭 도커 레지스트리인 Docker Hub를 사용합니다. 사용자가 프라이빗 레지스트리를 구축하여 사용할 수도 있습니다.
  • docker pull, docker run과 같은 명령어를 사용하면 사용자가 요청한 이미지를 docker registry에서 찾아서 가져오게 됩니다.
  • docker push 명령어 사용 시 docker는 이미지를 registry에 저장하게 됩니다.


Docker 내부에서 Docker 사용하기


Docker 내부에서 Docker를 사용하는 방법에는 크게 2가지가 있습니다.


Docker in Docker (DinD)

도커 내에서 도커 데몬을 추가로 실행하는 방식입니다. 실제 데몬을 동작시켜야 하기 때문에 --privileged 옵션을 사용하여 추가 권한을 부여하는 것이 필요합니다.

docker run --privileged --name <컨테이너명> -d <이미지명>

DinD 방식은 도커 안에 새로운 격리된 환경을 만들 수 있다는 장점이 있지만, 보안상의 문제로 추천되는 방식은 아닙니다.


--privileged 옵션은 호스트의 모든 장치에 액세스하는 권한을 부여하고 컨테이너가 호스트의 컨테이너 외부에서 실행되는 프로세스와 거의 동일한 호스트 액세스를 허용합니다. 즉, 컨테이너가 호스트 전체 권한을 갖게 되는 치명적인 결함을 가집니다.


DinD 사용법 참고 👉 Docker in Docker and play-with-docker



Docker out of Docker (DooD)

컨테이너 외부에 존재하는 도커 호스트의 기능을 빌려서 사용하는 방식입니다. 비교적 Docker 측에서 DinD보다 권장하는 방식입니다.
내부에 새로운 컨테이너 서비스를 만들지 않고 기존에 사용하던 컨테이너를 추가로 생성합니다.


소켓 파일을 컨테이너와 공유하면 소켓 파일을 통해 도커 명령을 수행할 수 있습니다.

docker run -v /var/run/docker.sock:/var/run/docker.sock --name <컨테이너명> -d <이미지명>

컨테이너 내부에서 도커 명령을 수행하게 되면 호스트에서 실행중인 도커 데몬에게 전달되게 됩니다.


컨테이너 내부에서 아래의 명령어를 수행합니다.

# 호스트의 docker 그룹 ID(998)로 지정된 그룹명을 docker로 변경
groupmod -g 998 docker
# 컨테이너 내부 사용자가 호스트의 파일에 접근 가능하도록 호스트 사용자 아이디(1000)로 변경
usermod -u 1000 jenkins

apt-get update
apt-get -y install lsb-release apt-transport-https ca-certificates curl gnupg2 software-properties-common
apt-get -y upgrade apt-transport-https

# Docker 다운로드 링크 추가
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey
apt-key add /tmp/dkey

# Docker Repository 등록
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") $(lsb_release -cs) stable"

# Docker 설치
apt-get update
apt-get -y install docker-ce docker-ce-cli containerd.io

참고) 호스트의 사용자 아이디는 /etc/passwd에서, 도커 그룹 아이디는 /etc/group에서 확인 가능합니다.


이제 컨테이너 내부에서 컨테이너 생성하는 명령어를 사용할 수 있습니다.


docker run --name mycentos7 -d -u root centos:7 /sbin/init

docker exec -it mycentos7 bash



참고

0개의 댓글