- 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?
- 오류:
Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: incorrect username or password
- 오류:
error during connect: Post "https://docker:2376/v1.24/auth": dial tcp: lookup docker on 127.0.0.11:53: no such host
- 오류:
cgroups: cgroup mountpoint does not exist: unknown
Docker 이미지 빌드에 Docker 사용하기
GitLab CI/CD를 사용하여 Docker로 Docker 이미지를 생성할 수 있습니다. 예를 들어 애플리케이션의 Docker 이미지를 만들고 테스트한 후 컨테이너 레지스트리에 푸시할 수 있습니다.
CI/CD 작업에서 Docker 명령을 실행하려면, GitLab Runner를 docker
명령을 지원하도록 구성해야 합니다. 이 방법은 privileged
모드를 필요로 합니다.
러너에서 privileged
모드를 활성화하지 않고 Docker 이미지를 빌드하려면 Docker 대체 옵션을 사용할 수 있습니다.
CI/CD 작업에서 Docker 명령 활성화하기
CI/CD 작업에 Docker 명령을 활성화하려면 다음을 사용할 수 있습니다:
쉘 러너 사용
CI/CD 작업에서 Docker 명령을 사용하려면, 러너를 shell
실행기로 구성할 수 있습니다. 이 구성에서는 gitlab-runner
사용자가 Docker 명령을 실행할 수 있지만, 그에게는 그에게 그러한 권한이 있어야 합니다.
- GitLab Runner 설치.
-
러너 등록.
shell
실행기를 선택하세요. 예시: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-in-Docker 사용
“Docker-in-Docker” (dind
)란:
- 등록된 러너가 Docker 실행기 또는 Kubernetes 실행기를 사용합니다.
- 실행기는 Docker가 제공하는 도커 컨테이너 이미지를 사용하여 CI/CD 작업을 실행합니다.
이 Docker 이미지에는 모든 docker
도구가 포함되어 있으며, 권한이 부여된 모드로 이미지 내에서 작업 스크립트를 실행할 수 있습니다.
_tls_를 활성화한 Docker-in-Docker를 사용해야 합니다. 이는 GitLab.com 인스턴스 러너에서 지원됩니다.
항상 docker:24.0.5
와 같이 특정 버전을 지정해야 합니다.
docker:latest
와 같은 태그를 사용하면 사용할 버전을 제어할 수 없습니다.
새 버전이 출시되면 호환성 문제를 일으킬 수 있습니다.
Docker 실행기와 tls 활성화된 Docker-in-Docker 사용
- GitLab Runner 11.11에 도입되었습니다.
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
를 마운트합니다. 자세한 내용은 도커 이미지 설명서를 참조하세요.
이전 명령은 다음 예와 유사한
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_HOST를 사용하도록 Docker에 지시해야 합니다. # 기본 /var/run/docker.sock 소켓 대신 서비스 내에서 네트워크 연결을 통해 사용할 수 있습니다. # 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는 부팅시 자동으로 생성하고 # 서비스 및 작업 컨테이너 사이에서 공유하기 위해 `/certs/client`를 만듭니다. # config.toml로부터 볼륨 마운트를 통해 Docker가 자동으로 이를 수행합니다 DOCKER_TLS_CERTDIR: "/certs" build: stage: build script: - docker build -t my-docker-image . - docker run my-docker-image /script/to/run/tests
Docker-in-Docker with TLS 비활성화된 Docker executor
가끔은 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 executor 및 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 executor 사용
Kubernetes executor를 사용하여 Docker 컨테이너에서 작업을 실행할 수 있습니다.
TLS가 활성화된 Kubernetes에서 Docker-in-Docker 사용
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 executor 및 Kubernetes 1.6 이전을 사용하고 있다면 GitLab Runner 12.7 이전 버전을 사용하는 경우 # 작업 컨테이너에 서비스를 연결하는 방법으로 인해 변수를 tcp://localhost:2376로 설정해야 합니다. # DOCKER_HOST: tcp://localhost:2376 # # Docker에게 인증서를 생성할 위치를 지정합니다. Docker는 부팅시 자동으로 이를 생성하고 # 볼륨 마운트로 인해 서비스와 작업 컨테이너 간에 `/certs/client`를 생성합니다. DOCKER_TLS_CERTDIR: "/certs" # 이들은 보통 엔트리포인트에 의해 지정되지만 Kubernetes executor는 엔트리포인트를 실행하지 않습니다. 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]]
섹션을 제거합니다. - 포트를
2376
에서2375
로 변경하고DOCKER_HOST: tcp://docker:2375
로 설정합니다. - TLS를 비활성화하도록 Docker에 지시하려면
DOCKER_TLS_CERTDIR: ""
로 설정합니다.
예시:
-
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 레이어 캐싱을 참조하세요.
-
스토리지 드라이버: 기본적으로 이전 버전의 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 소켓 바인딩으로 Docker 실행기 사용
CI/CD 작업에서 Docker 명령어를 사용하려면 /var/run/docker.sock
을 컨테이너로 바인딩해야 합니다.
그러면 이미지의 컨텍스트에서 Docker를 사용할 수 있습니다.
Docker 소켓을 바인딩하면
GitLab Runner 11.11 이상을 사용하는 경우,
docker:24.0.5-dind
를 서비스로 더 이상 사용할 수 없습니다. 볼륨 바인딩은 서비스에도 영향을 미치므로
호환되지 않습니다.
Docker를 이미지 컨텍스트에서 사용하도록 하려면, 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
Runner를 등록할 때 /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를 사용하여 Code Climate을 통한 복잡한 Docker-in-Docker 설정을 하는 경우, 호스트와 컨테이너 경로를 일치시켜야 합니다. 자세한 내용은 Private Runner를 사용하여 코드 품질 성능 향상을 참조하세요.
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 Runner 구성 파일의 서비스
GitLab Runner 관리자라면 Docker 데몬을 위해 레지스트리 미러를 구성하기 위해 command
를 지정할 수 있습니다. dind
서비스는 Docker 또는 Kubernetes executor를 위해 정의되어야 합니다.
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 Runner 구성 파일의 Docker executor
GitLab Runner 관리자라면 모든 dind
서비스에 대해 미러를 사용할 수 있습니다. 구성을 업데이트하여 런너 도커 섹션의 볼륨 마운트를 지정하세요.
다음과 같이 /opt/docker/daemon.json
파일이 있는 경우:
{
"registry-mirrors": [
"https://registry-mirror.example.com"
]
}
config.toml
파일을 업데이트하여 파일을 /etc/docker/daemon.json
에 마운트하도록 합니다. 이렇게 하면 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
서비스에 대해 미러를 사용할 수 있습니다. 구성을 업데이트하여 볼륨 사용을 지정하세요.
다음과 같이 /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를 위해 사용하는 작업 파드를 생성하는 쿠버네티스 executor의 네임스페이스를 사용해야 합니다.
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 명령으로 생성된 모든 컨테이너는 Runner의 형제로 간주되며, Runner의 자식이 아닙니다. 이는 워크플로에 복잡성을 유발할 수 있습니다.
-
소스 리포지토리에서 파일 및 디렉토리를 컨테이너로 공유하는 것이 예상대로 작동하지 않을 수 있습니다. 볼륨 마운팅은 빌드 컨테이너가 아니라 호스트 머신의 컨텍스트에서 수행됩니다. 예를 들어:
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 드라이버 사용
참고:
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 드라이버 사용
러너를 사용하는 경우, config.toml
파일의 [[runners]]
섹션에 DOCKER_DRIVER
환경 변수를 설정하여 모든 프로젝트에 대해 드라이버를 활성화할 수 있습니다.
environment = ["DOCKER_DRIVER=overlay2"]
여러 러너를 실행 중이면 모든 구성 파일을 수정해야 합니다.
러너 구성 및 OverlayFS 저장소 드라이버 사용에 대해 자세히 알아보세요.
Docker 대안
러너에서 특권 모드를 활성화하지 않고 Docker 이미지를 빌드하려면 다음 중 하나를 사용할 수 있습니다:
- kaniko
.
- buildah
.
Buildah 예시
GitLab CI/CD에서 Buildah를 사용하려면 다음 실행자 중 하나를 사용하는 러너가 필요합니다: - Kubernetes. - Docker. - Docker Machine.
이 예시에서 Buildah를 사용하여 다음을 수행합니다: 1. Docker 이미지를 빌드합니다. 1. 이를 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는 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를 사용하는 경우, 루트리스 컨테이너에서 이미지를 빌드하는 방법에 대한 튜토리얼을 확인해보세요.
GitLab 컨테이너 레지스트리 사용하기
도커 이미지를 빌드한 후, 해당 이미지를 GitLab 컨테이너 레지스트리에 푸시할 수 있습니다.
문제 해결
docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
이 오류는 Docker-in-Docker v19.03 이상을 사용할 때 일반적으로 발생합니다.
이 오류는 Docker가 TLS에서 자동으로 시작되기 때문에 발생합니다.
- 이것이 설정을 하는 첫 번째 시도라면, 도커 이미지를 사용하여 도커 실행기 사용를 참조하세요.
- 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. Is the docker daemon running?
docker
명령을 실행하여 dind
서비스에 액세스하려고 시도할 때 다음과 같은 오류가 발생할 수 있습니다.
$ 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에서 설명한대로, 이 오류는 작업이 이전에 사용되던 Docker --link
매개변수에서 파생된 환경 변수(예: DOCKER_PORT_2375_TCP
)에 의존하고 있고:
- CI/CD 이미지가
DOCKER_PORT_2375_TCP
와 같은 레거시 변수에 의존하는 경우 -
런너 기능 플래그
FF_NETWORK_PER_BUILD
가true
로 설정되어 있는 경우 -
DOCKER_HOST
가 명시적으로 설정되어 있지 않은 경우
작업이 이 오류로 실패할 수 있습니다.
오류: Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: incorrect username or password
이 오류는 폐기된 변수 CI_BUILD_TOKEN
을 사용할 때 발생합니다. 사용자가 이러한 오류를 받지 않도록하려면 다음을 해야 합니다:
- CI_JOB_TOKEN을 사용하세요.
-
gitlab-ci-token/CI_BUILD_TOKEN
에서$CI_REGISTRY_USER/$CI_REGISTRY_PASSWORD
로 변경하세요.
오류: error during connect: Post "https://docker:2376/v1.24/auth": dial tcp: lookup docker on 127.0.0.11:53: no such host
이 오류는 dind
서비스가 시작하지 못했을 때 발생합니다. job log
를 확인하여 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 작업이 올바르게 Runner 태그로 정의되어 있는지 확인하세요.
오류: cgroups: cgroup mountpoint does not exist: unknown
도커 엔진 20.10에서 도입된 알려진 호환성 문제가 있습니다.
호스트가 도커 엔진 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 이하 버전인 경우)는 문제없이 작동합니다. 최상의 전략을 위해 작업 환경 버전을 자주 테스트하고 업데이트하여 최신 버전으로 유지하는 것이 좋습니다. 이렇게 하면 새로운 기능이나 향상된 보안 그리고 이 특정 사례의 경우에는 러너 호스트의 기본 도커 엔진 업그레이드가 작업에 대해 투명하게 이루어집니다.