InfoGrab Docs

프록시 뒤에서 GitLab Runner 실행

요약

이 가이드는 특히 Docker 실행자를 사용하는 GitLab Runner가 프록시 뒤에서 작동하도록 설정하는 것을 목표로 합니다. 계속하기 전에 동일한 머신에 Docker와 GitLab Runner가 이미 설치되어 있는지 확인하세요.

이 가이드는 특히 Docker 실행자를 사용하는 GitLab Runner가 프록시 뒤에서 작동하도록 설정하는 것을 목표로 합니다.

계속하기 전에 동일한 머신에 DockerGitLab Runner가 이미 설치되어 있는지 확인하세요.

cntlm 설정#

Note

인증 없이 프록시를 이미 사용하고 있다면 이 섹션은 선택 사항이며, 이미지 다운로드를 위한 Docker 설정으로 건너뛸 수 있습니다. cntlm 설정은 인증이 필요한 프록시 뒤에 있는 경우에만 필요하지만, 어떤 경우에도 사용하는 것을 권장합니다.

cntlm은 로컬 프록시로 사용할 수 있는 Linux 프록시로, 수동으로 모든 곳에 프록시 세부 정보를 추가하는 것에 비해 2가지 주요 장점이 있습니다:

  • 자격 증명을 변경해야 하는 단일 위치
  • Docker 러너에서 자격 증명에 접근할 수 없음

cntlm을 설치했다고 가정하면, 먼저 설정해야 합니다.

docker0 인터페이스에서 수신하도록 cntlm 설정#

보안 강화 및 인터넷으로부터의 보호를 위해, 컨테이너가 접근할 수 있는 IP 주소를 가진 docker0 인터페이스에서만 수신하도록 cntlm을 바인딩합니다. Docker 호스트의 cntlm이 이 주소에서만 바인딩되도록 하면, Docker 컨테이너는 접근할 수 있지만 외부에서는 접근할 수 없습니다.

  1. Docker가 사용하는 IP를 찾습니다:

    ip -4 -oneline addr show dev docker0
    

    IP 주소는 일반적으로 172.17.0.1이며, 이를 docker0_interface_ip라고 부르겠습니다.

  2. cntlm 설정 파일(/etc/cntlm.conf)을 엽니다. 사용자명, 비밀번호, 도메인 및 프록시 호스트를 입력하고, 이전 단계에서 찾은 Listen IP 주소를 설정합니다. 다음과 같이 보여야 합니다:

    Username     testuser
    Domain       corp-uk
    Password     password
    Proxy        10.0.0.41:8080
    Proxy        10.0.0.42:8080
    Listen       172.17.0.1:3128 # docker0 인터페이스 IP로 변경
    
  3. 변경 사항을 저장하고 서비스를 재시작합니다:

    sudo systemctl restart cntlm
    

이미지 다운로드를 위한 Docker 설정#

Note

다음 내용은 systemd를 지원하는 OS에 적용됩니다.

프록시 사용 방법에 대한 정보는 Docker 문서를 참조하세요.

서비스 파일은 다음과 같이 보여야 합니다:

[Service]
Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"

GitLab Runner 설정에 프록시 변수 추가#

GitLab Runner가 프록시를 통해 GitLab.com에 연결할 수 있도록 프록시 변수를 GitLab Runner 설정에도 추가해야 합니다.

이 작업은 위의 Docker 서비스에 프록시를 추가하는 것과 동일합니다:

  1. gitlab-runner 서비스를 위한 systemd 드롭-인 디렉터리를 생성합니다:

    mkdir /etc/systemd/system/gitlab-runner.service.d
    
  2. HTTP_PROXY 환경 변수를 추가하는 /etc/systemd/system/gitlab-runner.service.d/http-proxy.conf 파일을 생성합니다:

    [Service]
    Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
    Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
    

    GitLab Runner를 GitLab Self-Managed 인스턴스와 같은 내부 URL에 연결하려면 NO_PROXY 환경 변수에 값을 설정하세요.

    [Service]
    Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
    Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
    Environment="NO_PROXY=gitlab.example.com"
    
  3. 파일을 저장하고 변경 사항을 적용합니다:

    systemctl daemon-reload
    
  4. GitLab Runner를 재시작합니다:

    sudo systemctl restart gitlab-runner
    
  5. 설정이 로드되었는지 확인합니다:

    systemctl show --property=Environment gitlab-runner
    

    다음이 표시되어야 합니다:

    Environment=HTTP_PROXY=http://docker0_interface_ip:3128/ HTTPS_PROXY=http://docker0_interface_ip:3128/
    

Docker 컨테이너에 프록시 추가#

러너를 등록한 후, 프록시 설정을 Docker 컨테이너에 전파할 수 있습니다 (예: git clone을 위해).

이렇게 하려면 /etc/gitlab-runner/config.toml을 편집하고 [[runners]] 섹션에 다음을 추가해야 합니다:

pre_get_sources_script = "git config --global http.proxy $HTTP_PROXY; git config --global https.proxy $HTTPS_PROXY"
environment = ["https_proxy=http://docker0_interface_ip:3128", "http_proxy=http://docker0_interface_ip:3128", "HTTPS_PROXY=docker0_interface_ip:3128", "HTTP_PROXY=docker0_interface_ip:3128"]

docker0_interface_ipdocker0 인터페이스의 IP 주소입니다.

Note

예시에서 소문자와 대문자 변수를 모두 설정하는 이유는 일부 프로그램은 HTTP_PROXY를 기대하고 다른 프로그램은 http_proxy를 기대하기 때문입니다. 안타깝게도 이러한 종류의 환경 변수에 대한 표준이 없습니다.

dind 서비스 사용 시 프록시 설정#

Docker-in-Docker 실행자 (dind)를 사용할 때, NO_PROXY 환경 변수에 docker:2375,docker:2376을 지정해야 할 수 있습니다. 포트가 필요하며, 그렇지 않으면 docker push가 차단됩니다.

dinddockerd와 로컬 docker 클라이언트 간의 통신(여기에 설명됨: https://hub.docker.com/_/docker/)은 root의 Docker 설정에 있는 프록시 변수를 사용합니다.

이를 설정하려면 /root/.docker/config.json을 편집하여 전체 프록시 설정을 포함시켜야 합니다. 예를 들면:

{
    "proxies": {
        "default": {
            "httpProxy": "http://proxy:8080",
            "httpsProxy": "http://proxy:8080",
            "noProxy": "docker:2375,docker:2376"
        }
    }
}

Docker 실행자의 컨테이너에 설정을 전달하려면, 컨테이너 내부에도 $HOME/.docker/config.json을 생성해야 합니다. 이는 .gitlab-ci.yml에서 before_script로 스크립팅할 수 있습니다. 예를 들면:

before_script:
  - mkdir -p $HOME/.docker/
  - 'echo "{ \"proxies\": { \"default\": { \"httpProxy\": \"$HTTP_PROXY\", \"httpsProxy\": \"$HTTPS_PROXY\", \"noProxy\": \"$NO_PROXY\" } } }" > $HOME/.docker/config.json'

또는 대안으로, 영향을 받는 gitlab-runner 설정(/etc/gitlab-runner/config.toml)에서:

[[runners]]
  pre_build_script = "mkdir -p $HOME/.docker/ && echo \"{ \\\"proxies\\\": { \\\"default\\\": { \\\"httpProxy\\\": \\\"$HTTP_PROXY\\\", \\\"httpsProxy\\\": \\\"$HTTPS_PROXY\\\", \\\"noProxy\\\": \\\"$NO_PROXY\\\" } } }\" > $HOME/.docker/config.json"
Note

이렇게 하면 TOML 파일 내의 단일 문자열로 지정된 shell이 있는 JSON 파일이 생성되므로 "의 추가 이스케이프 레벨이 필요합니다. 이것은 YAML이 아니므로 :를 이스케이프하지 마세요.

NO_PROXY 목록을 확장해야 하는 경우, 와일드카드 *는 접미사에만 작동하며 접두사나 CIDR 표기법에는 작동하지 않습니다. 자세한 내용은 https://github.com/moby/moby/issues/9145https://unix.stackexchange.com/questions/23452/set-a-network-range-in-the-no-proxy-environment-variable을 참조하세요.

속도 제한된 요청 처리#

GitLab 인스턴스는 남용을 방지하기 위해 API 요청에 속도 제한이 있는 리버스 프록시 뒤에 있을 수 있습니다. GitLab Runner는 API에 여러 요청을 보내며 이러한 속도 제한을 초과할 수 있습니다.

결과적으로, GitLab Runner는 다음 재시도 로직을 사용하여 속도 제한 시나리오를 처리합니다:

재시도 로직#

GitLab Runner가 429 Too Many Requests 응답을 받으면 다음 재시도 순서를 따릅니다:

  1. 러너는 응답 헤더에서 RateLimit-ResetTime 헤더를 확인합니다.
    • RateLimit-ResetTime 헤더는 Wed, 21 Oct 2015 07:28:00 GMT와 같이 유효한 HTTP 날짜(RFC1123)값을 가져야 합니다.
    • 헤더가 존재하고 유효한 값을 가지면, 러너는 지정된 시간까지 기다렸다가 다른 요청을 보냅니다.
  2. RateLimit-ResetTime 헤더가 유효하지 않거나 없으면, 러너는 응답 헤더에서 Retry-After 헤더를 확인합니다.
    • Retry-After 헤더는 Retry-After: 30과 같이 초 형식의 값을 가져야 합니다.
    • 헤더 형식이 존재하고 유효한 값을 가지면, 러너는 지정된 시간까지 기다렸다가 다른 요청을 보냅니다.
  3. 두 헤더가 모두 없거나 유효하지 않으면, 러너는 기본 간격 동안 기다렸다가 다른 요청을 보냅니다.

러너는 실패한 요청을 최대 5번까지 재시도합니다. 모든 재시도가 실패하면, 러너는 최종 응답의 오류를 기록합니다.

지원되는 헤더 형식#

헤더 형식 예시
RateLimit-ResetTime HTTP Date (RFC1123) Wed, 21 Oct 2015 07:28:00 GMT
Retry-After 30
Note

RateLimit-ResetTime 헤더는 모든 헤더 키가 http.CanonicalHeaderKey 함수를 통해 실행되기 때문에 대소문자를 구분하지 않습니다.

프록시 뒤에서 GitLab Runner 실행

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

이 가이드는 특히 Docker 실행자를 사용하는 GitLab Runner가 프록시 뒤에서 작동하도록 설정하는 것을 목표로 합니다. 계속하기 전에 동일한 머신에 Docker와 GitLab Runner가 이미 설치되어 있는지 확인하세요.

이 가이드는 특히 Docker 실행자를 사용하는 GitLab Runner가 프록시 뒤에서 작동하도록 설정하는 것을 목표로 합니다.

계속하기 전에 동일한 머신에 DockerGitLab Runner가 이미 설치되어 있는지 확인하세요.

cntlm 설정#

Note

인증 없이 프록시를 이미 사용하고 있다면 이 섹션은 선택 사항이며, 이미지 다운로드를 위한 Docker 설정으로 건너뛸 수 있습니다. cntlm 설정은 인증이 필요한 프록시 뒤에 있는 경우에만 필요하지만, 어떤 경우에도 사용하는 것을 권장합니다.

cntlm은 로컬 프록시로 사용할 수 있는 Linux 프록시로, 수동으로 모든 곳에 프록시 세부 정보를 추가하는 것에 비해 2가지 주요 장점이 있습니다:

  • 자격 증명을 변경해야 하는 단일 위치
  • Docker 러너에서 자격 증명에 접근할 수 없음

cntlm을 설치했다고 가정하면, 먼저 설정해야 합니다.

docker0 인터페이스에서 수신하도록 cntlm 설정#

보안 강화 및 인터넷으로부터의 보호를 위해, 컨테이너가 접근할 수 있는 IP 주소를 가진 docker0 인터페이스에서만 수신하도록 cntlm을 바인딩합니다. Docker 호스트의 cntlm이 이 주소에서만 바인딩되도록 하면, Docker 컨테이너는 접근할 수 있지만 외부에서는 접근할 수 없습니다.

  1. Docker가 사용하는 IP를 찾습니다:

    ip -4 -oneline addr show dev docker0
    

    IP 주소는 일반적으로 172.17.0.1이며, 이를 docker0_interface_ip라고 부르겠습니다.

  2. cntlm 설정 파일(/etc/cntlm.conf)을 엽니다. 사용자명, 비밀번호, 도메인 및 프록시 호스트를 입력하고, 이전 단계에서 찾은 Listen IP 주소를 설정합니다. 다음과 같이 보여야 합니다:

    Username     testuser
    Domain       corp-uk
    Password     password
    Proxy        10.0.0.41:8080
    Proxy        10.0.0.42:8080
    Listen       172.17.0.1:3128 # docker0 인터페이스 IP로 변경
    
  3. 변경 사항을 저장하고 서비스를 재시작합니다:

    sudo systemctl restart cntlm
    

이미지 다운로드를 위한 Docker 설정#

Note

다음 내용은 systemd를 지원하는 OS에 적용됩니다.

프록시 사용 방법에 대한 정보는 Docker 문서를 참조하세요.

서비스 파일은 다음과 같이 보여야 합니다:

[Service]
Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"

GitLab Runner 설정에 프록시 변수 추가#

GitLab Runner가 프록시를 통해 GitLab.com에 연결할 수 있도록 프록시 변수를 GitLab Runner 설정에도 추가해야 합니다.

이 작업은 위의 Docker 서비스에 프록시를 추가하는 것과 동일합니다:

  1. gitlab-runner 서비스를 위한 systemd 드롭-인 디렉터리를 생성합니다:

    mkdir /etc/systemd/system/gitlab-runner.service.d
    
  2. HTTP_PROXY 환경 변수를 추가하는 /etc/systemd/system/gitlab-runner.service.d/http-proxy.conf 파일을 생성합니다:

    [Service]
    Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
    Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
    

    GitLab Runner를 GitLab Self-Managed 인스턴스와 같은 내부 URL에 연결하려면 NO_PROXY 환경 변수에 값을 설정하세요.

    [Service]
    Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
    Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
    Environment="NO_PROXY=gitlab.example.com"
    
  3. 파일을 저장하고 변경 사항을 적용합니다:

    systemctl daemon-reload
    
  4. GitLab Runner를 재시작합니다:

    sudo systemctl restart gitlab-runner
    
  5. 설정이 로드되었는지 확인합니다:

    systemctl show --property=Environment gitlab-runner
    

    다음이 표시되어야 합니다:

    Environment=HTTP_PROXY=http://docker0_interface_ip:3128/ HTTPS_PROXY=http://docker0_interface_ip:3128/
    

Docker 컨테이너에 프록시 추가#

러너를 등록한 후, 프록시 설정을 Docker 컨테이너에 전파할 수 있습니다 (예: git clone을 위해).

이렇게 하려면 /etc/gitlab-runner/config.toml을 편집하고 [[runners]] 섹션에 다음을 추가해야 합니다:

pre_get_sources_script = "git config --global http.proxy $HTTP_PROXY; git config --global https.proxy $HTTPS_PROXY"
environment = ["https_proxy=http://docker0_interface_ip:3128", "http_proxy=http://docker0_interface_ip:3128", "HTTPS_PROXY=docker0_interface_ip:3128", "HTTP_PROXY=docker0_interface_ip:3128"]

docker0_interface_ipdocker0 인터페이스의 IP 주소입니다.

Note

예시에서 소문자와 대문자 변수를 모두 설정하는 이유는 일부 프로그램은 HTTP_PROXY를 기대하고 다른 프로그램은 http_proxy를 기대하기 때문입니다. 안타깝게도 이러한 종류의 환경 변수에 대한 표준이 없습니다.

dind 서비스 사용 시 프록시 설정#

Docker-in-Docker 실행자 (dind)를 사용할 때, NO_PROXY 환경 변수에 docker:2375,docker:2376을 지정해야 할 수 있습니다. 포트가 필요하며, 그렇지 않으면 docker push가 차단됩니다.

dinddockerd와 로컬 docker 클라이언트 간의 통신(여기에 설명됨: https://hub.docker.com/_/docker/)은 root의 Docker 설정에 있는 프록시 변수를 사용합니다.

이를 설정하려면 /root/.docker/config.json을 편집하여 전체 프록시 설정을 포함시켜야 합니다. 예를 들면:

{
    "proxies": {
        "default": {
            "httpProxy": "http://proxy:8080",
            "httpsProxy": "http://proxy:8080",
            "noProxy": "docker:2375,docker:2376"
        }
    }
}

Docker 실행자의 컨테이너에 설정을 전달하려면, 컨테이너 내부에도 $HOME/.docker/config.json을 생성해야 합니다. 이는 .gitlab-ci.yml에서 before_script로 스크립팅할 수 있습니다. 예를 들면:

before_script:
  - mkdir -p $HOME/.docker/
  - 'echo "{ \"proxies\": { \"default\": { \"httpProxy\": \"$HTTP_PROXY\", \"httpsProxy\": \"$HTTPS_PROXY\", \"noProxy\": \"$NO_PROXY\" } } }" > $HOME/.docker/config.json'

또는 대안으로, 영향을 받는 gitlab-runner 설정(/etc/gitlab-runner/config.toml)에서:

[[runners]]
  pre_build_script = "mkdir -p $HOME/.docker/ && echo \"{ \\\"proxies\\\": { \\\"default\\\": { \\\"httpProxy\\\": \\\"$HTTP_PROXY\\\", \\\"httpsProxy\\\": \\\"$HTTPS_PROXY\\\", \\\"noProxy\\\": \\\"$NO_PROXY\\\" } } }\" > $HOME/.docker/config.json"
Note

이렇게 하면 TOML 파일 내의 단일 문자열로 지정된 shell이 있는 JSON 파일이 생성되므로 "의 추가 이스케이프 레벨이 필요합니다. 이것은 YAML이 아니므로 :를 이스케이프하지 마세요.

NO_PROXY 목록을 확장해야 하는 경우, 와일드카드 *는 접미사에만 작동하며 접두사나 CIDR 표기법에는 작동하지 않습니다. 자세한 내용은 https://github.com/moby/moby/issues/9145https://unix.stackexchange.com/questions/23452/set-a-network-range-in-the-no-proxy-environment-variable을 참조하세요.

속도 제한된 요청 처리#

GitLab 인스턴스는 남용을 방지하기 위해 API 요청에 속도 제한이 있는 리버스 프록시 뒤에 있을 수 있습니다. GitLab Runner는 API에 여러 요청을 보내며 이러한 속도 제한을 초과할 수 있습니다.

결과적으로, GitLab Runner는 다음 재시도 로직을 사용하여 속도 제한 시나리오를 처리합니다:

재시도 로직#

GitLab Runner가 429 Too Many Requests 응답을 받으면 다음 재시도 순서를 따릅니다:

  1. 러너는 응답 헤더에서 RateLimit-ResetTime 헤더를 확인합니다.
    • RateLimit-ResetTime 헤더는 Wed, 21 Oct 2015 07:28:00 GMT와 같이 유효한 HTTP 날짜(RFC1123)값을 가져야 합니다.
    • 헤더가 존재하고 유효한 값을 가지면, 러너는 지정된 시간까지 기다렸다가 다른 요청을 보냅니다.
  2. RateLimit-ResetTime 헤더가 유효하지 않거나 없으면, 러너는 응답 헤더에서 Retry-After 헤더를 확인합니다.
    • Retry-After 헤더는 Retry-After: 30과 같이 초 형식의 값을 가져야 합니다.
    • 헤더 형식이 존재하고 유효한 값을 가지면, 러너는 지정된 시간까지 기다렸다가 다른 요청을 보냅니다.
  3. 두 헤더가 모두 없거나 유효하지 않으면, 러너는 기본 간격 동안 기다렸다가 다른 요청을 보냅니다.

러너는 실패한 요청을 최대 5번까지 재시도합니다. 모든 재시도가 실패하면, 러너는 최종 응답의 오류를 기록합니다.

지원되는 헤더 형식#

헤더 형식 예시
RateLimit-ResetTime HTTP Date (RFC1123) Wed, 21 Oct 2015 07:28:00 GMT
Retry-After 30
Note

RateLimit-ResetTime 헤더는 모든 헤더 키가 http.CanonicalHeaderKey 함수를 통해 실행되기 때문에 대소문자를 구분하지 않습니다.