- CNTLM 구성하기
- 이미지 다운로드를 위한 Docker 구성하기
- GitLab Runner 구성에 프록시 변수 추가하기
- Docker 컨테이너에 프록시 추가하기
- dind 서비스 사용 시 프록시 설정
- 속도 제한 요청 처리
프록시 뒤에서 GitLab Runner 실행하기
이 가이드는 Docker 실행자를 사용하는 GitLab Runner를 프록시 뒤에서 작동하게 하기 위해 특별히 작성되었습니다.
계속하기 전에, 동일한 머신에 이미
Docker와
GitLab Runner를 설치했는지 확인하세요.
CNTLM 구성하기
Docker 구성하기로 바로 건너뛰어도 됩니다.
CNTLM 구성이 필요한 것은 인증이 있는 프록시 뒤에 있을 때뿐이지만, 어떤 경우에도 사용하는 것이 좋습니다.
CNTLM은 로컬 프록시로 사용할 수 있는 리눅스 프록시이며,
프록시 세부 정보를 수동으로 모든 곳에 추가하는 것에 비해 두 가지 주요 장점이 있습니다:
- 자격 증명을 변경해야 하는 단일 소스
- 자격 증명은 Docker 러너에서 접근할 수 없습니다
CNTLM을 설치했다고 가정하면,
먼저 이를 구성해야 합니다.
CNTLM이 docker0
인터페이스를 수신하게 설정
추가 보안을 위해 외부 세계로부터 서버를 보호하기 위해,
CNTLM을 docker0
인터페이스에 바인딩하여 해당 IP가 컨테이너 내에서 접근 가능하게 할 수 있습니다.
Docker 호스트에서 CNTLM에게 이 주소에만 바인딩하도록 지시하면, Docker 컨테이너는 이를 접근할 수 있지만 외부 세계는 접근할 수 없습니다.
-
Docker가 사용 중인 IP를 찾습니다:
ip -4 -oneline addr show dev docker0
이 IP는 일반적으로
172.17.0.1
이고, 이를docker0_interface_ip
라고 부르겠습니다. -
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 # Change to your docker0 interface IP
-
변경 사항을 저장하고 서비스를 재시작합니다:
sudo systemctl restart cntlm
이미지 다운로드를 위한 Docker 구성하기
Docker 문서를 따라 프록시를 사용하는 방법을 참고하세요.
서비스 파일은 다음과 같아야 합니다:
[Service]
Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
GitLab Runner 구성에 프록시 변수 추가하기
프록시 변수는 GitLab Runner 구성에도 추가해야 하므로,
프록시 뒤에서 GitLab.com에 연결할 수 있습니다.
이는 위의 Docker 서비스에 프록시를 추가하는 것과 기본적으로 동일합니다:
-
gitlab-runner
서비스에 대한 systemd 드롭인 디렉토리를 생성합니다:mkdir /etc/systemd/system/gitlab-runner.service.d
-
/etc/systemd/system/gitlab-runner.service.d/http-proxy.conf
라는 파일을 생성하여
HTTP_PROXY
환경 변수를 추가합니다:[Service] Environment="HTTP_PROXY=http://docker0_interface_ip:3128/" Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
GitLab Runner를 내부 URL, 예를 들어 셀프 맨지드 GitLab 인스턴스에 연결하려면,
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
클라이언트 간의 통신은 루트의 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 파일의 단일 문자열 내에서 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는 다음 논리를 사용하여 속도 제한 시나리오를 처리합니다:
-
429 - TooManyRequests 응답 코드가 수신됩니다.
- 응답 헤더에서
RateLimit-ResetTime
헤더를 확인합니다.RateLimit-ResetTime
헤더는Wed, 21 Oct 2015 07:28:00 GMT
와 같은 유효한 HTTP 날짜 (RFC1123) 값을 가져야 합니다.- 헤더가 존재하고 유효한 값을 가진 경우, 러너는 지정된 시간까지 기다렸다가 또 다른 요청을 보냅니다.
- 헤더가 존재하지만 유효한 날짜가 아닌 경우, 1분의 대체 값이 사용됩니다.
- 헤더가 존재하지 않으면 추가 조치가 취해지지 않으며, 응답 오류가 반환됩니다.
- 위 과정이 5회 반복되며, 이후
gave up due to rate limit
오류가 반환됩니다.
RateLimit-ResetTime
은 모든 헤더 키가 http.CanonicalHeaderKey
함수로 실행되기 때문에 대소문자를 구분하지 않습니다.