- CI/CD 작업에서 Docker 명령 활성화하기
- Docker-in-Docker에서 레지스트리로 인증
- Docker 레이어 캐싱을 사용하여 Docker-in-Docker 빌드 가속화
- OverlayFS 드라이버 사용
- Docker 대체 옵션
- GitLab 컨테이너 레지스트리 사용
-
문제 해결
docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
- Docker
no such host
오류 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
- 오류:
unauthorized: incorrect username or password
- 오류 중 connect 중:
no such host
- 오류:
cgroups: cgroup mountpoint does not exist: unknown
Docker 이미지 빌드에 Docker 사용하기
Tier: Free, Premium, Ultimate
Offering: GitLab.com, Self-Managed, GitLab Dedicated
GitLab CI/CD와 Docker를 사용하여 Docker 이미지를 만들 수 있습니다. 예를 들어, 애플리케이션의 Docker 이미지를 생성하고 테스트한 후, 컨테이너 레지스트리에 푸시할 수 있습니다.
CI/CD 작업에서 Docker 명령을 실행하려면 GitLab Runner를 docker
명령을 지원하도록 구성해야 합니다. 이 방법은 privileged
모드를 필요로 합니다.
러너(runner)에서 privileged
모드를 사용하지 않고 Docker 이미지를 빌드하려면 Docker 대안을 사용할 수 있습니다.
CI/CD 작업에서 Docker 명령 활성화하기
CI/CD 작업에서 Docker 명령을 활성화하려면 다음을 사용할 수 있습니다.
The shell executor 사용하기
CI/CD 작업에서 Docker 명령을 포함하려면 러너를 shell
executor로 구성할 수 있습니다. 이 구성에서는 gitlab-runner
사용자가 Docker 명령을 실행하지만 이를 위한 권한이 필요합니다.
- GitLab Runner을 설치합니다.
-
러너를 등록합니다.
shell
executor를 선택합니다. 예:sudo gitlab-runner register -n \ --url "https://gitlab.com/" \ --registration-token REGISTRATION_TOKEN \ --executor shell \ --description "My Runner"
-
GitLab Runner가 설치된 서버에서 Docker Engine을 설치합니다. 지원되는 플랫폼 디렉터리을 확인합니다.
-
gitlab-runner
사용자를docker
그룹에 추가합니다.sudo usermod -aG docker gitlab-runner
-
gitlab-runner
가 Docker에 접근할 수 있는지 확인합니다.sudo -u gitlab-runner -H docker info
-
GitLab에서
.gitlab-ci.yml
에docker info
를 추가하여 Docker가 작동하는지 확인합니다.default: before_script: - docker info build_image: script: - docker build -t my-docker-image . - docker run my-docker-image /script/to/run/tests
이제 필요한 경우 docker
명령을 사용할 수 있습니다. 필요한 경우 Docker Compose도 설치할 수 있습니다.
gitlab-runner
를 docker
그룹에 추가하면 사실상 gitlab-runner
에게 완전한 루트 권한을 부여하게 됩니다.
자세한 내용은 docker 그룹의 보안을 참조하세요.
Docker-in-Docker 사용하기
“Docker-in-Docker”(dind
)란 다음을 의미합니다.
- 등록된 러너가 Docker executor 또는 Kubernetes executor를 사용합니다.
- Executor는 Docker의 컨테이너 이미지를 사용하여 CI/CD 작업을 실행합니다.
Docker 이미지에는 모든 docker
도구가 포함되어 있으며 작업 스크립트를 특권 모드에서 실행할 수 있습니다.
TLS를 활성화된 Docker-in-Docker를 사용해야 합니다. 이는 GitLab.com 인스턴스 러너에서 지원됩니다.
항상 docker:24.0.5
와 같이 특정 버전의 이미지를 지정해야 합니다.
docker:latest
와 같은 태그를 사용하면 사용되는 버전을 제어할 수 없습니다.
이로 인해 새 버전이 출시될 때 호환성 문제가 발생할 수 있습니다.
Docker executor와 TLS 활성화된 Docker-in-Docker 사용하기
- GitLab Runner 11.11에서 도입됨.
Docker 데몬은 TLS를 통한 연결을 지원합니다. TLS는 Docker 19.03.12 이상에서 기본 설정입니다.
--docker-privileged
를 활성화하여 컨테이너의 보안 메커니즘을 비활성화하고 호스트를 특권 상승에 노출시킵니다. 이 조치는 컨테이너 탈출을 유발할 수 있습니다. 자세한 내용은 runtime privilege and Linux capabilities을 참조하세요.TLS 활성화된 Docker-in-Docker를 사용하려면 다음을 수행합니다:
- GitLab Runner를 설치합니다.
-
명령줄에서 GitLab Runner를 등록합니다.
docker
와privileged
모드를 사용합니다.sudo gitlab-runner register -n \ --url "https://gitlab.com/" \ --registration-token REGISTRATION_TOKEN \ --executor docker \ --description "My Docker Runner" \ --docker-image "docker:24.0.5" \ --docker-privileged \ --docker-volumes "/certs/client"
- 이 명령은 빌드 및 서비스 컨테이너 시작에
privileged
모드를 사용하여docker:24.0.5
이미지를 사용하는 새 러너를 등록합니다. Docker-in-Docker를 사용하려면 Docker 컨테이너에서 항상privileged = true
를 사용해야 합니다. - 이 명령은 Docker 클라이언트가 해당 디렉터리의 인증서를 사용하도록 하기 위해 서비스 및 빌드 컨테이너에
/certs/client
을 마운트합니다. 자세한 내용은 Docker 이미지 문서를 참조하세요.
이전 명령은 다음 예와 유사한
config.toml
항목을 생성합니다:[[runners]] url = "https://gitlab.com/" token = TOKEN executor = "docker" [runners.docker] tls_verify = false image = "docker:24.0.5" privileged = true disable_cache = false volumes = ["/certs/client", "/cache"] [runners.cache] [runners.cache.s3] [runners.cache.gcs]
- 이 명령은 빌드 및 서비스 컨테이너 시작에
-
이제 작업 스크립트에서
docker
를 사용할 수 있습니다.docker:24.0.5-dind
서비스를 포함해야 합니다.default: image: docker:24.0.5 services: - docker:24.0.5-dind before_script: - docker info variables: # dind 서비스를 사용하는 경우 Docker에 서비스 내부에서 시작된 데몬과 통신하도록 Docker에 지시해야 합니다. 데몬은 기본 설정인 /var/run/docker.sock 소켓 대신 네트워크 연결로 사용할 수 있습니다. # Docker 19.03은 이를 자동으로 수행합니다. DOCKER_TLS_CERTDIR: "/certs" build: stage: build script: - docker build -t my-docker-image . - docker run my-docker-image /script/to/run/tests
TLS 비활성화된 Docker 실행기에서의 Docker-in-Docker
가끔씩 TLS를 비활성화해야 하는 합당한 이유가 있습니다. 예를 들어 사용 중인 GitLab Runner 구성을 제어할 수 없을 때입니다.
실행기의 config.toml
이 다음과 유사한 경우를 가정합니다:
[[runners]]
url = "https://gitlab.com/"
token = TOKEN
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:24.0.5"
privileged = true
disable_cache = false
volumes = ["/cache"]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
이제 작업 스크립트에서 docker
를 사용할 수 있습니다. docker:24.0.5-dind
서비스를 포함해야 합니다:
default:
image: docker:24.0.5
services:
- docker:24.0.5-dind
before_script:
- docker info
variables:
# dind 서비스를 사용하는 경우 Docker에 서비스 내부에서 시작된 데몬과 통신하도록 지시해야 합니다.
# 기본 /var/run/docker.sock 소켓 대신 네트워크 연결로 데몬에 액세스할 수 있습니다.
#
# 'docker' 호스트명은
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services에서 설명된 서비스 컨테이너의 별칭입니다.
#
# Kubernetes 실행기 및 Kubernetes 1.6 이전을 사용하는 GitLab Runner 12.7 이전의 경우
# 작업 컨테이너에 서비스를 연결하는 방식으로 인해 변수는 tcp://localhost:2375로 설정해야 합니다.
# DOCKER_HOST: tcp://localhost:2375
#
DOCKER_HOST: tcp://docker:2375
#
# Docker에 TLS를 사용하지 않도록 지시합니다.
DOCKER_TLS_CERTDIR: ""
build:
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
Docker-in-Docker에서 Kubernetes 실행기 사용
Kubernetes 실행기를 사용하여 Docker 컨테이너에서 작업을 실행할 수 있습니다.
TLS가 활성화된 Kubernetes에서 Docker-in-Docker 사용
- GitLab Runner Helm Chart 0.23.0에서 도입되었습니다.
Kubernetes에서 TLS가 활성화된 Docker-in-Docker를 사용하려면 다음을 수행해야 합니다:
-
Helm 차트를 사용하여
values.yml 파일
을 업데이트하여 볼륨 마운트를 지정합니다.runners: config: | [[runners]] [runners.kubernetes] image = "ubuntu:20.04" privileged = true [[runners.kubernetes.volumes.empty_dir]] name = "docker-certs" mount_path = "/certs/client" medium = "Memory"
-
이제 작업 스크립트에서
docker
를 사용할 수 있습니다.docker:24.0.5-dind
서비스를 포함해야 합니다:default: image: docker:24.0.5 services: - docker:24.0.5-dind before_script: - docker info variables: # dind 서비스를 사용하는 경우 Docker가 서비스 내부에서 시작된 데몬과 통신하도록 지시해야 합니다. # 기본 /var/run/docker.sock 소켓 대신 네트워크 연결로 데몬에 액세스할 수 있습니다. DOCKER_HOST: tcp://docker:2376 # # 'docker' 호스트명은 # https://docs.gitlab.com/ee/ci/services/#accessing-the-services에서 설명된 서비스 컨테이너의 별칭입니다. # Kubernetes 실행기 및 Kubernetes 1.6 이전을 사용하는 GitLab Runner 12.7 이전의 경우 # 작업 컨테이너에 서비스를 연결하는 방식으로 인해 변수는 tcp://localhost:2376로 설정해야 합니다. # DOCKER_HOST: tcp://localhost:2376 # # Docker에게 인증서를 생성할 위치를 지정합니다. Docker는 부팅 시 자동으로 인증서를 생성하고 # /certs/client를 만들어 서비스와 작업 컨테이너 간에 공유할 수 있도록 합니다. 이는 config.toml에서 # 볼륨 마운트를 통해 가능해집니다. DOCKER_TLS_CERTDIR: "/certs" # 일반적으로 entrypoint에서 지정하지만 Kubernetes 실행기는 entrypoint를 실행하지 않습니다. # https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125 DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" build: stage: build script: - docker build -t my-docker-image . - docker run my-docker-image /script/to/run/tests
TLS가 비활성화된 Kubernetes에서 Docker-in-Docker 사용
Kubernetes에서 TLS가 비활성화된 Docker-in-Docker를 사용하려면 위의 예시를 다음과 같이 수정해야 합니다:
-
values.yml
파일에서[[runners.kubernetes.volumes.empty_dir]]
섹션을 삭제합니다. -
DOCKER_HOST: tcp://docker:2376
로 포트를2375
로 변경합니다. -
DOCKER_TLS_CERTDIR: ""
로 TLS를 비활성화하도록 Docker에 지시합니다.
예시:
-
Helm 차트를 사용하여
values.yml 파일
을 업데이트합니다:runners: config: | [[runners]] [runners.kubernetes] image = "ubuntu:20.04" privileged = true
-
이제 작업 스크립트에서
docker
를 사용할 수 있습니다.docker:24.0.5-dind
서비스를 포함해야 합니다:default: image: docker:24.0.5 services: - docker:24.0.5-dind before_script: - docker info variables: # dind 서비스를 사용하는 경우 Docker가 서비스 내부에서 시작된 데몬과 통신하도록 지시해야 합니다. # 기본 /var/run/docker.sock 소켓 대신 네트워크 연결로 데몬에 액세스할 수 있습니다. DOCKER_HOST: tcp://docker:2375 # # 'docker' 호스트명은 # https://docs.gitlab.com/ee/ci/services/#accessing-the-services에서 설명된 서비스 컨테이너의 별칭입니다. # Kubernetes 실행기 및 Kubernetes 1.6 이전을 사용하는 GitLab Runner 12.7 이전의 경우 # 작업 컨테이너에 서비스를 연결하는 방식으로 인해 변수는 tcp://localhost:2376로 설정해야 합니다. # DOCKER_HOST: tcp://localhost:2376 # # Docker에 TLS를 사용하지 않도록 지시합니다. DOCKER_TLS_CERTDIR: "" build: stage: build script: - docker build -t my-docker-image . - docker run my-docker-image /script/to/run/tests
Docker-in-Docker에서 알려진 문제
Docker-in-Docker는 권장 구성이지만 다음과 같은 문제를 유념해야 합니다:
-
docker-compose
명령어: 기본적으로 이 명령이 이 구성에서는 사용할 수 없습니다. 작업 스크립트에서docker-compose
를 사용하려면 Docker Compose 설치 지침을 따르세요. - 캐시: 각 작업은 새로운 환경에서 실행됩니다. 모든 빌드는 자체 Docker 엔진 인스턴스를 얻기 때문에 동시 작업은 충돌을 일으키지 않습니다. 그러나 계층을 캐싱하지 않기 때문에 작업이 느릴 수 있습니다. Docker 계층 캐싱을 참조하세요(#make-docker-in-docker-builds-faster-with-docker-layer-caching).
-
저장 드라이버: 기본적으로, 이전 버전의 Docker는 각 작업에 대해 파일 시스템을 복사하는
vfs
저장 드라이버를 사용합니다. Docker 17.09 이후로는 권장하는 저장 드라이버인--storage-driver overlay2
를 사용합니다. 자세한 내용은 OverlayFS 드라이버 사용를 참조하십시오. -
루트 파일 시스템:
docker:24.0.5-dind
컨테이너와 러너 컨테이너가 루트 파일 시스템을 공유하지 않기 때문에, 작업 디렉터리를 하위 컨테이너의 마운트 지점으로 사용할 수 있습니다. 예를 들어, 하위 컨테이너와 공유하려는 파일이 있다면,/builds/$CI_PROJECT_PATH
아래에 하위 디렉터리를 생성하고 이를 마운트 지점으로 사용할 수 있습니다. 더 자세한 설명은 이슈 #41227를 참조하세요.
variables:
MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt
script:
- mkdir -p "$MOUNT_POINT"
- docker run -v "$MOUNT_POINT:/mnt" my-docker-image
Docker 소켓 바인딩을 사용한 도커 실행기 사용
CI/CD 작업에서 도커 명령어를 사용하려면 /var/run/docker.sock
을 컨테이너에 바인딩하면 됩니다. 그러면 도커가 이미지의 컨텍스트에서 사용할 수 있습니다.
도커 소켓을 바인딩하고 있고 GitLab Runner 11.11 이상을 사용하면 docker:24.0.5-dind
를 서비스로 더 이상 사용할 수 없습니다. 볼륨 바인딩은 서비스에도 영향을 주어, 호환되지 않게 만듭니다.
이미지의 컨텍스트에서 도커를 사용하려면, 실행된 컨테이너에 /var/run/docker.sock
을 마운트해야 합니다. 도커 실행기로 이 작업을 하려면 [runners.docker]
섹션에 "/var/run/docker.sock:/var/run/docker.sock"
을 추가하세요. 이 예와 비슷한 설정을 해야 합니다:
[[runners]]
url = "https://gitlab.com/"
token = RUNNER_TOKEN
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:24.0.5"
privileged = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
[runners.cache]
Insecure = false
등록하는 러너와 함께 /var/run/docker.sock
를 마운트하려면, 다음 옵션들을 포함해야 합니다:
sudo gitlab-runner register -n \
--url "https://gitlab.com/" \
--registration-token REGISTRATION_TOKEN \
--executor docker \
--description "My Docker Runner" \
--docker-image "docker:24.0.5" \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock
코드 품질 체크와 같은 복잡한 Docker-in-Docker 설정에서는 호스트와 컨테이너 경로를 일치시켜야 올바른 실행이 가능합니다. 자세한 내용은 아래를 참조하세요: 개인 러너로 코드 품질 성능 향상.
docker:dind
서비스에 대한 레지스트리 미러 활성화
서비스 컨테이너 내에서 Docker 데몬이 시작되면 기본 구성을 사용합니다. 성능 향상 및 Docker Hub 속도 제한을 초과하지 않도록 하기 위해 레지스트리 미러를 구성할 수 있습니다.
.gitlab-ci.yml
파일의 서비스
dind
서비스에 추가 CLI 플래그를 추가하여 레지스트리 미러를 설정할 수 있습니다:
services:
- name: docker:24.0.5-dind
command: ["--registry-mirror", "https://registry-mirror.example.com"] # 사용할 레지스트리 미러 지정
GitLab 러너 구성 파일의 서비스
GitLab 러너 관리자라면 Docker 데몬을 위해 레지스트리 미러를 구성하기 위해 command
를 지정할 수 있습니다. dind
서비스는 Docker 또는 Kubernetes 실행자를 위해 정의되어 있어야 합니다.
Docker:
[[runners]]
...
executor = "docker"
[runners.docker]
...
privileged = true
[[runners.docker.services]]
name = "docker:24.0.5-dind"
command = ["--registry-mirror", "https://registry-mirror.example.com"]
Kubernetes:
[[runners]]
...
name = "kubernetes"
[runners.kubernetes]
...
privileged = true
[[runners.kubernetes.services]]
name = "docker:24.0.5-dind"
command = ["--registry-mirror", "https://registry-mirror.example.com"]
GitLab 러너 구성 파일의 Docker 실행자
GitLab 러너 관리자라면 모든 dind
서비스에 대해 미러를 사용할 수 있습니다. 구성을 업데이트하여 볼륨 마운트를 지정할 수 있습니다.
json
{
"registry-mirrors": [
"https://registry-mirror.example.com"
]
}
/etc/docker/daemon.json
파일에 아래 내용으로 config.toml
파일을 수정합니다. 이렇게 하면 GitLab Runner에 의해 생성된 모든 컨테이너에 대해 파일이 마운트됩니다. 이 구성은 dind
서비스에 의해 감지됩니다.
[[runners]]
...
executor = "docker"
[runners.docker]
image = "alpine:3.12"
privileged = true
volumes = ["/opt/docker/daemon.json:/etc/docker/daemon.json:ro"]
GitLab Runner 구성 파일의 Kubernetes executor
GitLab Runner 관리자인 경우 모든 dind
서비스에 대해 미러를 사용할 수 있습니다. 구성을 업데이트하여 ConfigMap volume mount를 지정합니다.
예를 들어, /tmp/daemon.json
파일에 다음 내용이 있으면:
{
"registry-mirrors": [
"https://registry-mirror.example.com"
]
}
이 파일의 내용으로 ConfigMap을 생성합니다. 다음과 같은 명령을 사용하여 이 작업을 수행할 수 있습니다:
kubectl create configmap docker-daemon --namespace gitlab-runner --from-file /tmp/daemon.json
ConfigMap이 생성된 후, config.toml
파일을 업데이트하여 /etc/docker/daemon.json
파일을 마운트합니다. 이 업데이트로 인해 GitLab Runner에 의해 생성된 모든 컨테이너에 대해 파일이 마운트됩니다. dind
서비스가 이 구성을 감지합니다.
[[runners]]
...
executor = "kubernetes"
[runners.kubernetes]
image = "alpine:3.12"
privileged = true
[[runners.kubernetes.volumes.config_map]]
name = "docker-daemon"
mount_path = "/etc/docker/daemon.json"
sub_path = "daemon.json"
Docker 소켓 바인딩의 알려진 문제점
Docker 소켓 바인딩을 사용하면 Docker를 특권 모드로 실행하지 않을 수 있습니다. 그러나 이 방법의 함의는 다음과 같습니다.
- Docker 데몬을 공유함으로써 컨테이너의 모든 보안 메커니즘을 비활성화하고 호스트를 특권 상승에 노출시킵니다. 이로 인해 컨테이너 탈출이 발생할 수 있습니다. 예를 들어 프로젝트에서
docker rm -f $(docker ps -a -q)
을 실행하면 GitLab Runner 컨테이너가 제거될 수 있습니다. - 동시 작업이 작동하지 않을 수 있습니다. 특정 이름의 컨테이너를 만들면 테스트가 서로 충돌할 수 있습니다.
- Docker 명령에 의해 생성된 모든 컨테이너는 러너의 형제로 간주됩니다. 이는 워크플로에 복잡성을 유발할 수 있습니다.
-
소스 리포지터리에서 파일 및 디렉터리를 컨테이너로 공유할 때 예상대로 작동하지 않을 수 있습니다. 볼륨 마운트는 빌드 컨테이너의 컨텍스트에서 수행됩니다. 예를 들어:
docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
Docker-in-Docker 실행기를 사용할 때처럼 docker:24.0.5-dind
서비스를 추가할 필요는 없습니다.
default:
image: docker:24.0.5
before_script:
- docker info
build:
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
Docker-in-Docker에서 레지스트리로 인증
Docker-in-Docker를 사용할 때 표준 인증 방법은 서비스와 함께 새로운 Docker 데몬이 시작되기 때문에 작동하지 않습니다. 레지스트리로 인증해야 합니다.
Docker 레이어 캐싱을 사용하여 Docker-in-Docker 빌드 가속화
Docker-in-Docker를 사용할 때 Docker는 모든 이미지 레이어를 매번 빌드할 때마다 다운로드합니다. Docker 레이어 캐싱을 사용하여 빌드를 가속화할 수 있습니다.
OverlayFS 드라이버 사용
overlay2
드라이버를 사용합니다.기본적으로 docker:dind
를 사용할 때 Docker는 파일 시스템을 매번 복사하는 vfs
스토리지 드라이버를 사용합니다. 더 효율적인 작업을 위해 다른 드라이버(예: overlay2
)를 사용함으로써 디스크 사용을 피할 수 있습니다.
요구 사항
- 가능한 최신 커널(
>= 4.2
)을 사용합니다. -
overlay
모듈이 로드되어 있는지 확인합니다:sudo lsmod | grep overlay
결과가 없는 경우 모듈이 로드되어 있지 않습니다. 모듈을 로드하려면 다음을 사용합니다:
sudo modprobe overlay
모듈이 로드된 경우 부팅시에 모듈이 로드되도록 해야 합니다. Ubuntu 시스템에서는
/etc/modules
에 다음 줄을 추가하여 이를 수행할 수 있습니다:overlay
프로젝트별로 OverlayFS 드라이버 사용
.gitlab-ci.yml
의 DOCKER_DRIVER
CI/CD 변수를 사용하여 각 프로젝트별로 드라이버를 활성화할 수 있습니다.
variables:
DOCKER_DRIVER: overlay2
모든 프로젝트에 대해 OverlayFS 드라이버 사용
자체 러너를 사용하는 경우
config.toml
파일의 [[runners]]
섹션에서 DOCKER_DRIVER
환경 변수를 설정하여 각 프로젝트에 대해 드라이버를 활성화할 수 있습니다
(자세한 내용):
environment = ["DOCKER_DRIVER=overlay2"]
여러 개의 러너를 실행 중인 경우 모든 구성 파일을 수정해야 합니다.
러너 구성에 대해 자세히 알아보기 및 OverlayFS 저장 드라이버 사용를 읽어보세요.
Docker 대체 옵션
러너에서 특권 모드를 활성화하지 않고 Docker 이미지를 빌드하려면 다음 중 하나를 사용할 수 있습니다:
Buildah 예제
GitLab CI/CD에서 Buildah를 사용하려면 다음 중 하나의 실행기가 있는 러너가 필요합니다:
이 예에서 Buildah를 사용하여 다음을 수행합니다:
- Docker 이미지를 빌드합니다.
- GitLab 컨테이너 레지스트리에 푸시합니다.
마지막 단계에서 Buildah는 프로젝트의 루트 디렉터리에 있는 Dockerfile
을 사용하여 Docker 이미지를 빌드한 후 이미지를 프로젝트의 컨테이너 레지스트리에 푸시합니다:
build:
stage: build
image: quay.io/buildah/stable
variables:
# Buildah에서 vfs를 사용합니다. Docker는 기본적으로 overlayfs를 제공하지만 Buildah는 다른 overlayfs 파일 시스템 위에 overlayfs를 쌓을 수 없습니다.
STORAGE_DRIVER: vfs
# 모든 이미지 메타데이터를 표준 OCI 형식이 아니라 Docker 형식으로 작성합니다. 새로운 버전의 Docker는 OCI 형식을 처리할 수 있지만 Fedora 30과 같이 오래된 버전은 처리할 수 없을 수 있습니다.
BUILDAH_FORMAT: docker
FQ_IMAGE_NAME: "$CI_REGISTRY_IMAGE/test"
before_script:
# [미리 정의된 CI/CD 변수](../variables/index.md#predefined-cicd-variables)에서 가져온 GitLab 컨테이너 레지스트리 자격 증명으로 레지스트리에 인증합니다.
- echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
script:
- buildah images
- buildah build -t $FQ_IMAGE_NAME
- buildah images
- buildah push $FQ_IMAGE_NAME
GitLab Runner Operator가 OpenShift 클러스터에 배포된 경우 루트리스 컨테이너에서 이미지를 빌드하는 데 Buildah 사용하는 튜토리얼을 확인해보세요.
GitLab 컨테이너 레지스트리 사용
Docker 이미지를 빌드한 후 GitLab 컨테이너 레지스트리에 푸시할 수 있습니다.
문제 해결
docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
이 오류는 Docker-in-Docker를 사용할 때 v19.03 이상인 경우 흔히 발생합니다.
이 오류는 Docker가 자동으로 TLS를 시작하기 때문에 발생합니다.
- 처음 설정하는 경우 Docker 이미지와 함께 Docker 실행기 사용를 참조하세요.
- v18.09 또는 이전 버전에서 업그레이드하는 경우 업그레이드 가이드를 참조하세요.
이 오류는 Kubernetes 실행기에서도 발생할 수 있는데, 이 경우 Docker-in-Docker 서비스에 완전히 시작하기 전에 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
services:
- registry.hub.docker.com/library/docker:24.0.5-dind
서비스의 호스트 이름은 이미지 이름 전체에서 파생됩니다. 그러나 더 짧은 서비스 호스트 이름인 docker
가 예상됩니다.
서비스 해결 및 액세스를 허용하려면 서비스 이름 docker
에 명시적 별칭을 추가하세요:
default:
image: docker:24.0.5
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. Is the docker daemon running?
docker
명령을 실행하려고 할 때 다음 오류가 발생할 수 있습니다:
$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
작업이 다음 환경 변수를 정의했는지 확인하세요:
DOCKER_HOST
-
DOCKER_TLS_CERTDIR
(옵션) -
DOCKER_TLS_VERIFY
(옵션)
또한 Docker 클라이언트를 제공하는 이미지를 업데이트할 수 있습니다. 예를 들어, docker/compose
이미지가 사용되지 않습니다 대신에 docker
로 대체해야 합니다.
러너(runner) 이슈 30944에 설명되어 있듯이, 이 오류는 작업에서 이전에 사용되었던 Deprecated Docker --link
매개변수에서 유도된 환경 변수(예: DOCKER_PORT_2375_TCP
)로 인해 발생할 수 있습니다. 다음 조건에서 작업이 이 오류로 실패합니다.
- CI/CD 이미지가
DOCKER_PORT_2375_TCP
와 같은 기존 변수에 의존하는 경우 -
러너(runner) 피처 플래그
FF_NETWORK_PER_BUILD
가true
로 설정되어 있는 경우 -
DOCKER_HOST
가 명시적으로 설정되지 않은 경우
오류: unauthorized: incorrect username or password
이 오류는 Deprecated 변수 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
로 변경해야 합니다.
오류 중 connect 중: 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
작업 로그에서 mount: permission denied (are you root?)
가 나타나는지 확인하세요. 예를 들어:
서비스 컨테이너 로그:
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 러너가 dind
서비스를 시작할 권한이 없다는 것을 나타냅니다:
-
config.toml
에privileged = true
가 설정되어 있는지 확인하세요. - 해당 권한이 있는 러너 태그가 CI 작업에 올바르게 설정되어 있는지 확인하세요.
오류: 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 Engine 19.06.x 또는 이전 버전이 있는 경우 docker:24.0.5-dind
서비스)는 문제없이 작동합니다. 최상의 전략은 자주 테스트하여 환경 버전을 최신 상태로 업데이트하는 것입니다. 이로써 새로운 기능이나 향상된 보안을 제공하며, 특히 이 경우에는 러너 호스트의 기반이 되는 Docker Engine을 업그레이드할 때 투명하게 작업하게 됩니다.