0. 들어가기 전
개인 프로젝트의 CI/CD를 구성하는 도중에, 처음 접해보는 상황이 생겼었습니다.
바로, 도커 컨테이너 내부에서 도커를 사용해야 하는 상황이었습니다.
구글링을 진행해보니 이러한 상황은 Docker in Docker라는 기술로 불리고 있었습니다.
따라서, 적용한 Docker in Docker와 트러블 슈팅을 진행한 경험을 포스팅해보겠습니다.
1. Docker in Docker 필요 상황
도커 컨테이너 내부에서 왜 도커를 실행해야 하는 상황이 발생했는지 먼저 살펴보겠습니다.
저는 CD 툴로 Jenkins를 사용하고 있습니다.
이때, Jenkins도 하나의 도커 컨테이너 내부에서 실행되고 있습니다.
이 상황에서, Jenkins의 CD 파이프라인 일부는 다음과 같았습니다.
stage('push jar file to docker hub') {
steps {
echo 'docker hub login'
sh 'echo ${DOCKER_HUB_CREDENTIALS_PSW} | docker login -u ${DOCKER_HUB_CREDENTIALS_USR} --password-stdin'
echo 'push jar file to docker hub'
sh 'docker push ${repository}:${BUILD_NUMBER}'
}
}
도커 허브에 로그인하여, 빌드한 파일을 Docker hub에 push하는 step인데요!
Docker hub에 push하는 과정에서 도커 명령어(docker push)가 사용됩니다.
이때, 사용되는 환경은 도커 컨테이너 내부이기 때문에 기본 설정으로 도커 컨테이너를 실행했다면 내부에 도커가 없습니다.
따라서, 젠킨스 파이프라인에서 다음과 같은 에러를 마주쳤습니다.
docker: not found 라는 도커가 설치되지 않아서 도커 관련 명령어를 수행할 수 없는 에러입니다.
이러한 상황을 해결하기 위해, 도커 컨테이너 내부에 도커를 설치하려고 하던 중 Docker in Docker라는 개념을 발견했습니다.
1. Docker in Docker 사용하기
처음에는, 기존에 도커를 설치했던 방법처럼 도커 컨테이너 내부에서 도커를 설치하려고 했었습니다.
하지만 도커 컨테이너 내부는 빈 깡통과도 같았기 때문에 설치하기가 힘들었습니다.
그래서 구글링을 거쳐 Docker in Docker를 사용하여 해결하게 되었습니다.
Docker in Docker를 사용하여 도커 컨테이너 내부에서 도커를 사용하는 방법은 크게 2가지로 나뉩니다.
- 호스트의 도커 데몬을 사용(마운트)하여 도커 컨테이너 내부에서 호스트의 도커 데몬을 사용하는 방법
- 도커 컨테이너 내부에서 '실제' 도커를 사용하는 방법
두 가지 방법 중 첫 번째 방법을 중점적으로 설명해보겠습니다.
1-1. 도커 컨테이너 내부에서 호스트의 도커 데몬을 사용하는 방법
이 방법은 도커 컨테이너 내부에서 도커를 사용할 때,
도커 컨테이너 내부의 도커가 아닌, 호스트의 도커 데몬을 사용해서 도커를 사용하는 방법입니다.
사용 방법은 도커 컨테이너를 실행할 때,
도커 데몬에게 명령을 내릴 수 있는 인터페이스인 'docker.sock' 파일을 마운트해서 실행하면 됩니다.
쉽게 말하면, 도커 컨테이너 내부의 도커 데몬 명령어를 실행할 때
호스트의 docker.sock을 사용하도록 해서 별다른 도커 설치 없이 도커를 사용하는 방법입니다.
다음과 같이 마운트하여 도커 컨테이너를 실행하면 됩니다.
-v /var/run/docker.sock:/var/run/docker.sock
저는 젠킨스 이미지를 실행시키고, 백업용 마운트를 하나 더 설정했기 때문에 다음과 같이 컨테이너를 실행했습니다.
docker run -d -p 9000:8080 --name jenkins \
-v /home/ec2-user/jenkins_backup:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins
1-2. 도커 컨테이너 내부에서 실제 도커를 사용하는 방법
도커 컨테이너 내부에서 실제 도커를 사용하는 방법도 존재합니다.
간략하게는 다음과 같이 수행하면 됩니다.
docker run --privileged -d docker:dind
해당 방법은 아래의 링크에 자세히 나와 있습니다.
https://github.com/jpetazzo/dind
이 방법으로 진행하지 않은 이유는, 비효율적이라고 생각했기 때문입니다.
실제 도커를 사용하지 않고 호스트 도커 데몬을 사용하여 도커 명령어를 실행할 수 있음에도 불구하고
도커 컨테이너 내부에 실제 도커를 설치해서 사용하는 것은 서버 리소스 낭비가 심할 것 같았기 때문에 1번 방법으로 진행하게 되었습니다.
2. Docker in Docker 트러블 슈팅
1번 방법으로 호스트 데몬을 사용하여 상황이 해결될 것을 기대했지만, 다음과 같은 오류가 발생했었습니다.
위와 같이 권한 문제로 도커 명령어가 실행되지 않았습니다.
저는 호스트 환경에서 도커 그룹에 유저를 추가하여 권한 없이 도커를 실행하고 있었습니다.
따라서, 도커 컨테이너 내부 환경 사용자도 접근하도록 docker.sock 파일의 접근 권한을 다음과 같이 설정해줬습니다.
sudo chmod 666 /var/run/docker.sock
이렇게 도커 컨테이너 내부에서 도커를 사용할 수 있었습니다.
'Infra > Docker' 카테고리의 다른 글
[Docker] EC2 환경에서 Docker에 Spring Boot WAS 띄우기 with Docker Hub (0) | 2024.01.16 |
---|