-
DooD (docker-outside-of-docker) 를 통해 Jenkins 컨테이너에서 docker 사용하기docker 2021. 9. 6. 20:55반응형
Jenkins 를 docker 를 통해 컨테이너로 띄우는 것이 아주 편해져서 이제는 docker 로 운영하고 있다.
그런데, Jenkins 상에서 Docker 관련 작업이 필요하여 단순하게 컨테이너 내부에서 설치를 하려고 했는데, 내부에서 docker 를 띄우는 것과 관련하여 이것저것 이슈가 있다고 한다. (https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/)
관련해서 좀 더 찾아보았는데, 내부에서 Docker 를 전부 띄우지 말고 외부(호스트 환경) 의 Docker 와 소켓을 공유하여 사용하는 것이 그나만 나은 방법이라고 한다.
이를 기존의 방식인 Docker-in-docker 와 대비하여 Docker-outside-of-docker 라고 부르는 것 같다. 완전히 정착된 이름은 아닌 것 같지만 이 글에서는 이 이름을 사용하겠다.
공식 Jenkins 이미지: https://hub.docker.com/r/jenkins/jenkins
공식 Docker 이미지: https://hub.docker.com/_/docker (여기도 Docker-in-docker 를 추천하지 않는다고 쓰여있다.)
환경
- 호스트 서버
- CentOS 7.9
- Docker server: 20.10.8
- 사용자는 docker 그룹에 포함되어 있다. (sudo 없이 docker 명령어 입력 가능)
- Jenkins 컨테이너
- 기본 이미지: 2.289.3-jdk11
- 내부에서 Docker 를 사용해야 하기 때문에 이를 베이스로 새로 이미지를 만들 것이다.
- Docker client: 20.10.8
- 기본 이미지: 2.289.3-jdk11
1. Jenkins 이미지 만들기
컨테이너 내부에서 외부(호스트) 도커와 통신해야 하기 때문에 추가로 설치할 것이 있다. 기본 이미지는 현시점 (2021-09-06) 에서 가장 최신의 lts 버전이고, jdk11 이 들어 있는 버전인 2.289.3-jdk11 을 택한다.
젠킨스 이미지: https://hub.docker.com/r/jenkins/jenkins/tags?page=1&ordering=last_updated&name=2.289.3-jdk11
Docker client 가 필요하기 때문에 Dockerfile 를 통해 설치하고 이미지를 만든다. 베이스 이미지가 Debian 기반이기 때문에 Debian 환경에 Docker 설치를 위한 가이드를 참고한다.
공식 가이드: https://docs.docker.com/engine/install/debian/
Dockerfile 은 아래와 같다.
FROM jenkins/jenkins:2.289.3-jdk11 USER root RUN apt-get update \ && apt-get -y install lsb-release \ && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \ && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \ && apt-get update \ && apt-get -y install docker-ce docker-ce-cli containerd.io RUN usermod -u {{호스트의사용자아이디}} jenkins && \ groupmod -g {{호스트의도커그룹아이디}} docker && \ usermod -aG docker jenkins USER jenkins
- 사이트에서 요구하는 패키지들이 있는데, 대부분 이미 설치되어 있고, lsb-release 만 추가로 설치하면 된다.
- 외부(호스트) 도커 서버를 사용할거라서 docker-ce-cli 만 설치해도 되기는 하지만, docker-ce 를 설치해야 docker 그룹이 생긴다. 괜히 건드렸다가 꼬일 것 같아서 그냥 가이드대로 다 설치했다.
- 컨테이너 내부 사용자 (jenkins) 가 호스트의 파일에 접근이 가능 가능하도록 호스트 사용자 아이디와 동일하도록 맞춰준다. (위 Dockerfile 에서 {{호스트의사용자아이디}})
- 사용자 아이디는 호스트의 /etc/passwd 에서 확인한다.
- 컨테이너의 도커 그룹 아이디를 호스트의 도커 그룹 아이디와 동일하게 맞춘다. (위 Dockerfile 에서 {{호스트의도커그룹아이디}})
- 도커 그룹 아이디는 호스트의 /etc/group 에서 확인한다.
이미지를 만든다.
docker build -t my-jenkins:0.1 .
확인
[user@host ~]$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE my-jenkins 0.1 df9c3ec43a7c 4 minutes ago 1.15GB jenkins/jenkins 2.289.3-jdk11 ea470c80c15d 5 weeks ago 680MB
2. volume 만들기
jenkins 설정 및 히스토리를 저장하고 재시작시에도 유지되도록 volume 을 만든다.
docker volume create jenkins
확인
[user@host ~]$ docker volume ls DRIVER VOLUME NAME local jenkins
3. Jenkins 컨테이너 실행
docker run -d --name jenkins \ -v /var/run/docker.sock:/var/run/docker.sock \ -v jenkins:/var/jenkins_home \ -p 8080:8080 my-jenkins:0.1
- 핵심은 docker.sock 을 마운트 하는 것이다. 이를 통해 컨테니어 내부에서 외부(호스트) 의 docker 서버에 접근할 수 있다.
- volume 을 마운트하고, 접근 포트를 열어준다.
컨테이너가 잘 떴는지 확인해 보자
[user@host ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d57073d5fec2 my-jenkins:0.1 "/sbin/tini -- /usr/…" 3 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins
jenkins 컨테이너 내부에서도 호스트의 docker 에 접근이 가능한지 내부에서 호출하여 확인해 보자
[user@host ~]$ docker exec jenkins docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d57073d5fec2 my-jenkins:0.1 "/sbin/tini -- /usr/…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins
호스트의 도커 서버를 공유하고 있기 때문에 같은 결과가 나온다.
반응형'docker' 카테고리의 다른 글
nexus3 docker image 로 private docker repository 만들기 (1) 2022.02.14 docker 환경에서 nginx 로 jenkins ssl 적용 (0) 2022.02.09 - 호스트 서버