fix: php-fpmをexec php-fpm -Fで起動しCrashLoopBackOff(9000二重bind)/502を修正
Helm Chart Release / release-chart (push) Successful in 6s
Helm Chart Release / release-chart (push) Successful in 6s
setupシェルの子として起動していたためコンテナ再起動時にシェル(PID1)がSIGTERMを子へ転送せず、旧php-fpmが9000を握ったまま残存し次回起動が Address in use で失敗する自己増殖ループに陥っていた。execでphp-fpmをPID1にしシグナルを直接受けさせ、-Fで必ずフォアグラウンド起動にする。
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# Changelog - Version 8.5.9-d
|
||||
|
||||
## 不具合修正
|
||||
|
||||
### php-fpm を `exec php-fpm -F` で起動(CrashLoopBackOff / 502 の修正)
|
||||
|
||||
php-fpm コンテナの起動コマンドを、setup シェルスクリプト末尾の `php-fpm`(シェルの子プロセスとしてフォアグラウンド起動)から **`exec php-fpm -F`** に変更しました。
|
||||
|
||||
**背景(実際に発生した障害)**
|
||||
|
||||
`selenium.enabled: true` の構成(例: hotels / booking.e-stay.jp)で、php-fpm コンテナが次のエラーで永続的に CrashLoopBackOff に陥る事象が発生しました。
|
||||
|
||||
```
|
||||
[NOTICE] Failed implicitly binding to ::, retrying with 0.0.0.0
|
||||
[ERROR] unable to bind listening socket for address '9000': Address in use (98)
|
||||
[ERROR] FPM initialization failed
|
||||
```
|
||||
|
||||
php-fpm が 9000 を bind できず起動に失敗するため、nginx が `fastcgi_pass 127.0.0.1:9000` に投げても FastCGI ではない応答が返り、`upstream sent unsupported FastCGI protocol version: 60` として **全リクエストが 502** になります(`60` = `<`、= 9000 を握っている別プロセスが HTML 等を返している)。
|
||||
|
||||
**原因**
|
||||
|
||||
起動コマンドが `sh -c "<setup> ... php-fpm"` の形で、**php-fpm が setup シェルの子プロセス**になっていた。コンテナ PID1 はシェルであり、シェルは既定で受け取った `SIGTERM` を子プロセスへ転送しない。そのためコンテナ(php-fpm コンテナのみ)の再起動時に、PID1 のシェルだけが先に終了し、**旧 php-fpm が一時的に残存して 9000 を握ったまま**になることがある。この状態で新しい php-fpm が起動すると `Address in use` で失敗 → 再起動 → 同じ残存 → という自己増殖ループに入り、CrashLoopBackOff から復帰できなくなる。selenium サイドカーは 9000 を使用しておらず無関係(別 pod でのポート占有調査でも確認済み)。
|
||||
|
||||
**対応**
|
||||
|
||||
- `exec php-fpm` … php-fpm が setup シェルを置き換えて**コンテナの PID1 になる**。kubelet からの `SIGTERM`/`SIGKILL` が php-fpm 本体へ直接届き、停止時に 9000 が確実に解放されるため、次回起動での二重 bind が起きない。
|
||||
- `-F`(`--nodaemonize`)… php-fpm.conf の `daemonize` 設定に依存せず、必ずフォアグラウンドで起動する(master が背後に残る事故を防ぐ)。
|
||||
|
||||
これは全サイト共通で安全な変更(コンテナ内で php-fpm を動かす際の定石)であり、既存の正常稼働サイトの挙動は変わりません。
|
||||
|
||||
**復旧手順(重要)**
|
||||
|
||||
チャートを `8.5.9-d` に上げても、既存 pod のネットワーク名前空間に残存プロセスがある場合は、その pod を作り直してクリーンな状態にする必要があります。`helm upgrade` で新しい pod に置き換わりますが、置き換わらない場合は crashloop 中の pod を明示的に削除してください。
|
||||
|
||||
```bash
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.yaml
|
||||
# 置き換わらない場合:
|
||||
kubectl delete pod -n <namespace> -l app.kubernetes.io/name=phpfpm
|
||||
```
|
||||
|
||||
**対象ファイル**: `templates/deployment.yaml`, `Chart.yaml`, `README.md`, `CLAUDE.md`, `CHANGELOG-8.5.9-d.md`
|
||||
|
||||
## アップグレード手順
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**リリース日**: 2026-09-06
|
||||
**担当**: プロサーバーエンジニア(Claude)
|
||||
@@ -26,6 +26,12 @@ Websites 組織の各サイト(e-learn.jp / fcdomain.com / hotels / tskholding
|
||||
|
||||
## チャート改修履歴
|
||||
|
||||
### php-fpm を `exec php-fpm -F` で起動しCrashLoopBackOffを修正(2026-09-06, v8.5.9-d)
|
||||
|
||||
setup シェル末尾の `php-fpm`(シェルの子プロセス)を **`exec php-fpm -F`** に変更。selenium 有効構成(hotels)で php-fpm が `unable to bind ... '9000': Address in use` を出して永続 CrashLoopBackOff になり、nginx が非FastCGI応答を受けて全リクエスト502(`unsupported FastCGI protocol version: 60`)になる障害の修正。原因は php-fpm が setup シェルの子で、コンテナ PID1 のシェルが `SIGTERM` を子へ転送しないため、コンテナ再起動時に旧 php-fpm が残存し 9000 を握ったまま次回起動が二重 bind で失敗する自己増殖ループ。`exec` で php-fpm を PID1 にしてシグナルを直接受けさせ(停止時に 9000 を確実解放)、`-F` で `daemonize` 設定に依存せず必ずフォアグラウンド起動にした。全サイト共通で安全(コンテナで php-fpm を動かす定石)。復旧には `helm upgrade` に加え、残存プロセスを持つ既存 pod の削除が必要な場合がある。
|
||||
|
||||
**対象ファイル**: `templates/deployment.yaml`, `Chart.yaml`, `README.md`, `CLAUDE.md`, `CHANGELOG-8.5.9-d.md`
|
||||
|
||||
### Ingressのproxy-body-sizeもuploadMaxSizeに連動(2026-08-06, v8.5.9-c)
|
||||
|
||||
v8.5.9-bのフォローアップ。`templates/ingress.yaml` で `merge (deepCopy .Values.ingress.annotations) (dict "nginx.ingress.kubernetes.io/proxy-body-size" .Values.uploadMaxSize)` を使い、ユーザーが明示指定していなければ `uploadMaxSize` をIngressの `proxy-body-size` にも自動反映。明示指定があればそちらが優先(sprigのmergeはdst=ユーザー指定annotationsが優先、srcのデフォルト値は不足分のみ補う)。これで `uploadMaxSize` 1箇所でnginx・PHP・Ingressの3箇所すべてが揃う。
|
||||
|
||||
+1
-1
@@ -2,6 +2,6 @@ apiVersion: v2
|
||||
name: phpfpm
|
||||
description: Nginx + PHP-FPM Helm Chart with external DB and optional Selenium support
|
||||
type: application
|
||||
version: 8.5.9-c
|
||||
version: 8.5.9-d
|
||||
appVersion: "8.5.9"
|
||||
icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png
|
||||
|
||||
@@ -867,6 +867,24 @@ composer:
|
||||
- "autoconf"
|
||||
```
|
||||
|
||||
### php-fpm が CrashLoopBackOff/全リクエストが 502(`Address in use` / `unsupported FastCGI protocol version: 60`)
|
||||
|
||||
**症状**: php-fpm コンテナが `CrashLoopBackOff` になり、nginx ログに `upstream sent unsupported FastCGI protocol version: 60`、php-fpm ログに次が出る。
|
||||
|
||||
```
|
||||
[ERROR] unable to bind listening socket for address '9000': Address in use (98)
|
||||
[ERROR] FPM initialization failed
|
||||
```
|
||||
|
||||
**原因**: php-fpm が 9000 を bind できず起動失敗し、nginx が非 FastCGI 応答を受けて 502 になる。v8.5.9-c 以前は php-fpm を setup シェルの子プロセスとして起動していたため、コンテナ再起動時に PID1 のシェルが `SIGTERM` を子へ転送せず、旧 php-fpm が残存して 9000 を握ったまま次回起動が二重 bind で失敗する自己増殖ループに陥ることがあった。
|
||||
|
||||
**対策**: **v8.5.9-d 以降にアップグレードする**(起動を `exec php-fpm -F` に変更済み。php-fpm が PID1 になりシグナルを直接受けて 9000 を確実解放、`-F` で必ずフォアグラウンド起動)。アップグレード後も残存プロセスを持つ既存 pod が残る場合は作り直す。
|
||||
|
||||
```bash
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.yaml
|
||||
kubectl delete pod -n <namespace> -l app.kubernetes.io/name=phpfpm
|
||||
```
|
||||
|
||||
### データベース接続エラー
|
||||
|
||||
**確認**:
|
||||
|
||||
@@ -252,7 +252,16 @@ spec:
|
||||
{{- end }}
|
||||
|
||||
echo "Setup complete, starting PHP-FPM..."
|
||||
php-fpm
|
||||
# exec で php-fpm をコンテナの PID1 に置き換える。
|
||||
# 目的: setup シェルを介さず php-fpm 自身が SIGTERM/SIGKILL を直接受け取れる
|
||||
# ようにする。シェルは既定で子プロセスへシグナルを転送しないため、exec せず
|
||||
# `php-fpm`(子)のまま起動すると、コンテナ再起動時にシェル(PID1)だけが落ちて
|
||||
# 旧 php-fpm が一時的に残存し、9000 を握ったまま次回起動が
|
||||
# 「unable to bind ... '9000': Address in use」で失敗して CrashLoopBackOff に陥る。
|
||||
# exec すれば php-fpm が PID1 になり、停止時に 9000 が確実に解放される。
|
||||
# -F(--nodaemonize): 設定に依存せず必ずフォアグラウンドで起動する
|
||||
# (デーモン化して master が背後に残る事故を防ぐ)。
|
||||
exec php-fpm -F
|
||||
ports:
|
||||
- containerPort: 9000 # PHP-FPMは9000ポートでリッスン
|
||||
volumeMounts:
|
||||
|
||||
Reference in New Issue
Block a user