冒頭まとめ
GitLab の 502 には、他のソフトウェアにはない手がかりがあります。専用の画面が用意されていて、応答に時間がかかりすぎている、という趣旨の文言が表示されます。この文言が出ているかどうかが、切り分けの起点になります。
専用の画面が表示されているなら、応答を作ったのは GitLab に同梱されている前段のソフトウェアです。つまり、前段は動いています。動いていない相手は、その後ろにいる応用処理の側です。逆に、素っ気ない画面や別の形式の画面が出ているなら、応答を作ったのは GitLab の外側にいる中継役です。この場合、GitLab の設定をいくら見直しても変わりません。
GitLab の構成は多段です。前段が受け取り、補助の役が中継し、応用処理が実際の処理を行い、その先に格納の役が控えています。502 が起きるのは、このどこかで応答が返らなくなったときです。段が多いぶん、どこで止まったかを特定する作業が要ります。
公式の窓口記事には、具体的な設定に起因する例が挙げられています。応用処理を単独で動かす設定にしていると、頻繁な再起動が起き、その際に 502 が表示される、というものです。この設定は資源の限られた環境向けのもので、外すと複数の処理単位で動くようになり、順に入れ替える方式が使えるため、停止する時間が短くなる、と説明されています。
エラーの概要
利用者側に表示されるのは、GitLab が用意した専用の画面です。時間がかかりすぎている、という趣旨の文言が入ります。
前段の記録には、その先へ繋げなかったことが残ります。
upstream prematurely closed connection while reading response header from upstream
connect() failed (111: Connection refused) while connecting to upstream,
upstream: "http://unix:/var/opt/gitlab/gitlab-rails/sockets/gitlab.socket:/"
転送先として、ファイルを経由した接続先が記録されているのが特徴です。この経路で繋がらないということは、応用処理が待ち受けていないか、応答を返す前に落ちているということです。
各段の稼働状況は、まとめて確認できます。
run: gitaly: (pid 1580) 83s; run: log: (pid 1575) 83s
run: nginx: (pid 1588) 83s; run: log: (pid 1584) 83s
run: puma: (pid 12394) 0s; run: log: (pid 1574) 83s
run: sidekiq: (pid 12015) 2s; run: log: (pid 1578) 83s
ここで見るべきは、右側の経過時間です。他の段が同じくらいの値なのに、応用処理の段だけが数秒しか経っていない場合、その段が繰り返し起動し直していることを示します。この形は、後述する再起動の問題に直結します。
まず最初に:専用の画面かどうかと、経過時間を見る
第一に、表示されている画面が GitLab 専用のものかを確認します。専用なら前段は動いています。そうでなければ、GitLab の外側を先に疑ってください。
第二に、各段の稼働状況を確認し、経過時間を見比べます。1つの段だけが短ければ、その段が繰り返し起動し直しています。
第三に、応用処理の段の記録を見ます。起動に失敗しているのか、起動はしているが応答が返らないのかで、対処が変わります。
よくある原因と解決手順
原因1:応用処理が繰り返し起動し直している
公式の窓口記事が挙げている例です。応用処理を単独で動かす設定にしていると、頻繁な再起動が起き、そのたびに 502 が表示されます。
Before(単独で動かす設定になっている):
# /etc/gitlab/gitlab.rb
puma['worker_processes'] = 0
After(設定を外して複数で動かす):
# /etc/gitlab/gitlab.rb
# puma['worker_processes'] = 0
記事では、この行を削除するか無効にしたうえで設定を反映し直すよう案内されています。複数の処理単位で動くようになると、順に入れ替える方式が使えるため、入れ替えの最中も応答を返し続けられます。
sudo gitlab-ctl reconfigure
sudo gitlab-ctl status
反映後、経過時間が伸び続けるかを確認してください。伸びていれば、再起動は止まっています。
原因2:資源が足りずに落ちている
応用処理は、起動時に多くの領域を必要とします。足りないと、起動の途中で終了させられ、前段からは接続を拒否された状態に見えます。
まず、実際に足りているかを確認します。
free -h
sudo gitlab-ctl tail puma
記録の中に、領域の確保に失敗した旨や、外部から終了させられた旨が残っていないかを見てください。増設できない環境では、同時に動かす数を減らして凌ぐ方法があります。ただし、これは原因1で挙げた単独動作とは別の調整で、程度の問題です。減らしすぎると、今度は入れ替えの最中に応答が途切れます。
原因3:起動はしているが、応答が返らない
各段の経過時間は伸びているのに 502 が続く場合です。応用処理は生きているが、要求を処理しきれていない状態です。
この場合、疑うのはさらに後ろの段です。格納の役が応答しないと、応用処理はそこで待ち続け、前段から見ると応答が返らないのと同じになります。
sudo gitlab-ctl tail gitaly
sudo gitlab-ctl tail postgresql
後ろの段の記録に遅延や失敗が残っていれば、502 は結果であって原因ではありません。応用処理の設定を触っても直りません。
原因4:更新や再構成の直後
版を上げた直後や、設定を反映し直した直後に出る形です。各段が順に立ち上がるまでの間、前段だけが先に応答できる状態になるため、その間は 502 になります。
この場合、待てば収まります。収まらない場合は、立ち上がりに失敗している段があるということなので、稼働状況を確認してください。
sudo gitlab-ctl status
sudo gitlab-ctl restart
再構成の途中で失敗が出ている場合は、その内容を先に解消する必要があります。502 の側だけを見ていても進みません。
原因5:GitLabの外側の中継役が502を作っている
専用の画面ではなく、素っ気ない画面や別の形式が出ている場合です。GitLab の前に別の中継役を置いている構成で起きます。
この場合、GitLab 側の各段は正常に動いていることが多く、稼働状況を見ても異常が見つかりません。中継役を経由せずに直接叩いて確かめてください。
# GitLab の機器の上から直接叩く
curl -sS -o /dev/null -w "status:%{http_code}\n" http://127.0.0.1/-/readiness
直接なら成功するのに、外から叩くと 502 になるなら、原因は中継役側です。
補足:似ているが別のもの
応用処理が例外で失敗した場合は 500 で、専用の画面ではなく別の表示になります(GitLab の 500 の記事)。要求の頻度が上限を超えた場合は 429 です(GitLab の 429 の記事)。権限が足りない場合は 403、対象が見つからない、あるいは見せない方針の場合は 404 です(GitLab の 403 の記事、404 の記事)。
送った内容が検証に通らない場合は 422 です(GitLab の 422 の記事)。502 は応答が得られなかった話なので、送った内容とは無関係です。
切り分けの順序
- 表示が GitLab 専用の画面かを確認する。専用なら前段は動いている。
- 各段の稼働状況を見て、経過時間を見比べる。1つだけ短ければ、その段が繰り返し起動し直している。
- 繰り返し起動し直しているなら、単独で動かす設定になっていないかを確認する。
- 資源が足りているかを確認する。起動の途中で終了させられていないかを記録で見る。
- 経過時間が伸びているのに 502 が続くなら、後ろの段を疑う。
- 更新や再構成の直後なら、しばらく待ってから再確認する。
- 専用の画面でないなら、GitLab の外側の中継役を疑う。機器の上から直接叩いて比べる。
確認コマンド集
# 1. 各段の稼働状況と経過時間を確認する
sudo gitlab-ctl status
# 2. 応用処理の記録を追う
sudo gitlab-ctl tail puma
# 3. 前段の記録から、その先へ繋げなかった行を探す
sudo grep -E "connect\(\) failed|prematurely closed" /var/log/gitlab/nginx/gitlab_error.log | tail -20
# 4. 後ろの段の記録を確認する
sudo gitlab-ctl tail gitaly
sudo gitlab-ctl tail postgresql
# 5. 資源の空きを確認する
free -h
# 6. 機器の上から直接叩いて、外側の中継役の関与を切り分ける
curl -sS -o /dev/null -w "status:%{http_code}\n" http://127.0.0.1/-/readiness
Editor’s Note
GitLab が 502 に専用の画面を用意していることは、調査の面では大きな利点です。多くのソフトウェアでは、502 の画面から応答を作った相手を判別できません。GitLab の場合、専用の画面が出ているという事実そのものが、「前段は生きている」という情報になります。段の多い構成で、最初の1段を確定できる意味は小さくありません。
公式の窓口記事が挙げている例も示唆的です(Frequent 502 Errors and Restarts Due to Puma Single Mode Configuration)。応用処理を単独で動かす設定は、資源の限られた環境のために用意されたものです。つまり、資源を節約しようとした選択が、頻繁な再起動という別の問題を呼び込む形になっています。記事では、この設定を外すと順に入れ替える方式が使えるようになり、停止の時間が減ると説明されています。
ここから読み取れるのは、502 の原因が「壊れている」とは限らない、ということです。意図して選んだ設定が、別の場面で不都合を生んでいるだけ、という場合があります。稼働状況の経過時間を見比べる、という単純な確認が効くのはこのためです。動いていないのではなく、動き直し続けている。この違いは、記録を追う前に数字で見えます。
免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。
この記事でエラーは解決しましたか?