Docker Build 문제 해결
Docker Build 문제 해결
GitLab CI에서 Docker 이미지를 빌드하다 보면 "Docker daemon에 연결할 수 없다", "인증서를 검증하지 못했다" 같은 오류를 자주 만나게 돼요. 특히 Docker-in-Docker(dind)를 사용할 때 이런 문제가 잘 생기죠. 이 글은 Docker Build와 관련해 겪는 대표적인 오류들을 모아, 각각 어떤 상황에서 발생하고 어떻게 해결하는지 설명할게요.
출처: 문서
본문
오류: docker: Cannot connect to the Docker daemon at tcp://docker:2375
이 오류는 Docker-in-Docker v19.03 이상을 사용할 때 흔합니다.
docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
이 오류는 Docker가 자동으로 TLS로 시작되기 때문에 발생해요.
- 처음 설정하는 경우라면 Docker 이미지로 Docker executor 사용하기를 참고하세요.
- v18.09 이하에서 업그레이드하는 경우라면 업그레이드 가이드를 참고하세요.
이 오류는 Kubernetes executor에서 Docker-in-Docker 서비스가 완전히 시작되기 전에 접근하려 할 때도 발생할 수 있어요. 더 자세한 설명은 이슈 27215를 참고하세요.
Docker no such host 오류
docker: error during connect: Post https://docker:2376/v1.40/containers/create: dial tcp: lookup docker on x.x.x.x:53: no such host 같은 오류를 볼 수 있어요.
이 문제는 서비스의 이미지 이름에 레지스트리 호스트 이름이 포함될 때 발생할 수 있어요. 예를 들어:
default:
image: docker:24.0.5-cli
services:
- registry.hub.docker.com/library/docker:24.0.5-dind
서비스의 호스트 이름은 전체 이미지 이름에서 파생돼요. 하지만 서비스 호스트 이름 docker가 더 짧은 형태로 기대됩니다. 서비스 해석과 접근을 허용하려면 서비스 이름 docker에 명시적 별칭을 추가하세요.
default:
image: docker:24.0.5-cli
services:
- name: registry.hub.docker.com/library/docker:24.0.5-dind
alias: docker
오류: Cannot connect to the Docker daemon at unix:///var/run/docker.sock
dind 서비스에 접근하는 docker 명령을 실행하려 할 때 다음 오류가 보일 수 있어요.
$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
job에 다음 환경 변수가 정의되어 있는지 확인하세요.
- DOCKER_HOST
- DOCKER_TLS_CERTDIR (선택)
- DOCKER_TLS_VERIFY (선택)
Docker 클라이언트를 제공하는 이미지도 업데이트하고 싶을 수 있어요. 예를 들어 docker/compose 이미지는 더 이상 사용되지 않으며 docker로 교체해야 합니다.
러너 이슈 30944에 설명된 대로, 이 오류는 job이 이전에 사용되지 않는 Docker --link 파라미터에서 파생된 DOCKER_PORT_2375_TCP 같은 환경 변수에 의존했다면 발생할 수 있어요. 다음 경우에 job이 이 오류로 실패합니다.
- CI/CD 이미지가
DOCKER_PORT_2375_TCP같은 레거시 변수에 의존하는 경우 - 러너 기능 플래그 FF_NETWORK_PER_BUILD가
true로 설정된 경우 - DOCKER_HOST가 명시적으로 설정되지 않은 경우
오류: unauthorized: incorrect username or password
이 오류는 사용되지 않는 변수인 CI_BUILD_TOKEN을 사용할 때 나타나요.
Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: incorrect username or password
이 오류가 사용자에게 나타나지 않게 하려면:
- CI_JOB_TOKEN을 대신 사용하세요.
gitlab-ci-token/CI_BUILD_TOKEN에서$CI_REGISTRY_USER/$CI_REGISTRY_PASSWORD로 바꾸세요.
연결 중 오류: no such host
이 오류는 dind 서비스가 시작에 실패했을 때 나타나요.
error during connect: Post "https://docker:2376/v1.24/auth": dial tcp: lookup docker on 127.0.0.11:53: no such host
job 로그에 mount: permission denied (are you root?)가 나타나는지 확인하세요. 예를 들어:
Service container logs:
2023-08-01T16:04:09.541703572Z Certificate request self-signature ok
2023-08-01T16:04:09.541770852Z subject=CN = docker:dind server
2023-08-01T16:04:09.556183222Z /certs/server/cert.pem: OK
2023-08-01T16:04:10.641128729Z Certificate request self-signature ok
2023-08-01T16:04:10.641173149Z subject=CN = docker:dind client
2023-08-01T16:04:10.656089908Z /certs/client/cert.pem: OK
2023-08-01T16:04:10.659571093Z ip: can't find device 'ip_tables'
2023-08-01T16:04:10.660872131Z modprobe: can't change directory to '/lib/modules': No such file or directory
2023-08-01T16:04:10.664620455Z mount: permission denied (are you root?)
2023-08-01T16:04:10.664692175Z Could not mount /sys/kernel/security.
2023-08-01T16:04:10.664703615Z AppArmor detection and --privileged mode might break.
2023-08-01T16:04:10.665952353Z mount: permission denied (are you root?)
이것은 GitLab Runner가 dind 서비스를 시작할 권한이 없음을 나타냅니다.
config.toml에privileged = true가 설정되어 있는지 확인하세요.- CI job이 이 privileged 러너를 사용할 수 있는 올바른 Runner tags를 가지고 있는지 확인하세요.
오류: cgroups: cgroup mountpoint does not exist: unknown
Docker Engine 20.10에서 도입된 알려진 비호환성이 있어요.
호스트가 Docker Engine 20.10 이상을 사용할 때, 20.10보다 오래된 버전의 docker:dind 서비스는 예상대로 동작하지 않습니다.
서비스 자체는 문제없이 시작되지만, 컨테이너 이미지를 빌드하려 하면 다음 오류가 발생합니다.
cgroups: cgroup mountpoint does not exist: unknown
이 문제를 해결하려면 docker:dind 컨테이너를 최소 20.10.x 버전(예: docker:24.0.5-dind)으로 업데이트하세요.
반대 구성(docker:24.0.5-dind 서비스와 19.06.x 이하 버전의 호스트 Docker Engine)은 문제없이 동작합니다. 가장 좋은 전략은 job 환경 버전을 자주 테스트하고 최신 버전으로 업데이트하는 것이에요. 그러면 새 기능과 개선된 보안을 얻을 수 있고, 이 특정 경우에는 러너 호스트의 기본 Docker Engine 업그레이드가 job에 투명하게 적용됩니다.
오류: failed to verify certificate: x509: certificate signed by unknown authority
커스텀 또는 프라이빗 인증서(예: Zscaler 인증서)를 사용하는 Docker-in-Docker 환경에서 docker build나 docker pull 같은 Docker 명령을 실행하면 이 오류가 나타날 수 있어요.
error pulling image configuration: download failed after attempts=6: tls: failed to verify certificate: x509: certificate signed by unknown authority
이 오류는 Docker-in-Docker 환경의 Docker 명령이 두 개의 분리된 컨테이너를 사용하기 때문에 발생합니다.
- 빌드 컨테이너는 Docker 클라이언트(
/usr/bin/docker)를 실행하고 job의 스크립트 명령을 실행해요. - 서비스 컨테이너 (종종
svc로 불림)는 대부분의 Docker 명령을 처리하는 Docker 데몬을 실행해요.
조직에서 커스텀 인증서를 사용하면 두 컨테이너 모두 이 인증서가 필요합니다. 두 컨테이너 모두에 올바른 인증서 구성이 없으면 외부 레지스트리나 서비스에 연결하는 Docker 작업이 인증서 오류로 실패합니다.
이 문제를 해결하려면:
루트 인증서를 CA_CERTIFICATE라는 CI/CD 변수로 저장하세요. 인증서는 다음 형식이어야 합니다.
-----BEGIN CERTIFICATE-----
(certificate content)
-----END CERTIFICATE-----
Docker 데몬을 시작하기 전에 서비스 컨테이너가 인증서를 설치하도록 파이프라인을 구성하세요. 예를 들어:
image_build:
stage: build
image:
name: docker:19.03
variables:
DOCKER_HOST: tcp://localhost:2375
DOCKER_TLS_CERTDIR: ""
CA_CERTIFICATE: "$CA_CERTIFICATE"
services:
- name: docker:19.03-dind
command:
- /bin/sh
- -c
- |
echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/custom-ca.crt && \
update-ca-certificates && \
dockerd-entrypoint.sh || exit
script:
- docker info
- docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY
- docker build -t "${DOCKER_REGISTRY}/my-app:${CI_COMMIT_REF_NAME}" .
- docker push "${DOCKER_REGISTRY}/my-app:${CI_COMMIT_REF_NAME}"
더 알아보기 (Learn more)
Docker-in-Docker의 기본 사용법이 궁금하다면 Docker 이미지로 Docker executor 사용하기 문서를, CI job 토큰으로 레지스트리 인증을 설정하는 방법은 CI job 토큰 문서를 참고하세요.