- CI/CD 작업에서 Docker 명령 활성화하기
- Docker-in-Docker에서 레지스트리 인증
- Docker-in-Docker 빌드를 Docker 레이어 캐싱으로 더 빠르게 만들기
- OverlayFS 드라이버 사용
- Docker 대안
- GitLab 컨테이너 레지스트리 사용
- 문제 해결
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
모드를 필요로 합니다.
privileged
모드를 활성화하지 않고 Docker 이미지를 빌드하려면 Docker 대안을 사용할 수 있습니다.
CI/CD 작업에서 Docker 명령 활성화하기
CI/CD 작업에서 Docker 명령을 활성화하려면 다음을 사용할 수 있습니다:
The shell executor 사용하기
CI/CD 작업에 Docker 명령을 포함하려면 러너를 shell
executor로 구성할 수 있습니다. 이 구성에서 gitlab-runner
사용자가 Docker 명령을 실행하지만, 그에 대한 권한이 필요합니다.
- GitLab Runner 설치.
-
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에
docker info
를.gitlab-ci.yml
에 추가하여 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
에 전체 root 권한이 부여됩니다.
더 많은 정보는 docker 그룹의 보안을 참조하십시오.
Docker-in-Docker 사용하기
“Docker-in-Docker”(dind
)은:
- 등록된 러너가 Docker executor 또는 Kubernetes executor를 사용합니다.
- executor는 Docker가 제공하는 Docker 컨테이너 이미지를 사용하여 CI/CD 작업을 실행합니다.
Docker 이미지에는 모든 docker
도구가 포함되어 있으며 privileged
모드로 작업 스크립트를 실행할 수 있습니다.
TLS가 활성화된 Docker-in-Docker를 사용해야 합니다. 이는 GitLab.com 인스턴스 러너에서 지원됩니다.
항상 docker:latest
와 같은 태그 대신 특정 버전을 사용해야 합니다. 새로운 버전이 출시되면 호환성 문제가 발생할 수 있기 때문입니다.
Docker executor와 Docker-in-Docker 사용하기
Docker executor를 사용하여 Docker 컨테이너에서 작업을 실행할 수 있습니다.
Docker executor에서 TLS가 활성화된 Docker-in-Docker
Docker 데몬은 TLS 연결을 지원합니다. TLS는 Docker 19.03.12부터 기본값입니다.
경고:
이 작업은 --docker-privileged
을 활성화하여 컨테이너의 보안 메커니즘을 비활성화하고 호스트를 특권 승격에 노출시키는 것을 의미합니다. 이 작업은 컨테이너 탈출을 유발할 수 있습니다. 자세한 내용은 런타임 특권 및 Linux 기능을 참조하십시오.
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"
- 이 명령은
docker:24.0.5
이미지를 사용하는 새 러너를 등록합니다(작업 수준에서 지정되지 않은 경우). 빌드 및 서비스 컨테이너를 시작하려면privileged
모드를 사용합니다. 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에 지시해야 합니다. # Docker 19.03에서 이 작업을 자동으로 수행합니다 # https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29 # # 'docker' 호스트명은 https://docs.gitlab.com/ee/ci/services/#accessing-the-services에서 설명된 서비스 컨테이너의 별칭입니다. # # 인증서를 생성할 위치를 Docker에 지정합니다. # Docker는 부팅시 자동으로 인증서를 만들고 # config.toml의 볼륨 마운트로 서비스 및 작업 컨테이너 간에 공유하기 위해 # `/certs/client`를 생성합니다. 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 구성을 제어할 수 없는 경우입니다.
가정하에 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에 설명된 서비스 컨테이너의 별칭입니다.
#
# GitLab Runner 12.7 이하 버전을 사용하여 Kubernetes 실행기와 Kubernetes 1.6 이하 버전을 사용하는 경우,
# Kubernetes 실행기가 서비스를 작업 컨테이너에 연결하는 방식 때문에 변수를 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
Kubernetes 실행기에서 Docker-in-Docker 사용
Kubernetes 실행기를 사용하여 Docker 컨테이너에서 작업을 실행할 수 있습니다.
Kubernetes에서 TLS가 활성화된 Docker-in-Docker 사용
Kubernetes에서 TLS가 활성화된 Docker-in-Docker를 사용하려면 다음을 따르세요:
-
헬름 차트를 사용하여
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에 설명된 서비스 컨테이너의 별칭입니다. # GitLab Runner 12.7 이하 버전을 사용하여 Kubernetes 실행기와 Kubernetes 1.6 이하 버전을 사용하는 경우, # 변수를 tcp://localhost:2376로 설정해야 합니다. # DOCKER_HOST: tcp://localhost:2376 # # Docker에게 인증서를 생성할 위치를 지정합니다. Docker는 부팅 시 자동으로 이를 생성하고 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
Kubernetes에서 TLS가 비활성화된 Docker-in-Docker 사용
Kubernetes에서 TLS가 비활성화된 Docker-in-Docker를 사용하려면 위의 예제를 적절하게 수정해야 합니다:
-
values.yml
파일에서[[runners.kubernetes.volumes.empty_dir]]
섹션을 제거합니다. - ‘DOCKER_HOST: tcp://docker:2375’로 포트를
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에 설명된 서비스 컨테이너의 별칭입니다. # 이해를 돕기 위해, GitLab Runner 12.7 이하 버전을 사용하여 Kubernetes 실행기와 Kubernetes 1.6 이하 버전을 사용하는 경우, # 변수를 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 레이어 캐싱을 참조하세요.
-
스토리지 드라이버: 이전 버전의 Docker에서는 기본적으로
vfs
스토리지 드라이버를 사용하여 각 작업에 파일 시스템을 복사합니다. Docker 17.09부터는 권장하는 스토리지 드라이버인--storage-driver overlay2
를 사용합니다. 자세한 내용은 OverlayFS 드라이버 사용를 참조하세요. -
루트 파일 시스템:
docker:24.0.5-dind
컨테이너와 실행자 컨테이너는 루트 파일 시스템을 공유하지 않으므로, 작업의 작업 디렉터리를 자식 컨테이너의 마운트 지점으로 사용할 수 있습니다. 예를 들어, 자식 컨테이너와 공유할 파일이 있다면/builds/$CI_PROJECT_PATH
아래에 하위 디렉터리를 만들고 마운트 지점으로 사용할 수 있습니다. 더 자세한 설명은 issue #41227을 확인하세요.변수: MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt 스크립트: - mkdir -p "$MOUNT_POINT" - docker run -v "$MOUNT_POINT:/mnt" my-docker-image
Docker 실행자를 Docker 소켓 바인딩과 함께 사용
CI/CD 작업에서 Docker 명령어를 사용하려면 /var/run/docker.sock
을
컨테이너에 bind-mount 할 수 있습니다. 이렇게 하면 Docker를 이미지의 컨텍스트에서 사용할 수 있습니다.
Docker 소켓을 바인딩하면 docker:24.0.5-dind
을 서비스로 사용할 수 없습니다. 볼륨 바인딩은 서비스에도 영향을 미치므로
호환되지 않습니다.
이미지의 컨텍스트에서 Docker를 사용하려면 러너의 컨텍스트에
/var/run/docker.sock
을 마운트해야 합니다. Docker
실행자로 사용하려면 [runners.docker]
섹션에 "/var/run/docker.sock:/var/run/docker.sock"
을 추가하세요.
(Volumes in the [runners.docker]
section을 참조하세요).
구성은 다음 예와 유사해야합니다:
[[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
Code Quality 검사와 같은 복잡한 Docker-in-Docker 설정의 경우, 올바른 실행을 위해 호스트와 컨테이너 경로를 일치시켜야 합니다. 자세한 내용은 프라이빗 러너로 Code Quality 성능 향상을 참조하세요.
docker:dind
서비스를 위한 레지스트리 미러 활성화
서비스 컨테이너 내에서 Docker 데몬이 시작되면 기본 구성을 사용합니다. 성능 향상을 위해 레지스트리 미러를 구성할 수 있습니다.
.gitlab-ci.yml
파일의 서비스에 추가 CLI 플래그를 붙여서 레지스트리 미러를 설정할 수 있습니다:
서비스:
- name: docker:24.0.5-dind
command: ["--registry-mirror", "https://registry-mirror.example.com"] # 사용할 레지스트리 미러 지정
GitLab 러너 구성 파일에서도 Docker 데몬을 위한 레지스트리 미러를 설정할 수 있습니다. 이를 위해 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 실행자를 사용하고 있다면
매 dind
서비스에 대해 미러를 사용할 수 있습니다. 구성을 업데이트하여
볼륨 마운트를 지정하세요.
예를 들어, /opt/docker/daemon.json
파일에 다음 내용이 포함되어 있는 경우:
{
"registry-mirrors": [
"https://registry-mirror.example.com"
]
}
config.toml
파일을 업데이트하여 파일을 /etc/docker/daemon.json
에 마운트하도록 합니다. 이렇게 하면 GitLab 러너에 의해 생성된 모든 컨테이너에 파일이 마운트됩니다.
구성은 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 볼륨 마운트를 지정하세요.
예를 들어, 다음과 같은 내용의 /tmp/daemon.json
파일이 있는 경우:
{
"registry-mirrors": [
"https://registry-mirror.example.com"
]
}
이 파일의 내용으로 ConfigMap을 만들 수 있습니다. 다음과 같이 명령어를 사용하여 만들 수 있습니다:
kubectl create configmap docker-daemon --namespace gitlab-runner --from-file /tmp/daemon.json
참고: GitLab Runner를 사용하여 작업 팟을 만들 때 사용하는 네임스페이스를 사용해야 합니다.
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 executor를 사용할 때와 같이 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-in-Docker 빌드를 Docker 레이어 캐싱으로 더 빠르게 만들기
Docker-in-Docker를 사용하는 경우, 이미지를 빌드할 때마다 Docker가 모든 계층을 다운로드합니다. Docker 레이어 캐싱을 사용하여 빌드 속도를 높일 수 있습니다.
OverlayFS 드라이버 사용
참고:
GitLab.com의 인스턴스 러너는 기본적으로 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 드라이버 사용
직접 운영하는 러너를 사용하는 경우, DOCKER_DRIVER
환경 변수를 설정하여 모든 프로젝트에 대해 드라이버를 활성화할 수 있습니다. 이를 위해 config.toml
파일의 [[runners]]
섹션을 수정해야 합니다:
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:
# vfs를 buildah와 함께 사용합니다. Docker는 오버레이FS를 기본으로 제공하지만, Buildah는 다른 오버레이FS 파일 시스템 위에 다른 오버레이FS를 스택할 수 없습니다.
STORAGE_DRIVER: vfs
# 모든 이미지 메타데이터를 표준 OCI 형식이 아니라 Docker 형식으로 작성합니다. 새로운 버전의 Docker는 OCI 형식을 처리할 수 있지만, Fedora 30과 같이 오래된 버전은 처리할 수 없을 수 있습니다.
BUILDAH_FORMAT: docker
FQ_IMAGE_NAME: "$CI_REGISTRY_IMAGE/test"
before_script:
# GitLab 컨테이너 레지스트리 자격 증명은
# [사전 정의 CI/CD 변수](../variables/index.md#predefined-cicd-variables)에서 가져와 레지스트리에 인증합니다.
- 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
OpenShift 클러스터에 배포된 GitLab Runner Operator를 사용하는 경우 루트리스 컨테이너에서 이미지 빌드를 위해 Buildah 사용하는 튜토리얼을 시도해보세요.
GitLab 컨테이너 레지스트리 사용
도커 이미지를 빌드한 후 GitLab 컨테이너 레지스트리에 푸시할 수 있습니다.
문제 해결
오류: 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 실행자 사용를 참조하십시오.
- v18.09 이전 버전에서 업그레이드하는 경우 업그레이드 가이드를 참조하십시오.
이 오류는 또한 Kubernetes 실행자가 완전히 시작되기 전에 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
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
로 대체해야 합니다.
런너 이슈 30944에서 설명한대로, 이 오류는 다음 조건을 충족하는 경우 발생할 수 있습니다.
- 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
로 변경합니다.
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?)
가 표시되는지 확인하십시오. 예를 들어:
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 러너가 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:24.0.5-dind
서비스 및 호스트의 Docker Engine 버전이 19.06.x 이하인 경우)는 문제없이 작동합니다. 최상의 전략을 위해 최신으로 작업 환경 버전을 자주 테스트하고 업데이트하시는 것이 좋습니다. 이렇게 하면 새로운 기능과 향상된 보안, 특히 이 특정한 경우에는 러너 호스트의 기본 Docker Engine 업그레이드가 작업에 대해 투명해집니다.