프록시 뒤에서 GitLab Runner 실행
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
이 가이드는 특히 Docker 실행자를 사용하는 GitLab Runner가 프록시 뒤에서 작동하도록 설정하는 것을 목표로 합니다. 계속하기 전에 동일한 머신에 Docker와 GitLab Runner가 이미 설치되어 있는지 확인하세요.
이 가이드는 특히 Docker 실행자를 사용하는 GitLab Runner가 프록시 뒤에서 작동하도록 설정하는 것을 목표로 합니다.
계속하기 전에 동일한 머신에 Docker와 GitLab Runner가 이미 설치되어 있는지 확인하세요.
cntlm 설정#
인증 없이 프록시를 이미 사용하고 있다면 이 섹션은 선택 사항이며, 이미지 다운로드를 위한 Docker 설정으로 건너뛸 수 있습니다.
cntlm 설정은 인증이 필요한 프록시 뒤에 있는 경우에만 필요하지만, 어떤 경우에도 사용하는 것을 권장합니다.
cntlm은 로컬 프록시로 사용할 수 있는 Linux 프록시로, 수동으로 모든 곳에 프록시 세부 정보를 추가하는 것에 비해 2가지 주요 장점이 있습니다:
- 자격 증명을 변경해야 하는 단일 위치
- Docker 러너에서 자격 증명에 접근할 수 없음
cntlm을 설치했다고 가정하면, 먼저 설정해야 합니다.
docker0 인터페이스에서 수신하도록 cntlm 설정#
보안 강화 및 인터넷으로부터의 보호를 위해, 컨테이너가 접근할 수 있는 IP 주소를 가진 docker0 인터페이스에서만 수신하도록 cntlm을 바인딩합니다. Docker 호스트의 cntlm이 이 주소에서만 바인딩되도록 하면, Docker 컨테이너는 접근할 수 있지만 외부에서는 접근할 수 없습니다.
-
Docker가 사용하는 IP를 찾습니다:
ip -4 -oneline addr show dev docker0IP 주소는 일반적으로
172.17.0.1이며, 이를docker0_interface_ip라고 부르겠습니다. -
cntlm설정 파일(/etc/cntlm.conf)을 엽니다. 사용자명, 비밀번호, 도메인 및 프록시 호스트를 입력하고, 이전 단계에서 찾은ListenIP 주소를 설정합니다. 다음과 같이 보여야 합니다: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로 변경 -
변경 사항을 저장하고 서비스를 재시작합니다:
sudo systemctl restart cntlm
이미지 다운로드를 위한 Docker 설정#
다음 내용은 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 서비스에 프록시를 추가하는 것과 동일합니다:
-
gitlab-runner서비스를 위한 systemd 드롭-인 디렉터리를 생성합니다:mkdir /etc/systemd/system/gitlab-runner.service.d -
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" -
파일을 저장하고 변경 사항을 적용합니다:
systemctl daemon-reload -
GitLab Runner를 재시작합니다:
sudo systemctl restart gitlab-runner -
설정이 로드되었는지 확인합니다:
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_ip는 docker0 인터페이스의 IP 주소입니다.
예시에서 소문자와 대문자 변수를 모두 설정하는 이유는 일부 프로그램은 HTTP_PROXY를 기대하고 다른 프로그램은 http_proxy를 기대하기 때문입니다. 안타깝게도 이러한 종류의 환경 변수에 대한 표준이 없습니다.
dind 서비스 사용 시 프록시 설정#
Docker-in-Docker 실행자 (dind)를 사용할 때, NO_PROXY 환경 변수에 docker:2375,docker:2376을 지정해야 할 수 있습니다. 포트가 필요하며, 그렇지 않으면 docker push가 차단됩니다.
dind의 dockerd와 로컬 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"
이렇게 하면 TOML 파일 내의 단일 문자열로 지정된 shell이 있는 JSON 파일이 생성되므로 "의 추가 이스케이프 레벨이 필요합니다. 이것은 YAML이 아니므로 :를 이스케이프하지 마세요.
NO_PROXY 목록을 확장해야 하는 경우, 와일드카드 *는 접미사에만 작동하며 접두사나 CIDR 표기법에는 작동하지 않습니다.
자세한 내용은
https://github.com/moby/moby/issues/9145
및
https://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 응답을 받으면 다음 재시도 순서를 따릅니다:
- 러너는 응답 헤더에서
RateLimit-ResetTime헤더를 확인합니다.RateLimit-ResetTime헤더는Wed, 21 Oct 2015 07:28:00 GMT와 같이 유효한 HTTP 날짜(RFC1123)값을 가져야 합니다.- 헤더가 존재하고 유효한 값을 가지면, 러너는 지정된 시간까지 기다렸다가 다른 요청을 보냅니다.
RateLimit-ResetTime헤더가 유효하지 않거나 없으면, 러너는 응답 헤더에서Retry-After헤더를 확인합니다.Retry-After헤더는Retry-After: 30과 같이 초 형식의 값을 가져야 합니다.- 헤더 형식이 존재하고 유효한 값을 가지면, 러너는 지정된 시간까지 기다렸다가 다른 요청을 보냅니다.
- 두 헤더가 모두 없거나 유효하지 않으면, 러너는 기본 간격 동안 기다렸다가 다른 요청을 보냅니다.
러너는 실패한 요청을 최대 5번까지 재시도합니다. 모든 재시도가 실패하면, 러너는 최종 응답의 오류를 기록합니다.
지원되는 헤더 형식#
| 헤더 | 형식 | 예시 |
|---|---|---|
RateLimit-ResetTime |
HTTP Date (RFC1123) | Wed, 21 Oct 2015 07:28:00 GMT |
Retry-After |
초 | 30 |
RateLimit-ResetTime 헤더는 모든 헤더 키가 http.CanonicalHeaderKey 함수를 통해 실행되기 때문에 대소문자를 구분하지 않습니다.
