Docker는 크게 Docker Daemon, Docker Client, Docker Registry로 분리되어 있습니다.
dockerd
)docker
)dockerd
)로 전송합니다.docker pull
, docker run
과 같은 명령어를 사용하면 사용자가 요청한 이미지를 docker registry에서 찾아서 가져오게 됩니다.docker push
명령어 사용 시 docker는 이미지를 registry에 저장하게 됩니다.Docker 내부에서 Docker를 사용하는 방법에는 크게 2가지가 있습니다.
도커 내에서 도커 데몬을 추가로 실행하는 방식입니다. 실제 데몬을 동작시켜야 하기 때문에 --privileged
옵션을 사용하여 추가 권한을 부여하는 것이 필요합니다.
docker run --privileged --name <컨테이너명> -d <이미지명>
DinD 방식은 도커 안에 새로운 격리된 환경을 만들 수 있다는 장점이 있지만, 보안상의 문제로 추천되는 방식은 아닙니다.
--privileged
옵션은 호스트의 모든 장치에 액세스하는 권한을 부여하고 컨테이너가 호스트의 컨테이너 외부에서 실행되는 프로세스와 거의 동일한 호스트 액세스를 허용합니다. 즉, 컨테이너가 호스트 전체 권한을 갖게 되는 치명적인 결함을 가집니다.
DinD 사용법 참고 👉 Docker in Docker and play-with-docker
컨테이너 외부에 존재하는 도커 호스트의 기능을 빌려서 사용하는 방식입니다. 비교적 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
참고