이것이 점프 투 공작소

Docker out of Docker(DooD)로 컨테이너 내부에서 도커 사용하기 /var/run/docker.sock 에러 본문

도커

Docker out of Docker(DooD)로 컨테이너 내부에서 도커 사용하기 /var/run/docker.sock 에러

겅겅겅 2023. 5. 27. 20:51

gitlab-ci를 이용한 CICD 파이프라인을 만드는 중 gitlab-runner 컨테이너에서 호스트의 도커 명령어를 사용해야하는 상황이 생겼습니다.

그 과정에서 제가 만났던 문제와 해결 방법을 포스팅하려고합니다.

 

도커의 구조 (Client, Daemon, Registry)

컨테이너 내부에서 도커를 사용하려면 도커의 구조에 대해 알아야합니다.

도커는 도커 명령어를 실행하는 클라이언트, 실제 도커가 실행되는 프로세스가 되는 도커데몬, 도커이미지를 저장하는 레지스트리로 구성되어져 있습니다.

DooD 방법을 사용하려면 도커 클라이언트와 도커 데몬(Host)의 관계에 대해서 알아야합니다.

도커 클라이언트

실행 가능한 파일이나 명령어를 조회하는 which 명령어로 도커를 조회해보면 /usr/bin/docker 파일을 통해 도커 명령어가 실행되고 있음을 알 수 있습니다.

우리가 도커 명령어로 사용하는 모든 명령어들은 /usr/bin/docker 에 존재하는 파일에 의해 인식되고,

도커 클라이언트는 /run/docker.sock 라는 유닉스 소켓을 통해 도커데몬의 API를 호출하여 요청을 전달합니다.

 ( OS에 따라 유닉스 소켓은 /var/run/docker.sock에 있을수도 있습니다. ) 

도커 데몬

실제 도커의 컨테이너, 볼륨, 네트워크 등 리소스를 관리하는 프로세스는 모두 /usr/bin/dockerd 라는 프로세스로서 동작하고있습니다.

도커 데몬은 클라이언트의 요청을 받아 처리합니다.

컨테이너에서 도커를 사용하려면?

위에서 살펴봤듯이 도커는 클라이언트와 데몬 두가지로 나뉘어져있으며,

도커 컨테이너 내에서 도커 데몬을 추가로 동작시키는 Docker in Docker 방식과

컨테이너 내에서 호스트의 docker.sock 파일을 공유하는 Docker out of Docker 방식이 있습니다.

Docker in Docker

$ docker run --privileged --name dind1 -d docker:1.8-dind

docker in docker 방식을 사용하려면 컨테이너 안에서 호스트의 모든 기능을 하용 할 수 있도록 하는 --privileged 옵션을 사용하여 도커를 실행시켜야합니다.

하지만 컨테이너가 host와 거의 동등한 권한을 가지기에 도커에서 추천하는 방식이 아니기에 Docker out of Docker 방식이 더 선호됩니다.

Docker out of Docker

도커는 클라이언트와 데몬이 나뉘어져 있습니다. 이를 이용하여 호스트에 존재하는 docker.sock 을 -v 옵션으로 컨테이너에 공유하여 사용함으로서 컨테이너 내에서 도커 명령어를 사용 할 수 있도록 합니다.

저는 깃 러너를 Docker in Docker 로 실행시켰습니다.

docker run --detach \
--name gitlab-runner \
--restart always \
--volume /srv/gitlab-runner/config:/etc/gitlab-runner: \
--volume /var/run/docker.sock:/var/run/docker.sock \ # Docker in Docker 를 사용하기 위한 볼륨
gitlab/gitlab-runner:latest

DooD로 컨테이너를 사용하던 중 발생한 에러 

Docker in Docker로 컨테이너를 실행하였는데도 gitlab에서 cicd 파이프라인에서 도커 클라이언트의 실행 권한이 없다는 에러가 발생하였습니다.

도커를 사용하다보면 정말 자주 볼 수 있는 메세지있는 것 같습니다..

게다가 깃랩에서 cicd를 사용할때 기본적으로 gitlab-runner서버에서 gitlab-runner 라는 사용자로 작업을 진행하게됩니다.

그러니 'git-runner 컨테이너에 gitlab-runner라는 사용자가 도커 클라이언트에 대한 사용 권한이 없다' 라고 생각이 들었습니다.

분명 DooD로 도커 클라이언트를 공유 한다고 되었는데 왜 실행권한이 없다는건지 확인해보겠습니다.

깃랩 cicd 중 발생한 에러

사용권한을 어떻게 확인하고 줄 수 있을까?

컨테이너에서 docker.sock 파일 확인

먼저 컨테이너 안에서 ls -l /run 명령어로 실행중인 프로세스에 대해 조회해 보았습니다.

docker.sock 파일의 group이 994로 되어있습니다.

 

깃랩 컨테이너 내에서 docker.sock 조회

이 그룹아이디 944가 어떤 group인지 host에서 group-id를 확인해보면

호스트에서 도커라는 그룹의 group-id라는걸 확인 할 수 있습니다.

도커 host의 group id 조회

즉 컨테이너 내에서 host의 group-id만 사용하고 있을 뿐 group자체와 필요한 group의 사용자(gitlab-runner)가 존재하지 않기에 발생하는 오류입니다.

컨테이너에서 사용자 그룹 및 사용자 추가

컨테이너 내부에서 host에 존재하는 동일한 사용자 그룹을 만들고 Docker클라이언트 실행권한이 필요한 gitlab-runner라는 유저를 그룹에 추가시켜줍니다.

groupadd docker # 도커라는 그룹 추가
groupmod -g 944 docker # 컨테이너의 도커그룹에 host의 도커 그룳과 동일한 gid 지정
usermod -aG docker gitlab-runner # 사용자 추가

추가 후 컨테이너의 group확인해보면 사용자도 추가되어있고, docker.sock의 그룹id는 docker로 변경되어있는걸 확인 할 수 있습니다.

컨테이너에서 group 및 사용자 추가

다시 gitlab pipeline 실행

권한 추가 후 문제없이 DooD가 동작합니다!

docker 사용 성공