Jenkins 컨테이너로 해당 호스트의 Docker 데몬을 사용하는 파이프라인 구성 및 해당 동작이 가능한 원리에 대해서 정리
jenkins 컨테이너를 실행할 때 docker 명령어와 docker 소켓 파일을 같이 마운트 해준다
docker run -d -p 8080:8080 -p 50000:50000 --name jenkins-server --restart=on-failure
-v jenkins_home:/var/jenkins_home
-v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker jenkins/jenkins
7bafd7c2be269b7f7d8dc10579c105dccf87adbc318ad46bcc33643a3c388352
간단하게 docker 컨테이너의 조회를 하는 파이프라인을 작성
pipeline {
agent any
stages {
stage('using docker') {
steps {
sh 'docker ps'
}
}
}
}

# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bafd7c2be26 jenkins/jenkins "/usr/bin/tini -- /u…" 43 minutes ago Up 43 minutes 0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp jenkins-server
도커는 클라이언트와 도커 서버(docker daemon)과의 통신을 유닉스 소켓 통신을 사용

출처 : https://docs.docker.com/get-started/docker-overview/#docker-architecture
docker 설치 경로 중 /var/run/docker.sock 해당 파일이 클라이언트 - 서버 간의 소켓 통신을 할 수 있게 해주는 인터페이스
따라서, 해당 파일만 공유하게 되면 호스트에 설치 된 Docker 데몬을 사용할 수 있게 된다
-> jenkins 컨테이너에 호스트의 /var/run/docker.sock 파일을 마운트 해주었기 때문에 jenkins 컨테이너에서 docker ps 명령어가 가능 해짐
리눅스는 모든 게 파일로 이루어졌기 때문에 도커 소켓 인터페이스도 파일로 구성 되어 있음
-> 도커 소켓 인터페이스 파일만 공유해도 통신이 이루어지는 이유
Docker에서 Docker 이미지를 바탕으로 Docker 컨테이너를 띄우고 호스트의 /var/run/docker.sock 로 마운트 해주면 Docker 컨테이너 내에서 호스트의 docker 명령어가 사용 가능한 Docker in Docker 가 가능하게 된다

소켓 파일에 대한 접근 권한 에러가 나서 소켓 파일의 권한을 확인하였다
$ ls -l
total 4
-rw-r--r-- 1 root root 0 Aug 27 14:21 adduser
srw-rw---- 1 root 1001 0 Aug 28 12:35 docker.sock
drwxrwxrwt 2 root root 4096 Aug 12 00:00 lock
# cat /etc/passwd
jenkins:x:1000:1000::/var/jenkins_home:/bin/bash
# ls -l
total 4
-rw-r--r-- 1 root root 0 Aug 27 14:21 adduser
srw-rw---- 1 root jenkins 0 Aug 28 12:35 docker.sock
drwxrwxrwt 2 root root 4096 Aug 12 00:00 lock
확인 결과 1001 그룹으로 되어있어서 1000 그룹인 jenkins에게 소켓 권한이 없는것으로 판단하였고,
chgrp 1000 docker.sock
명령어로 소켓 파일의 권한을 변경하고 해결이 되었다
그치만.......
1001 그룹은 도커 설치 시, docker 그룹이 생성되고 그 docker 그룹이 1001이라서 바꾸면 안 됐다..
앞으로는 root권한이 필요한 경우 privileged 옵션을 주도록 하자