InfoGrab Docs

Docker 컨테이너에서 CI/CD 잡 실행

요약

전용 CI/CD 빌드 서버나 로컬 머신에서 호스팅되는 Docker 컨테이너에서 CI/CD 잡을 실행할 수 있습니다. Docker 컨테이너에서 CI/CD 잡을 실행하려면 다음이 필요합니다: Docker와 함께 GitLab Runner를 사용하려면 Docker 실행기를 사용하는 러너를 등록해야 합니다.

전용 CI/CD 빌드 서버나 로컬 머신에서 호스팅되는 Docker 컨테이너에서 CI/CD 잡을 실행할 수 있습니다.

Docker 컨테이너에서 CI/CD 잡을 실행하려면 다음이 필요합니다:

  1. 러너를 등록하고 Docker 실행기를 사용하도록 구성합니다.
  2. .gitlab-ci.yml 파일에서 CI/CD 잡을 실행할 컨테이너 이미지를 지정합니다.
  3. 선택 사항. MySQL 같은 다른 서비스를 컨테이너에서 실행합니다. .gitlab-ci.yml 파일에서 서비스를 지정하여 이를 수행합니다.

Docker 실행기를 사용하는 러너 등록#

Docker와 함께 GitLab Runner를 사용하려면 Docker 실행기를 사용하는 러너를 등록해야 합니다.

다음 예시는 서비스를 제공하기 위한 임시 템플릿을 설정하는 방법을 보여줍니다:

cat > /tmp/test-config.template.toml << EOF
[[runners]]
[runners.docker]
[[runners.docker.services]]
name = "postgres:latest"
[[runners.docker.services]]
name = "mysql:latest"
EOF

그런 다음 이 템플릿을 사용하여 러너를 등록합니다:

sudo gitlab-runner register \
  --url "https://gitlab.example.com/" \
  --token "$RUNNER_TOKEN" \
  --description "docker-ruby:2.6" \
  --executor "docker" \
  --template-config /tmp/test-config.template.toml \
  --docker-image ruby:3.3

등록된 러너는 ruby:2.6 Docker 이미지를 사용하고, 빌드 프로세스 중에 접근 가능한 두 서비스인 postgres:latestmysql:latest를 실행합니다.

이미지란#

image 키워드는 Docker 실행기가 CI/CD 잡을 실행하는 데 사용하는 Docker 이미지의 이름입니다.

기본적으로 실행기는 Docker Hub에서 이미지를 가져옵니다. 그러나 gitlab-runner/config.toml 파일에서 레지스트리 위치를 구성할 수 있습니다. 예를 들어, 로컬 이미지를 사용하도록 Docker 풀 정책을 설정할 수 있습니다.

이미지와 Docker Hub에 대한 자세한 내용은 Docker 개요를 참조하세요.

이미지 요구 사항#

CI/CD 잡을 실행하는 데 사용되는 이미지에는 다음 애플리케이션이 설치되어 있어야 합니다:

  • sh 또는 bash
  • grep

.gitlab-ci.yml 파일에서 image 정의#

모든 잡에 사용되는 이미지와 런타임 중에 사용할 서비스 목록을 정의할 수 있습니다:

default:
  image: ruby:2.6
  services:
    - postgres:16.10
  before_script:
    - bundle install

test:
  script:
    - bundle exec rake spec

이미지 이름은 다음 형식 중 하나여야 합니다:

  • image: <image-name> (latest 태그와 함께 <image-name> 사용과 동일)
  • image: <image-name>:<tag>
  • image: <image-name>@<digest>

확장 Docker 구성 옵션#

히스토리
  • GitLab 및 GitLab Runner 9.4에서 도입됨.

image 또는 services 항목에 문자열 또는 맵을 사용할 수 있습니다:

  • 문자열에는 전체 이미지 이름이 포함되어야 합니다(Docker Hub 이외의 레지스트리에서 이미지를 다운로드하려면 레지스트리 포함).
  • 맵에는 문자열 설정에 사용된 것과 동일한 이미지 이름인 name 옵션이 최소한 포함되어야 합니다.

예를 들어, 다음 두 정의는 동일합니다:

  • imageservices에 대한 문자열:

    image: "registry.example.com/my/image:latest"
    
    services:
      - postgresql:16.10
      - redis:latest
    
  • imageservices에 대한 맵. image:name이 필수입니다:

    image:
      name: "registry.example.com/my/image:latest"
    
    services:
      - name: postgresql:16.10
      - name: redis:latest
    

스크립트가 실행되는 위치#

Docker 컨테이너에서 CI 잡이 실행되면 before_script, script, after_script 명령은 /builds/<project-path>/ 디렉토리에서 실행됩니다. 이미지는 다른 기본 WORKDIR이 정의되어 있을 수 있습니다. WORKDIR로 이동하려면 WORKDIR을 환경 변수로 저장하여 잡 실행 중에 컨테이너에서 참조할 수 있도록 합니다.

이미지의 엔트리포인트 재정의#

히스토리
  • GitLab 및 GitLab Runner 9.4에서 도입됨. 확장 구성 옵션에 대해 자세히 읽어보세요.

사용 가능한 엔트리포인트 재정의 방법을 설명하기 전에 러너가 시작하는 방식을 설명하겠습니다. 러너는 CI/CD 잡에 사용되는 컨테이너에 Docker 이미지를 사용합니다:

  1. 러너가 정의된 엔트리포인트를 사용하여 Docker 컨테이너를 시작합니다. .gitlab-ci.yml 파일에서 재정의될 수 있는 Dockerfile의 기본값.
  2. 러너가 실행 중인 컨테이너에 연결됩니다.
  3. 러너가 스크립트( before_script, script, after_script의 조합)를 준비합니다.
  4. 러너가 스크립트를 컨테이너의 셸 stdin으로 보내고 출력을 받습니다.

Docker 이미지의 엔트리포인트를 재정의하려면 .gitlab-ci.yml 파일에서:

  • Docker 17.06 이상에서는 entrypoint를 빈 값으로 설정합니다.
  • Docker 17.03 이하에서는 entrypoint/bin/sh -c, /bin/bash -c 또는 이미지에서 사용 가능한 동등한 셸로 설정합니다.

image:entrypoint의 구문은 Dockerfile ENTRYPOINT와 유사합니다.

SQL 데이터베이스가 있는 super/sql:experimental 이미지가 있다고 가정해봅니다. 이 데이터베이스 바이너리로 일부 테스트를 실행하고 싶기 때문에 잡의 기본 이미지로 사용하려고 합니다. 이 이미지가 엔트리포인트로 /usr/bin/super-sql run이 구성되어 있다고 가정해보겠습니다. 컨테이너가 추가 옵션 없이 시작되면 데이터베이스의 프로세스를 실행합니다. 러너는 이미지에 엔트리포인트가 없거나 엔트리포인트가 셸 명령을 시작하도록 준비되어 있다고 기대합니다.

확장 Docker 구성 옵션을 사용하면 다음 대신:

  • super/sql:experimental을 기반으로 자체 이미지 생성.
  • ENTRYPOINT를 셸로 설정.
  • CI 잡에서 새 이미지 사용.

이제 .gitlab-ci.yml 파일에서 entrypoint를 정의할 수 있습니다.

Docker 17.06 이상:

image:
  name: super/sql:experimental
  entrypoint: [""]

Docker 17.03 이하:

image:
  name: super/sql:experimental
  entrypoint: ["/bin/sh", "-c"]

config.toml에서 이미지 및 서비스 정의#

config.toml 파일에서 다음을 정의할 수 있습니다:

[runners.docker]
  image = "ruby:latest"
  services = ["mysql:latest", "postgres:latest"]

이 방식으로 정의된 이미지 및 서비스는 해당 러너가 실행하는 모든 잡에 추가됩니다.

비공개 컨테이너 레지스트리에서 이미지 접근#

비공개 컨테이너 레지스트리에 접근하기 위해 GitLab Runner 프로세스는 다음을 사용할 수 있습니다:

동일한 GitLab 인스턴스에서 GitLab 컨테이너 레지스트리를 사용하는 경우, GitLab은 이 레지스트리에 대한 기본 자격 증명을 제공합니다. 이 자격 증명을 사용하면 인증에 CI_JOB_TOKEN이 사용됩니다. 잡 토큰을 사용하려면 잡을 시작하는 사용자가 비공개 이미지가 호스팅된 프로젝트에 대한 개발자, 유지 관리자 또는 소유자 역할이 있어야 합니다. 비공개 이미지를 호스팅하는 프로젝트도 다른 프로젝트가 잡 토큰으로 인증하도록 허용해야 합니다. 이 접근은 기본적으로 비활성화되어 있습니다. 자세한 내용은 CI/CD 잡 토큰을 참조하세요.

사용할 옵션을 정의하기 위해 러너 프로세스는 다음 순서로 구성을 읽습니다:

  • /root/.docker 디렉토리의 config.json 파일.
  • DOCKER_AUTH_CONFIG CI/CD 변수.
  • 러너의 config.toml 파일에 설정된 DOCKER_AUTH_CONFIG 환경 변수.
  • 프로세스를 실행하는 사용자의 $HOME/.docker 디렉토리의 config.json 파일. --user 플래그가 제공되어 자식 프로세스를 비권한 사용자로 실행하는 경우 기본 러너 프로세스 사용자의 홈 디렉토리가 사용됩니다.

요구 사항 및 제한 사항#

  • 자격 증명 저장소자격 증명 도우미는 바이너리를 GitLab Runner $PATH에 추가해야 하며 이를 위한 접근 권한이 필요합니다. 따라서 이러한 기능은 인스턴스 러너나 러너가 설치된 환경에 접근할 수 없는 다른 러너에서는 사용할 수 없습니다.

정적으로 정의된 자격 증명 사용#

두 가지 방법으로 비공개 레지스트리에 접근할 수 있습니다. 두 방법 모두 적절한 인증 정보와 함께 CI/CD 변수 DOCKER_AUTH_CONFIG를 설정해야 합니다.

  1. 잡별: 하나의 잡에 비공개 레지스트리 접근을 구성하려면 DOCKER_AUTH_CONFIGCI/CD 변수로 추가합니다.
  2. 러너별: 러너의 모든 잡이 비공개 레지스트리에 접근할 수 있도록 구성하려면 러너 구성에서 DOCKER_AUTH_CONFIG를 환경 변수로 추가합니다.

각 예시는 다음 섹션을 참조하세요.

DOCKER_AUTH_CONFIG 데이터 결정#

예를 들어, registry.example.com:5000/private/image:latest 이미지를 사용하려 한다고 가정해봅니다. 이 이미지는 비공개이며 비공개 컨테이너 레지스트리에 로그인해야 합니다.

로그인 자격 증명이 다음과 같다고 가정해봅니다:

registry registry.example.com:5000
username my_username
password my_password

DOCKER_AUTH_CONFIG의 값을 결정하는 데 다음 방법 중 하나를 사용하세요:

  • 로컬 머신에서 docker login을 수행합니다:

    docker login registry.example.com:5000 --username my_username --password my_password
    

    그런 다음 ~/.docker/config.json의 내용을 복사합니다.

    컴퓨터에서 레지스트리에 접근할 필요가 없는 경우 docker logout을 수행할 수 있습니다:

    docker logout registry.example.com:5000
    
  • 일부 설정에서 Docker 클라이언트가 사용 가능한 시스템 키 저장소를 사용하여 docker login의 결과를 저장할 수 있습니다. 이 경우 ~/.docker/config.json을 읽는 것이 불가능하므로 필요한 base64 인코딩 버전의 ${username}:${password}를 준비하고 Docker 구성 JSON을 수동으로 생성해야 합니다. 터미널을 열고 다음 명령을 실행합니다:

    # The use of printf (as opposed to echo) prevents encoding a newline in the password.
    printf "my_username:my_password" | openssl base64 -A
    
    # Example output to copy
    bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=
    

    [!note] 사용자 이름에 @와 같은 특수 문자가 포함된 경우 인증 문제를 방지하기 위해 백슬래시(\)로 이스케이프해야 합니다.

    다음과 같이 Docker JSON 구성 내용을 만듭니다:

    {
        "auths": {
            "registry.example.com:5000": {
                "auth": "(Base64 content from above)"
            }
        }
    }
    

잡 구성#

registry.example.com:5000에 대한 접근이 가능한 단일 잡을 구성하려면 다음 단계를 따르세요:

  1. Docker 구성 파일의 내용을 값으로 하는 CI/CD 변수 DOCKER_AUTH_CONFIG를 만듭니다:

    {
        "auths": {
            "registry.example.com:5000": {
                "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
            }
        }
    }
    
  2. 이제 .gitlab-ci.yml 파일의 image 또는 services에 정의된 registry.example.com:5000의 비공개 이미지를 사용할 수 있습니다:

    image: registry.example.com:5000/namespace/image:tag
    

    이전 예시에서 GitLab Runner는 registry.example.com:5000에서 이미지 namespace/image:tag를 찾습니다.

이전에 설명한 대로 "auths" 해시에 더 많은 레지스트리를 추가하여 원하는 만큼 많은 레지스트리에 대한 구성을 추가할 수 있습니다.

러너가 DOCKER_AUTH_CONFIG를 매치시키기 위해서는 모든 곳에 전체 hostname:port 조합이 필요합니다. 예를 들어, .gitlab-ci.yml 파일에 registry.example.com:5000/namespace/image:tag가 지정된 경우, DOCKER_AUTH_CONFIG에도 registry.example.com:5000이 지정되어야 합니다. registry.example.com만 지정하는 것은 작동하지 않습니다.

러너 구성#

동일한 레지스트리에 접근하는 파이프라인이 많은 경우 러너 수준에서 레지스트리 접근을 설정해야 합니다. 이렇게 하면 파이프라인 작성자가 적절한 러너에서 잡을 실행하는 것만으로 비공개 레지스트리에 접근할 수 있습니다. 또한 레지스트리 변경 및 자격 증명 교체를 단순화하는 데 도움이 됩니다.

이는 해당 러너의 모든 잡이 프로젝트 간에도 동일한 권한으로 레지스트리에 접근할 수 있음을 의미합니다. 레지스트리에 대한 접근을 제어해야 하는 경우 러너에 대한 접근을 제어해야 합니다.

러너에 DOCKER_AUTH_CONFIG를 추가하려면:

  1. 다음과 같이 러너의 config.toml 파일을 수정합니다:

    [[runners]]
      environment = ["DOCKER_AUTH_CONFIG={\"auths\":{\"registry.example.com:5000\":{\"auth\":\"bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=\"}}}"]
    
    • DOCKER_AUTH_CONFIG 데이터에 포함된 큰따옴표는 TOML로 해석되지 않도록 백슬래시로 이스케이프해야 합니다.
    • environment 옵션은 목록입니다. 러너에 기존 항목이 있을 수 있으며 이를 대체하는 것이 아니라 목록에 추가해야 합니다.
  2. 러너 서비스를 다시 시작합니다.

자격 증명 저장소 사용#

자격 증명 저장소를 구성하려면:

  1. 자격 증명 저장소를 사용하려면 특정 키체인 또는 외부 저장소와 상호 작용하는 외부 도우미 프로그램이 필요합니다. 도우미 프로그램이 GitLab Runner $PATH에 있는지 확인합니다.

  2. GitLab Runner가 이를 사용하도록 합니다. 다음 옵션 중 하나를 사용하여 이를 달성할 수 있습니다:

    • Docker 구성 파일의 내용을 값으로 하는 CI/CD 변수 DOCKER_AUTH_CONFIG를 만듭니다:

        {
          "credsStore": "osxkeychain"
        }
      
    • 또는 자체 관리형 러너를 실행 중인 경우 JSON을 ${GITLAB_RUNNER_HOME}/.docker/config.json에 추가합니다. GitLab Runner가 이 구성 파일을 읽고 이 특정 저장소에 필요한 도우미를 사용합니다.

credsStore모든 레지스트리에 접근하는 데 사용됩니다. 비공개 레지스트리의 이미지와 Docker Hub의 공개 이미지를 모두 사용하는 경우 Docker Hub에서 가져오기가 실패합니다. Docker 데몬은 모든 레지스트리에 동일한 자격 증명을 사용하려고 합니다.

자격 증명 도우미 사용#

예를 들어, <aws_account_id>.dkr.ecr.<region>.amazonaws.com/private/image:latest 이미지를 사용하려 한다고 가정해봅니다. 이 이미지는 비공개이며 비공개 컨테이너 레지스트리에 로그인해야 합니다.

<aws_account_id>.dkr.ecr.<region>.amazonaws.com에 대한 접근을 구성하려면 다음 단계를 따르세요:

  1. docker-credential-ecr-login이 GitLab Runner $PATH에 있는지 확인합니다.

  2. 다음 AWS 자격 증명 설정 중 하나를 완료합니다. GitLab Runner Manager가 자격 증명을 획득하고 러너에 전달합니다. GitLab Runner가 자격 증명에 접근할 수 있는지 확인합니다.

  3. GitLab Runner가 이를 사용하도록 합니다. 다음 옵션 중 하나를 사용하여 이를 달성할 수 있습니다:

    • Docker 구성 파일의 내용을 값으로 하는 CI/CD 변수 DOCKER_AUTH_CONFIG를 만듭니다:

      {
        "credHelpers": {
          "<aws_account_id>.dkr.ecr.<region>.amazonaws.com": "ecr-login"
        }
      }
      

      이는 특정 레지스트리에 대한 자격 증명 도우미를 사용하도록 Docker를 구성합니다.

      대신 모든 Amazon Elastic Container Registry(ECR) 레지스트리에 자격 증명 도우미를 사용하도록 Docker를 구성할 수 있습니다:

      {
        "credsStore": "ecr-login"
      }
      

      [!note] {"credsStore": "ecr-login"}을 사용하는 경우 AWS 공유 구성 파일(~/.aws/config)에서 지역을 명시적으로 설정합니다. ECR 자격 증명 도우미가 인증 토큰을 검색할 때 지역을 지정해야 합니다.

    • 또는 자체 관리형 러너를 실행 중인 경우 이전 JSON을 ${GITLAB_RUNNER_HOME}/.docker/config.json에 추가합니다. GitLab Runner가 이 구성 파일을 읽고 이 특정 저장소에 필요한 도우미를 사용합니다.

  4. 이제 .gitlab-ci.yml 파일의 image 및/또는 services에 정의된 <aws_account_id>.dkr.ecr.<region>.amazonaws.com의 비공개 이미지를 사용할 수 있습니다:

    image: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/private/image:latest
    

    이 예시에서 GitLab Runner는 <aws_account_id>.dkr.ecr.<region>.amazonaws.com에서 이미지 private/image:latest를 찾습니다.

"credHelpers" 해시에 더 많은 레지스트리를 추가하여 원하는 만큼 많은 레지스트리에 대한 구성을 추가할 수 있습니다.

체크섬을 사용하여 이미지 보안 유지#

.gitlab-ci.yml 파일의 잡 정의에 이미지 체크섬을 사용하여 이미지의 무결성을 확인합니다. 이미지 무결성 확인에 실패하면 수정된 컨테이너를 사용할 수 없습니다.

이미지 체크섬을 사용하려면 끝에 체크섬을 추가해야 합니다:

image: ruby:2.6.8@sha256:d1dbaf9665fe8b2175198e49438092fdbcf4d8934200942b94425301b17853c7

이미지 체크섬을 얻으려면 이미지 TAG 탭에서 DIGEST 열을 봅니다. 예를 들어, Ruby 이미지를 봅니다. 체크섬은 6155f0235e95와 같은 임의의 문자열입니다.

또한 docker images --digests 명령으로 시스템의 모든 이미지의 체크섬을 얻을 수 있습니다:

❯ docker images --digests
REPOSITORY                                                        TAG       DIGEST                                                                    (...)
gitlab/gitlab-ee                                                  latest    sha256:723aa6edd8f122d50cae490b1743a616d54d4a910db892314d68470cc39dfb24   (...)
gitlab/gitlab-runner                                              latest    sha256:4a18a80f5be5df44cb7575f6b89d1fdda343297c6fd666c015c0e778b276e726   (...)

사용자 정의 GitLab Runner Docker 이미지 만들기#

AWS CLI와 Amazon ECR 자격 증명 도우미를 패키지로 포함하는 사용자 정의 GitLab Runner Docker 이미지를 만들 수 있습니다. 이 설정은 특히 컨테이너화된 애플리케이션에서 AWS 서비스와의 안전하고 효율적인 상호 작용을 용이하게 합니다. 예를 들어, Amazon ECR에서 Docker 이미지를 관리, 배포, 업데이트하는 데 이 설정을 사용합니다. 이 설정은 시간이 많이 걸리고 오류가 발생하기 쉬운 구성 및 수동 자격 증명 관리를 방지하는 데 도움이 됩니다.

  1. GitLab과 AWS 인증.

  2. 다음 내용으로 Dockerfile을 만듭니다:

    # Control package versions
    ARG GITLAB_RUNNER_VERSION=v17.3.0
    ARG AWS_CLI_VERSION=2.17.36
    
    # AWS CLI and Amazon ECR Credential Helper
    FROM amazonlinux as aws-tools
    RUN set -e \
        && yum update -y \
        && yum install -y --allowerasing git make gcc curl unzip \
        && curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" --output "awscliv2.zip" \
        && unzip awscliv2.zip && ./aws/install -i /usr/local/bin \
        && yum clean all
    
    # Download and install ECR Credential Helper
    RUN curl --location --output  /usr/local/bin/docker-credential-ecr-login "https://github.com/awslabs/amazon-ecr-credential-helper/releases/latest/download/docker-credential-ecr-login-linux-amd64"
    RUN chmod +x /usr/local/bin/docker-credential-ecr-login
    
    # Configure the ECR Credential Helper
    RUN mkdir -p /root/.docker
    RUN echo '{ "credsStore": "ecr-login" }' > /root/.docker/config.json
    
    # Final image based on GitLab Runner
    FROM gitlab/gitlab-runner:${GITLAB_RUNNER_VERSION}
    
    # Install necessary packages
    RUN apt-get update \
        && apt-get install -y --no-install-recommends jq procps curl unzip groff libgcrypt20 tar gzip less openssh-client \
        && apt-get clean && rm -rf /var/lib/apt/lists/*
    
    # Copy AWS CLI and Amazon ECR Credential Helper binaries
    COPY --from=aws-tools /usr/local/bin/ /usr/local/bin/
    
    # Copy ECR Credential Helper Configuration
    COPY --from=aws-tools /root/.docker/config.json /root/.docker/config.json
    
  3. .gitlab-ci.yml에서 사용자 정의 GitLab Runner Docker 이미지를 빌드하려면 다음 예시를 포함합니다:

    variables:
      DOCKER_DRIVER: overlay2
      IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
      GITLAB_RUNNER_VERSION: v17.3.0
      AWS_CLI_VERSION: 2.17.36
    
    stages:
      - build
    
    build-image:
      stage: build
      script:
        - echo "Logging into GitLab container registry..."
        - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
        - echo "Building Docker image..."
        - docker build --build-arg GITLAB_RUNNER_VERSION=${GITLAB_RUNNER_VERSION} --build-arg AWS_CLI_VERSION=${AWS_CLI_VERSION} -t ${IMAGE_NAME} .
        - echo "Pushing Docker image to GitLab container registry..."
        - docker push ${IMAGE_NAME}
      rules:
        - changes:
            - Dockerfile
    
  4. 러너를 등록합니다.

Docker 컨테이너에서 CI/CD 잡 실행

Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

전용 CI/CD 빌드 서버나 로컬 머신에서 호스팅되는 Docker 컨테이너에서 CI/CD 잡을 실행할 수 있습니다. Docker 컨테이너에서 CI/CD 잡을 실행하려면 다음이 필요합니다: Docker와 함께 GitLab Runner를 사용하려면 Docker 실행기를 사용하는 러너를 등록해야 합니다.

전용 CI/CD 빌드 서버나 로컬 머신에서 호스팅되는 Docker 컨테이너에서 CI/CD 잡을 실행할 수 있습니다.

Docker 컨테이너에서 CI/CD 잡을 실행하려면 다음이 필요합니다:

  1. 러너를 등록하고 Docker 실행기를 사용하도록 구성합니다.
  2. .gitlab-ci.yml 파일에서 CI/CD 잡을 실행할 컨테이너 이미지를 지정합니다.
  3. 선택 사항. MySQL 같은 다른 서비스를 컨테이너에서 실행합니다. .gitlab-ci.yml 파일에서 서비스를 지정하여 이를 수행합니다.

Docker 실행기를 사용하는 러너 등록#

Docker와 함께 GitLab Runner를 사용하려면 Docker 실행기를 사용하는 러너를 등록해야 합니다.

다음 예시는 서비스를 제공하기 위한 임시 템플릿을 설정하는 방법을 보여줍니다:

cat > /tmp/test-config.template.toml << EOF
[[runners]]
[runners.docker]
[[runners.docker.services]]
name = "postgres:latest"
[[runners.docker.services]]
name = "mysql:latest"
EOF

그런 다음 이 템플릿을 사용하여 러너를 등록합니다:

sudo gitlab-runner register \
  --url "https://gitlab.example.com/" \
  --token "$RUNNER_TOKEN" \
  --description "docker-ruby:2.6" \
  --executor "docker" \
  --template-config /tmp/test-config.template.toml \
  --docker-image ruby:3.3

등록된 러너는 ruby:2.6 Docker 이미지를 사용하고, 빌드 프로세스 중에 접근 가능한 두 서비스인 postgres:latestmysql:latest를 실행합니다.

이미지란#

image 키워드는 Docker 실행기가 CI/CD 잡을 실행하는 데 사용하는 Docker 이미지의 이름입니다.

기본적으로 실행기는 Docker Hub에서 이미지를 가져옵니다. 그러나 gitlab-runner/config.toml 파일에서 레지스트리 위치를 구성할 수 있습니다. 예를 들어, 로컬 이미지를 사용하도록 Docker 풀 정책을 설정할 수 있습니다.

이미지와 Docker Hub에 대한 자세한 내용은 Docker 개요를 참조하세요.

이미지 요구 사항#

CI/CD 잡을 실행하는 데 사용되는 이미지에는 다음 애플리케이션이 설치되어 있어야 합니다:

  • sh 또는 bash
  • grep

.gitlab-ci.yml 파일에서 image 정의#

모든 잡에 사용되는 이미지와 런타임 중에 사용할 서비스 목록을 정의할 수 있습니다:

default:
  image: ruby:2.6
  services:
    - postgres:16.10
  before_script:
    - bundle install

test:
  script:
    - bundle exec rake spec

이미지 이름은 다음 형식 중 하나여야 합니다:

  • image: <image-name> (latest 태그와 함께 <image-name> 사용과 동일)
  • image: <image-name>:<tag>
  • image: <image-name>@<digest>

확장 Docker 구성 옵션#

히스토리
  • GitLab 및 GitLab Runner 9.4에서 도입됨.

image 또는 services 항목에 문자열 또는 맵을 사용할 수 있습니다:

  • 문자열에는 전체 이미지 이름이 포함되어야 합니다(Docker Hub 이외의 레지스트리에서 이미지를 다운로드하려면 레지스트리 포함).
  • 맵에는 문자열 설정에 사용된 것과 동일한 이미지 이름인 name 옵션이 최소한 포함되어야 합니다.

예를 들어, 다음 두 정의는 동일합니다:

  • imageservices에 대한 문자열:

    image: "registry.example.com/my/image:latest"
    
    services:
      - postgresql:16.10
      - redis:latest
    
  • imageservices에 대한 맵. image:name이 필수입니다:

    image:
      name: "registry.example.com/my/image:latest"
    
    services:
      - name: postgresql:16.10
      - name: redis:latest
    

스크립트가 실행되는 위치#

Docker 컨테이너에서 CI 잡이 실행되면 before_script, script, after_script 명령은 /builds/<project-path>/ 디렉토리에서 실행됩니다. 이미지는 다른 기본 WORKDIR이 정의되어 있을 수 있습니다. WORKDIR로 이동하려면 WORKDIR을 환경 변수로 저장하여 잡 실행 중에 컨테이너에서 참조할 수 있도록 합니다.

이미지의 엔트리포인트 재정의#

히스토리
  • GitLab 및 GitLab Runner 9.4에서 도입됨. 확장 구성 옵션에 대해 자세히 읽어보세요.

사용 가능한 엔트리포인트 재정의 방법을 설명하기 전에 러너가 시작하는 방식을 설명하겠습니다. 러너는 CI/CD 잡에 사용되는 컨테이너에 Docker 이미지를 사용합니다:

  1. 러너가 정의된 엔트리포인트를 사용하여 Docker 컨테이너를 시작합니다. .gitlab-ci.yml 파일에서 재정의될 수 있는 Dockerfile의 기본값.
  2. 러너가 실행 중인 컨테이너에 연결됩니다.
  3. 러너가 스크립트( before_script, script, after_script의 조합)를 준비합니다.
  4. 러너가 스크립트를 컨테이너의 셸 stdin으로 보내고 출력을 받습니다.

Docker 이미지의 엔트리포인트를 재정의하려면 .gitlab-ci.yml 파일에서:

  • Docker 17.06 이상에서는 entrypoint를 빈 값으로 설정합니다.
  • Docker 17.03 이하에서는 entrypoint/bin/sh -c, /bin/bash -c 또는 이미지에서 사용 가능한 동등한 셸로 설정합니다.

image:entrypoint의 구문은 Dockerfile ENTRYPOINT와 유사합니다.

SQL 데이터베이스가 있는 super/sql:experimental 이미지가 있다고 가정해봅니다. 이 데이터베이스 바이너리로 일부 테스트를 실행하고 싶기 때문에 잡의 기본 이미지로 사용하려고 합니다. 이 이미지가 엔트리포인트로 /usr/bin/super-sql run이 구성되어 있다고 가정해보겠습니다. 컨테이너가 추가 옵션 없이 시작되면 데이터베이스의 프로세스를 실행합니다. 러너는 이미지에 엔트리포인트가 없거나 엔트리포인트가 셸 명령을 시작하도록 준비되어 있다고 기대합니다.

확장 Docker 구성 옵션을 사용하면 다음 대신:

  • super/sql:experimental을 기반으로 자체 이미지 생성.
  • ENTRYPOINT를 셸로 설정.
  • CI 잡에서 새 이미지 사용.

이제 .gitlab-ci.yml 파일에서 entrypoint를 정의할 수 있습니다.

Docker 17.06 이상:

image:
  name: super/sql:experimental
  entrypoint: [""]

Docker 17.03 이하:

image:
  name: super/sql:experimental
  entrypoint: ["/bin/sh", "-c"]

config.toml에서 이미지 및 서비스 정의#

config.toml 파일에서 다음을 정의할 수 있습니다:

[runners.docker]
  image = "ruby:latest"
  services = ["mysql:latest", "postgres:latest"]

이 방식으로 정의된 이미지 및 서비스는 해당 러너가 실행하는 모든 잡에 추가됩니다.

비공개 컨테이너 레지스트리에서 이미지 접근#

비공개 컨테이너 레지스트리에 접근하기 위해 GitLab Runner 프로세스는 다음을 사용할 수 있습니다:

동일한 GitLab 인스턴스에서 GitLab 컨테이너 레지스트리를 사용하는 경우, GitLab은 이 레지스트리에 대한 기본 자격 증명을 제공합니다. 이 자격 증명을 사용하면 인증에 CI_JOB_TOKEN이 사용됩니다. 잡 토큰을 사용하려면 잡을 시작하는 사용자가 비공개 이미지가 호스팅된 프로젝트에 대한 개발자, 유지 관리자 또는 소유자 역할이 있어야 합니다. 비공개 이미지를 호스팅하는 프로젝트도 다른 프로젝트가 잡 토큰으로 인증하도록 허용해야 합니다. 이 접근은 기본적으로 비활성화되어 있습니다. 자세한 내용은 CI/CD 잡 토큰을 참조하세요.

사용할 옵션을 정의하기 위해 러너 프로세스는 다음 순서로 구성을 읽습니다:

  • /root/.docker 디렉토리의 config.json 파일.
  • DOCKER_AUTH_CONFIG CI/CD 변수.
  • 러너의 config.toml 파일에 설정된 DOCKER_AUTH_CONFIG 환경 변수.
  • 프로세스를 실행하는 사용자의 $HOME/.docker 디렉토리의 config.json 파일. --user 플래그가 제공되어 자식 프로세스를 비권한 사용자로 실행하는 경우 기본 러너 프로세스 사용자의 홈 디렉토리가 사용됩니다.

요구 사항 및 제한 사항#

  • 자격 증명 저장소자격 증명 도우미는 바이너리를 GitLab Runner $PATH에 추가해야 하며 이를 위한 접근 권한이 필요합니다. 따라서 이러한 기능은 인스턴스 러너나 러너가 설치된 환경에 접근할 수 없는 다른 러너에서는 사용할 수 없습니다.

정적으로 정의된 자격 증명 사용#

두 가지 방법으로 비공개 레지스트리에 접근할 수 있습니다. 두 방법 모두 적절한 인증 정보와 함께 CI/CD 변수 DOCKER_AUTH_CONFIG를 설정해야 합니다.

  1. 잡별: 하나의 잡에 비공개 레지스트리 접근을 구성하려면 DOCKER_AUTH_CONFIGCI/CD 변수로 추가합니다.
  2. 러너별: 러너의 모든 잡이 비공개 레지스트리에 접근할 수 있도록 구성하려면 러너 구성에서 DOCKER_AUTH_CONFIG를 환경 변수로 추가합니다.

각 예시는 다음 섹션을 참조하세요.

DOCKER_AUTH_CONFIG 데이터 결정#

예를 들어, registry.example.com:5000/private/image:latest 이미지를 사용하려 한다고 가정해봅니다. 이 이미지는 비공개이며 비공개 컨테이너 레지스트리에 로그인해야 합니다.

로그인 자격 증명이 다음과 같다고 가정해봅니다:

registry registry.example.com:5000
username my_username
password my_password

DOCKER_AUTH_CONFIG의 값을 결정하는 데 다음 방법 중 하나를 사용하세요:

  • 로컬 머신에서 docker login을 수행합니다:

    docker login registry.example.com:5000 --username my_username --password my_password
    

    그런 다음 ~/.docker/config.json의 내용을 복사합니다.

    컴퓨터에서 레지스트리에 접근할 필요가 없는 경우 docker logout을 수행할 수 있습니다:

    docker logout registry.example.com:5000
    
  • 일부 설정에서 Docker 클라이언트가 사용 가능한 시스템 키 저장소를 사용하여 docker login의 결과를 저장할 수 있습니다. 이 경우 ~/.docker/config.json을 읽는 것이 불가능하므로 필요한 base64 인코딩 버전의 ${username}:${password}를 준비하고 Docker 구성 JSON을 수동으로 생성해야 합니다. 터미널을 열고 다음 명령을 실행합니다:

    # The use of printf (as opposed to echo) prevents encoding a newline in the password.
    printf "my_username:my_password" | openssl base64 -A
    
    # Example output to copy
    bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=
    

    [!note] 사용자 이름에 @와 같은 특수 문자가 포함된 경우 인증 문제를 방지하기 위해 백슬래시(\)로 이스케이프해야 합니다.

    다음과 같이 Docker JSON 구성 내용을 만듭니다:

    {
        "auths": {
            "registry.example.com:5000": {
                "auth": "(Base64 content from above)"
            }
        }
    }
    

잡 구성#

registry.example.com:5000에 대한 접근이 가능한 단일 잡을 구성하려면 다음 단계를 따르세요:

  1. Docker 구성 파일의 내용을 값으로 하는 CI/CD 변수 DOCKER_AUTH_CONFIG를 만듭니다:

    {
        "auths": {
            "registry.example.com:5000": {
                "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
            }
        }
    }
    
  2. 이제 .gitlab-ci.yml 파일의 image 또는 services에 정의된 registry.example.com:5000의 비공개 이미지를 사용할 수 있습니다:

    image: registry.example.com:5000/namespace/image:tag
    

    이전 예시에서 GitLab Runner는 registry.example.com:5000에서 이미지 namespace/image:tag를 찾습니다.

이전에 설명한 대로 "auths" 해시에 더 많은 레지스트리를 추가하여 원하는 만큼 많은 레지스트리에 대한 구성을 추가할 수 있습니다.

러너가 DOCKER_AUTH_CONFIG를 매치시키기 위해서는 모든 곳에 전체 hostname:port 조합이 필요합니다. 예를 들어, .gitlab-ci.yml 파일에 registry.example.com:5000/namespace/image:tag가 지정된 경우, DOCKER_AUTH_CONFIG에도 registry.example.com:5000이 지정되어야 합니다. registry.example.com만 지정하는 것은 작동하지 않습니다.

러너 구성#

동일한 레지스트리에 접근하는 파이프라인이 많은 경우 러너 수준에서 레지스트리 접근을 설정해야 합니다. 이렇게 하면 파이프라인 작성자가 적절한 러너에서 잡을 실행하는 것만으로 비공개 레지스트리에 접근할 수 있습니다. 또한 레지스트리 변경 및 자격 증명 교체를 단순화하는 데 도움이 됩니다.

이는 해당 러너의 모든 잡이 프로젝트 간에도 동일한 권한으로 레지스트리에 접근할 수 있음을 의미합니다. 레지스트리에 대한 접근을 제어해야 하는 경우 러너에 대한 접근을 제어해야 합니다.

러너에 DOCKER_AUTH_CONFIG를 추가하려면:

  1. 다음과 같이 러너의 config.toml 파일을 수정합니다:

    [[runners]]
      environment = ["DOCKER_AUTH_CONFIG={\"auths\":{\"registry.example.com:5000\":{\"auth\":\"bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=\"}}}"]
    
    • DOCKER_AUTH_CONFIG 데이터에 포함된 큰따옴표는 TOML로 해석되지 않도록 백슬래시로 이스케이프해야 합니다.
    • environment 옵션은 목록입니다. 러너에 기존 항목이 있을 수 있으며 이를 대체하는 것이 아니라 목록에 추가해야 합니다.
  2. 러너 서비스를 다시 시작합니다.

자격 증명 저장소 사용#

자격 증명 저장소를 구성하려면:

  1. 자격 증명 저장소를 사용하려면 특정 키체인 또는 외부 저장소와 상호 작용하는 외부 도우미 프로그램이 필요합니다. 도우미 프로그램이 GitLab Runner $PATH에 있는지 확인합니다.

  2. GitLab Runner가 이를 사용하도록 합니다. 다음 옵션 중 하나를 사용하여 이를 달성할 수 있습니다:

    • Docker 구성 파일의 내용을 값으로 하는 CI/CD 변수 DOCKER_AUTH_CONFIG를 만듭니다:

        {
          "credsStore": "osxkeychain"
        }
      
    • 또는 자체 관리형 러너를 실행 중인 경우 JSON을 ${GITLAB_RUNNER_HOME}/.docker/config.json에 추가합니다. GitLab Runner가 이 구성 파일을 읽고 이 특정 저장소에 필요한 도우미를 사용합니다.

credsStore모든 레지스트리에 접근하는 데 사용됩니다. 비공개 레지스트리의 이미지와 Docker Hub의 공개 이미지를 모두 사용하는 경우 Docker Hub에서 가져오기가 실패합니다. Docker 데몬은 모든 레지스트리에 동일한 자격 증명을 사용하려고 합니다.

자격 증명 도우미 사용#

예를 들어, <aws_account_id>.dkr.ecr.<region>.amazonaws.com/private/image:latest 이미지를 사용하려 한다고 가정해봅니다. 이 이미지는 비공개이며 비공개 컨테이너 레지스트리에 로그인해야 합니다.

<aws_account_id>.dkr.ecr.<region>.amazonaws.com에 대한 접근을 구성하려면 다음 단계를 따르세요:

  1. docker-credential-ecr-login이 GitLab Runner $PATH에 있는지 확인합니다.

  2. 다음 AWS 자격 증명 설정 중 하나를 완료합니다. GitLab Runner Manager가 자격 증명을 획득하고 러너에 전달합니다. GitLab Runner가 자격 증명에 접근할 수 있는지 확인합니다.

  3. GitLab Runner가 이를 사용하도록 합니다. 다음 옵션 중 하나를 사용하여 이를 달성할 수 있습니다:

    • Docker 구성 파일의 내용을 값으로 하는 CI/CD 변수 DOCKER_AUTH_CONFIG를 만듭니다:

      {
        "credHelpers": {
          "<aws_account_id>.dkr.ecr.<region>.amazonaws.com": "ecr-login"
        }
      }
      

      이는 특정 레지스트리에 대한 자격 증명 도우미를 사용하도록 Docker를 구성합니다.

      대신 모든 Amazon Elastic Container Registry(ECR) 레지스트리에 자격 증명 도우미를 사용하도록 Docker를 구성할 수 있습니다:

      {
        "credsStore": "ecr-login"
      }
      

      [!note] {"credsStore": "ecr-login"}을 사용하는 경우 AWS 공유 구성 파일(~/.aws/config)에서 지역을 명시적으로 설정합니다. ECR 자격 증명 도우미가 인증 토큰을 검색할 때 지역을 지정해야 합니다.

    • 또는 자체 관리형 러너를 실행 중인 경우 이전 JSON을 ${GITLAB_RUNNER_HOME}/.docker/config.json에 추가합니다. GitLab Runner가 이 구성 파일을 읽고 이 특정 저장소에 필요한 도우미를 사용합니다.

  4. 이제 .gitlab-ci.yml 파일의 image 및/또는 services에 정의된 <aws_account_id>.dkr.ecr.<region>.amazonaws.com의 비공개 이미지를 사용할 수 있습니다:

    image: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/private/image:latest
    

    이 예시에서 GitLab Runner는 <aws_account_id>.dkr.ecr.<region>.amazonaws.com에서 이미지 private/image:latest를 찾습니다.

"credHelpers" 해시에 더 많은 레지스트리를 추가하여 원하는 만큼 많은 레지스트리에 대한 구성을 추가할 수 있습니다.

체크섬을 사용하여 이미지 보안 유지#

.gitlab-ci.yml 파일의 잡 정의에 이미지 체크섬을 사용하여 이미지의 무결성을 확인합니다. 이미지 무결성 확인에 실패하면 수정된 컨테이너를 사용할 수 없습니다.

이미지 체크섬을 사용하려면 끝에 체크섬을 추가해야 합니다:

image: ruby:2.6.8@sha256:d1dbaf9665fe8b2175198e49438092fdbcf4d8934200942b94425301b17853c7

이미지 체크섬을 얻으려면 이미지 TAG 탭에서 DIGEST 열을 봅니다. 예를 들어, Ruby 이미지를 봅니다. 체크섬은 6155f0235e95와 같은 임의의 문자열입니다.

또한 docker images --digests 명령으로 시스템의 모든 이미지의 체크섬을 얻을 수 있습니다:

❯ docker images --digests
REPOSITORY                                                        TAG       DIGEST                                                                    (...)
gitlab/gitlab-ee                                                  latest    sha256:723aa6edd8f122d50cae490b1743a616d54d4a910db892314d68470cc39dfb24   (...)
gitlab/gitlab-runner                                              latest    sha256:4a18a80f5be5df44cb7575f6b89d1fdda343297c6fd666c015c0e778b276e726   (...)

사용자 정의 GitLab Runner Docker 이미지 만들기#

AWS CLI와 Amazon ECR 자격 증명 도우미를 패키지로 포함하는 사용자 정의 GitLab Runner Docker 이미지를 만들 수 있습니다. 이 설정은 특히 컨테이너화된 애플리케이션에서 AWS 서비스와의 안전하고 효율적인 상호 작용을 용이하게 합니다. 예를 들어, Amazon ECR에서 Docker 이미지를 관리, 배포, 업데이트하는 데 이 설정을 사용합니다. 이 설정은 시간이 많이 걸리고 오류가 발생하기 쉬운 구성 및 수동 자격 증명 관리를 방지하는 데 도움이 됩니다.

  1. GitLab과 AWS 인증.

  2. 다음 내용으로 Dockerfile을 만듭니다:

    # Control package versions
    ARG GITLAB_RUNNER_VERSION=v17.3.0
    ARG AWS_CLI_VERSION=2.17.36
    
    # AWS CLI and Amazon ECR Credential Helper
    FROM amazonlinux as aws-tools
    RUN set -e \
        && yum update -y \
        && yum install -y --allowerasing git make gcc curl unzip \
        && curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" --output "awscliv2.zip" \
        && unzip awscliv2.zip && ./aws/install -i /usr/local/bin \
        && yum clean all
    
    # Download and install ECR Credential Helper
    RUN curl --location --output  /usr/local/bin/docker-credential-ecr-login "https://github.com/awslabs/amazon-ecr-credential-helper/releases/latest/download/docker-credential-ecr-login-linux-amd64"
    RUN chmod +x /usr/local/bin/docker-credential-ecr-login
    
    # Configure the ECR Credential Helper
    RUN mkdir -p /root/.docker
    RUN echo '{ "credsStore": "ecr-login" }' > /root/.docker/config.json
    
    # Final image based on GitLab Runner
    FROM gitlab/gitlab-runner:${GITLAB_RUNNER_VERSION}
    
    # Install necessary packages
    RUN apt-get update \
        && apt-get install -y --no-install-recommends jq procps curl unzip groff libgcrypt20 tar gzip less openssh-client \
        && apt-get clean && rm -rf /var/lib/apt/lists/*
    
    # Copy AWS CLI and Amazon ECR Credential Helper binaries
    COPY --from=aws-tools /usr/local/bin/ /usr/local/bin/
    
    # Copy ECR Credential Helper Configuration
    COPY --from=aws-tools /root/.docker/config.json /root/.docker/config.json
    
  3. .gitlab-ci.yml에서 사용자 정의 GitLab Runner Docker 이미지를 빌드하려면 다음 예시를 포함합니다:

    variables:
      DOCKER_DRIVER: overlay2
      IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
      GITLAB_RUNNER_VERSION: v17.3.0
      AWS_CLI_VERSION: 2.17.36
    
    stages:
      - build
    
    build-image:
      stage: build
      script:
        - echo "Logging into GitLab container registry..."
        - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
        - echo "Building Docker image..."
        - docker build --build-arg GITLAB_RUNNER_VERSION=${GITLAB_RUNNER_VERSION} --build-arg AWS_CLI_VERSION=${AWS_CLI_VERSION} -t ${IMAGE_NAME} .
        - echo "Pushing Docker image to GitLab container registry..."
        - docker push ${IMAGE_NAME}
      rules:
        - changes:
            - Dockerfile
    
  4. 러너를 등록합니다.