개요

이 글은 다음 내용을 포함 함.

  • mac 환경에서 docker가 설치된 jenkins 컨테이너 이미지 만들기
  • jenkins 컨테이너 내부에서 docker 명령 수행 시 permission denied 발생시 조치 방안

docker를 갖는 jenkins 이미지 작성

  • 컨테이너 기반 jenkins에서 docker 커멘드를 실행하려면 아래 두 가지 수행 필요
    1. docker가 설치된 jenkins 이미지를 작성
    2. /var/run/docker.sock 을 host에 설치된 /var/run/docker.sock과 볼륨 마운트

dockerfile 작성

  • 기본 jenkins 이미지에 docker 설치 커멘드를 포함 한 dockerfile 작성
  • 참고로 아래 dockerfile은 debian os 기반 docker 설치 커멘드로 다른 os관련 내용은 아래 참고
  • Install on CentOS
  • Install on Fedora
  • Install on Ubuntu
  • Dockerfile

     FROM jenkins/jenkins:2.263.1-lts-jdk11
    
     USER root
     RUN apt-get -y update && \ 
         apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common && \
         curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
         add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" && \
         apt-get -y update && \ 
         apt-get -y install docker-ce docker-ce-cli containerd.io
     USER jenkins
    

docker-compose.yml 작성

  • docker-compose를 통해 jenkins 컨테이너 기동 시 컨테이너와 호스트 간 /var/run/docker.sock 볼륨 마운트 되도록 스크립트 작성 함
  • docker-compose.yml
     version: '3.1'
     services:
       summit-jenkins:
         container_name: summit-jenkins
         image: jacob:1.0.0
         ports:
            - 6060:8080
            - 50000:50000
         environment:
            - "JAVA_OPTS=-Xmx4G -Xms2G"
         volumes:
            - ~/mount/jenkins:/var/jenkins_home
            - /var/run/docker.sock:/var/run/docker.sock #<-컨테이너와 호스트간 /var/run/docker.sock 마운트
         restart: always
    

현상

  • jenkins 컨테이너 내부에서 빌드 완료된 artifact를 dockerfile로 컨테이너 이미지로 만들기 위해 docker 커멘드 실행
  • 참고로 파이프라인 생성을 위해 jenkinsfile에서 수행 함

       <생략> 
       stage("Docker Build & Push") {
           steps {
               script {
                   sh("docker login registry.gitlab.com -u sftth -p gw170104@u")
                   sh("docker build -t registry.gitlab.com/sftth-modern-group/whms:1.0.0 .")
                   sh("docker push registry.gitlab.com/sftth-modern-group/whms:1.0.0")
               }
           }
       } 
       <생략> 
    
  • jenkins 컨테이너 내부에서 docker 명령어 실행 시 permission denied 발생

    <생략>
    + docker login registry.gitlab.com -u sftth -p gw170104@u
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    Got permission denied while trying to connect to the Docker daemon socket 
    at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.24/auth: 
    dial unix /var/run/docker.sock: connect: permission denied
    <생략> 
    

원인

  • permission denied의 원인은 다음 두 가지 조건 때문임
    1. jenkins 컨테이너 내부에서는 jenkins 계정으로 작업을 수행하는데 jenkins 계정은 docker 명령을 수행할 권한이 없음
    2. jenkins 계정으로 docker를 수행할 수 없는 이유는 jenkins 내에 /var/run/docker.sock 이 root 계정에만 실행 권한을 갖기 때문

해결책

  1. Host 즉, Mac에서 docker desktop을 설치하면 기존 사용자로 sudo 입력 없이 docker 명령어를 사용할 수 있음
  2. 그래서 Jenkins 컨테이너 내부에 jenkins 계정의 UID를 Host 사용자 UID로 변경 시킴

  3. Jenkins 컨테이너 내부 docker 그룹의 GID를 Host의 docker 그룹 GID와 일치 시켜서 해결

해결책의 문제점

  • 위에서 제시한 방법을 mac 환경에서 수행하기에 몇가지 문제점이 있음
  1. Host 내 계정의 UID와 docker 그룹의 GID를 알아야 함
  2. Mac에서 계정의 UID는 확인 가능하지만 docker 그룹의 GID 확인이 어려움
  3. 실제 jenkins 컨테이너 내부 docker 그룹의 GID를 Host 의 /var/run/docker.sock 실행 권한을 갖는 그룹 GID로 바꾸려니 충돌 발생

나름 나의 해결책

  • 작업을 하다보니 jenkins 컨테이너에 root로 접속하여 아래 명령어를 수행하니 해결 됨

     Host $ docker exec -it -u root ${jenkins-container-name} /bin/bash
     컨테이너 내부(root) $ chown jenkins:jenkins /var/run/docker.sock
    
  • 위 해겨책에 맞게 dockerfile을 수정함

     FROM jenkins/jenkins:2.263.1-lts-jdk11
    
     USER root
     RUN apt-get -y update && \ 
         apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common && \
         curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
         add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" && \
         apt-get -y update && \ 
         apt-get -y install docker-ce docker-ce-cli containerd.io
     RUN if [ -e /var/run/docker.sock ]; then chown jenkins:jenkins /var/run/docker.sock; fi #<-- 권한 변경 추가 
     USER jenkins
    

Docker inside Docker for Jenkins Permission Denied 해결 참고 Dockerfile 참고 Dockerfile에 chown 구문 참

태그:

카테고리:

업데이트:

댓글남기기