- CNTLMの設定
- イメージをダウンロードするためのDockerの設定
- ランナー設定へのプロキシ変数の追加
- Dockerコンテナへのプロキシの追加
- dindサービス使用時のプロキシ設定
- 料金制限リクエストへの対応
GitLab Runnerをプロキシの背後で実行する方法
このガイドは、GitLab Runner with Docker executorをプロキシの後ろで動作させることに特化しています。
先に進む前に、DockerとGitLab Runnerが同じマシンにインストール済みであることを確認する必要があります。
CNTLMの設定
CNTLMはローカルプロキシとして使用できる Linux プロキシで、手動であらゆる場所にプロキシの詳細を追加するのに比べて、2 つの大きな利点があります:
- クレデンシャルを変更する必要がある場合は、1つのソースをご利用ください。
- Docker Runnerから認証情報にアクセスできません。
CNTLMをインストールしたと仮定して、まずそれを設定する必要があります。
CNTLMがdocker0
インターフェースをリッスンするようにします。
さらにセキュリティを強化し、サーバを外部から保護するために、コンテナ内部から到達可能なIPを持つdocker0
インターフェースをリッスンするようにCNTLMをバインドすることができます。DockerホストのCNTLMにこのアドレスのみにバインドするように指示すると、Dockerコンテナはそのアドレスに到達することができますが、外部からは到達することができません。
-
Dockerが使用しているIPを検索します:
ip -4 -oneline addr show dev docker0
これは通常、
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/"
ランナー設定へのプロキシ変数の追加
プロキシ変数も Runner の設定に追加する必要があります。プロキシの後ろで GitLab から割り当てられたビルドを取得できるようにするためです。
これは基本的に、上記の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/"
-
ファイルを保存し、変更をフラッシュします:
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コンテナへのプロキシの追加
Runnerを登録した後、Dockerコンテナにプロキシ設定を伝搬させたいかもしれません(git clone
やその他のもののために)。
そのためには、/etc/gitlab-runner/config.toml
を編集し、[[runners]]
セクションに以下を追加する必要があります:
pre_clone_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 アドレスです。Docker コンテナ内からアクセスできる必要があるので、正しく設定することが重要です。
HTTP_PROXY
を、他のプログラムではhttp_proxy
を想定しているからです。残念ながら、この種の環境変数に関する標準はありません。dindサービス使用時のプロキシ設定
Docker-in-Dockerexecutor (dind)を使用する場合、NO_PROXY
環境変数にdocker:2375,docker:2376
を指定する必要がある場合があります。これはプロキシがDocker-in-Docker間のTCP接続をインターセプトするためです:
-
dockerd
ディンド・コンテナから。 -
docker
をクライアントコンテナから削除します。
そうしないと、docker push
がDockerにマッピングされたIPから発信されるためブロックされてしまうからです。ただし、その場合はプロキシを経由するようになっています。
dindのdockerd
とdocker
クライアントとの間の通信をローカルでテストする場合(ここで説明されているように:https://hub.docker.com/_/docker/)、dindのdockerd
はホストシステム上のクライアントとしてrootによって最初に起動され、プロキシ変数は/root/.docker/config.json
から取得されます。
使用例:
{
"proxies": {
"default": {
"httpProxy": "http://proxy:8080",
"httpsProxy": "http://proxy:8080",
"noProxy": "docker:2375,docker:2376"
}
}
}
しかし、.gitlab-ci.yml
スクリプトを実行するために起動されたコンテナでは、gitlab-runner
の設定(/etc/gitlab-runner/config.toml
)によって環境変数が設定されます。これらは、dockerd
をサービスとして実行し、docker
クライアントを実行する dind コンテナでは、(上記のローカルテストの.docker/config.json
とは対照的に)そのまま環境変数として利用可能です.gitlab-ci.yml
。 で .gitlab-ci.yml
、環境変数は、デフォルトの環境変数からプロキシ設定を尊重する任意のプログラムによってピックアップされます。 たとえば、wget
、apt
、apk
、docker info
、docker pull
(ただし、docker run
やdocker build
のようにhttps://github.com/moby/moby/issues/24697#issuecomment-366680499)ではありません。
docker run
やdocker build
をDocker executorのコンテナ内部で実行すると、$HOME/.docker/config.json
にあるプロキシ設定を探します。 は現在、executorコンテナ内部にあります(最初は空です)。したがって、docker run
やdocker build
を実行すると、プロキシ設定はありません。設定を引き継ぐには、executorコンテナ内に$HOME/.docker/config.json
を作成する必要があります。 たとえば、 は、 にあるプロキシ設定を探します:
before_script:
- mkdir -p $HOME/.docker/
- 'echo "{ \"proxies\": { \"default\": { \"httpProxy\": \"$HTTP_PROXY\", \"httpsProxy\": \"$HTTPS_PROXY\", \"noProxy\": \"$NO_PROXY\" } } }" > $HOME/.docker/config.json'
プロキシの場合にのみ必要な行を.gitlab-ci.yml
ファイルに追加するのは混乱を招くので、$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"
"
をエスケープする追加レベルが必要です。これはもはや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
チェックしますRateLimit-ResetTime
。RateLimit-ResetTime
ヘッダはWed, 21 Oct 2015 07:28:00 GMT
のような有効なHTTP Date (RFC1123) でなければなりません。- ヘッダーが存在し、有効な値を持っている場合、Runnerは指定された時間まで 待機し、別のリクエストを発行します。
- ヘッダが存在するが有効な日付でない場合、1分のフォールバックが使用されます。
- ヘッダーが存在しない場合、追加のアクションは行われず、応答エラーが返されます。
- 上記の処理が5回繰り返され、
gave up due to rate limit
エラーが返されます。
RateLimit-ResetTime
は大文字と小文字を区別しません。 http.CanonicalHeaderKey
関数を通して実行されるためです。