Docker-in-Docker에서 레지스트리 인증하기

Docker-in-Docker에서 레지스트리 인증하기 (Authenticate with registry in Docker-in-Docker)

Docker-in-Docker를 쓸 때는 표준 인증 방법이 동작하지 않아요. 서비스와 함께 새 Docker 데몬이 뜨기 때문인데요, 이 상황에서 쓸 수 있는 인증 방법 세 가지를 살펴볼게요.

출처: 문서

본문

방법 1: docker login 실행 (Option 1: Run docker login)

before_script에서 docker login을 실행하면 돼요.

default:
  image: docker:24.0.5-cli
  services:
    - docker:24.0.5-dind

variables:
  DOCKER_TLS_CERTDIR: "/certs"

build:
  stage: build
  before_script:
    - echo "$DOCKER_REGISTRY_PASS" | docker login $DOCKER_REGISTRY --username $DOCKER_REGISTRY_USER --password-stdin
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests

Docker Hub에 로그인하려면 $DOCKER_REGISTRY를 비워 두거나 제거하면 돼요.

방법 2: 각 job에 ~/.docker/config.json 마운트 (Option 2: Mount ~/.docker/config.json on each job)

GitLab Runner 관리자라면 인증 설정이 담긴 파일을 ~/.docker/config.json에 마운트할 수 있어요. 그러면 러너가 처리하는 모든 job이 이미 인증된 상태로 시작됩니다. 공식 docker:24.0.5 이미지를 쓰고 있다면 홈 디렉터리는 /root 아래에 있어요.

주의할 점이 하나 있어요. 구성 파일을 마운트하면 ~/.docker/config.json을 수정하는 docker 명령은 실패합니다. 예를 들어 docker login은 파일이 읽기 전용으로 마운트되어 있어서 실패해요. 이 파일을 읽기 전용에서 바꾸면 문제가 생기니 건드리지 마세요.

다음은 DOCKER_AUTH_CONFIG 문서를 따른 /opt/.docker/config.json 예시입니다.

{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
        }
    }
}

Docker 환경

volume mounts에 이 파일을 포함하도록 수정합니다.

[[runners]]
  ...
  executor = "docker"
  [runners.docker]
    ...
    privileged = true
    volumes = ["/opt/.docker/config.json:/root/.docker/config.json:ro"]

Kubernetes 환경

이 파일의 내용으로 ConfigMap을 생성합니다. 다음과 같은 명령으로 만들 수 있어요.

kubectl create configmap docker-client-config --namespace gitlab-runner --from-file /opt/.docker/config.json

그리고 volume mounts에 이 파일을 포함하도록 수정합니다.

[[runners]]
  ...
  executor = "kubernetes"
  [runners.kubernetes]
    image = "alpine:3.12"
    privileged = true
    [[runners.kubernetes.volumes.config_map]]
      name = "docker-client-config"
      mount_path = "/root/.docker/config.json"
      sub_path = "config.json"

방법 3: DOCKER_AUTH_CONFIG 사용 (Option 3: Use DOCKER_AUTH_CONFIG)

이미 DOCKER_AUTH_CONFIG를 정의해 두었다면 이 변수를 활용해서 ~/.docker/config.json에 저장하면 돼요. 이 인증은 여러 곳에서 정의할 수 있습니다.

다음 예시는 before_script를 보여줘요. 어떤 방식으로 구현하든 적용되는 명령은 동일합니다.

default:
  image: docker:24.0.5-cli
  services:
    - docker:24.0.5-dind

variables:
  DOCKER_TLS_CERTDIR: "/certs"

build:
  stage: build
  before_script:
    - mkdir -p $HOME/.docker
    - echo $DOCKER_AUTH_CONFIG > $HOME/.docker/config.json
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests

더 알아보기

Docker-in-Docker 환경에서는 프라이빗 레지스트리 인증이 기본 방식으로 안 풀리는 경우가 많아요. 상황에 따라 docker login을 매 job에서 실행하거나, 러너 수준에서 설정 파일을 마운트하거나, DOCKER_AUTH_CONFIG 변수를 쓰는 방법 중 하나를 고르면 됩니다. 그다음으로는 Docker 레이어 캐시를 함께 설정하면 빌드 속도를 크게 줄일 수 있어요.