From 86cd705d060ffb6220f9394dc561b5988f9d8429 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 26 Sep 2026 08:05:10 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Selenium=E3=82=92=E7=8B=AC=E7=AB=8BDeplo?= =?UTF-8?q?yment/Service=E3=81=AB=E5=88=86=E9=9B=A2=E3=81=97resources?= =?UTF-8?q?=E3=81=AE=E6=AD=BB=E3=82=93=E3=81=A0=E8=A8=AD=E5=AE=9A=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit selenium.enabled=true構成でphp-fpmのCrashLoopBackOffとサイト完全停止が続いた件を調査し、2つの設計上の欠陥を確認した。(1) resources values キーがテンプレートで一切参照されておらず、全コンテナがQoS Class: BestEffortで動作しOOM Killされやすい状態だった。(2) nginx/php-fpm/SeleniumをすべてSelenium同一Podで起動しており、Kubernetesの Pod Ready判定(全コンテナのAND)により、Seleniumだけが不調でもPod全体がServiceのEndpointsから外れ、Seleniumを使わない静的ページ配信まで巻き込まれてサービス全体が停止していた。対応: Seleniumを独立Deployment(-phpfpm-selenium)/Serviceに分離し、SELENIUM_URLを自動注入。resourcesをnginx/phpfpm/selenium個別に構造化して実際にコンテナへ反映されるよう修正。詳細はCHANGELOG-8.5.10-b.md参照。 --- CHANGELOG-8.5.10-b.md | 100 +++++++++++++++++++++++++++++ CLAUDE.md | 7 ++ Chart.yaml | 2 +- README.md | 80 ++++++++++++++++------- templates/deployment-selenium.yaml | 68 ++++++++++++++++++++ templates/deployment.yaml | 29 +++++---- templates/service-selenium.yaml | 19 ++++++ templates/service.yaml | 1 + values.yaml | 38 ++++++++++- 9 files changed, 307 insertions(+), 37 deletions(-) create mode 100644 CHANGELOG-8.5.10-b.md create mode 100644 templates/deployment-selenium.yaml create mode 100644 templates/service-selenium.yaml diff --git a/CHANGELOG-8.5.10-b.md b/CHANGELOG-8.5.10-b.md new file mode 100644 index 0000000..d0eac16 --- /dev/null +++ b/CHANGELOG-8.5.10-b.md @@ -0,0 +1,100 @@ +# Changelog - Version 8.5.10-b + +## 不具合修正・アーキテクチャ変更 + +### Selenium を独立した Deployment/Service に分離(サービス完全停止の防止) + +**背景(実際に発生した障害)** + +`selenium.enabled: true` の構成(hotels / booking.e-stay.jp)で、php-fpm コンテナの +`CrashLoopBackOff` が断続的に発生し、その間サイト全体が Nginx の 502(`unsupported +FastCGI protocol version`)で完全に閲覧不能になる障害が続いた。v8.5.9-d で php-fpm の +起動方式(`exec php-fpm -F`)を修正した後も、8時間で1,375回という高頻度の再起動が +継続して観測された。 + +**原因(確定した2点)** + +1. **`resources` values キーがテンプレート側で一切参照されていなかった(死んだ設定)。** + `values.yaml` の `resources: {}` にどんな値を書いても、nginx・php-fpm・selenium + いずれのコンテナにも CPU/メモリの requests・limits が反映されない実装だった。 + このため全コンテナが `QoS Class: BestEffort`(実際のデプロイでも確認済み)で動作し、 + ノードのメモリ逼迫時に Linux の OOM Killer に真っ先に狙われる状態だった。 + Selenium(Chromium)はメモリを多く消費するため、Raspberry Pi 等のメモリに余裕がない + ノードでは他コンテナの OOM Kill を誘発しやすい。 +2. **nginx・php-fpm・Selenium を同一 Pod のコンテナとして起動しており、Pod の Ready 判定 + が「全コンテナの AND」になっていた。** readinessProbe を持たないコンテナは、 + Running であれば Ready 扱いになる一方、CrashLoopBackOff で Waiting/Terminated を + 繰り返している間は Ready=false になる。Kubernetes の Service は Pod 全体が Ready + でなければ Endpoints に含めないため、**Selenium だけが不調でも Service の + Endpoints がゼロになり、Selenium を全く使わない静的ページの配信まで巻き込まれて + サイト全体が停止していた**。`replicaCount: 1`(冗長性なし)の構成では、この1点が + 即・全断につながる。 + +(OOM Kill が今回の php-fpm クラッシュの直接のトリガーだったかは、`kubectl describe pod` +の `Last State` / `Reason` 等での確認が必要で、本リリース時点では未確認・要検証。 +ただし上記2点はコード上で確認できる確定した設計上の欠陥であり、いずれも本番運用の +安定性を損なうため、原因の切り分けを待たずに先に修正する。) + +**対応** + +- `selenium.enabled: true` のとき、Selenium は nginx/php-fpm と別の + **独立した Deployment(`-phpfpm-selenium`)と Service** として起動するように + 変更した(`templates/deployment-selenium.yaml` / `templates/service-selenium.yaml` を新設)。 + - php-fpm コンテナの `SELENIUM_URL` 環境変数は、`selenium.enabled: true` のとき + 自動的にこの新しい Service(`http://-phpfpm-selenium:4444/wd/hub`)を + 指すよう自動注入される(`phpEnv` で独自に設定していても、こちらが優先される)。 + - `selenium.replicaCount`(既定 `1`)で Selenium の Pod 数を独立して設定可能。 + - `selenium.mountHtml`(既定 `false`): `true` にすると Selenium コンテナにも + PVC の `html` サブパスをマウントする。別 Pod からの同時マウントになるため、 + 有効にする場合は `persistence.accessMode: ReadWriteMany` + (NFS バックエンドの StorageClass なら対応可能)が必要。 + - メインの Service(`-phpfpm`)・Deployment には + `app.kubernetes.io/component: web` ラベルを、Selenium 側には `component: selenium` + ラベルを付与し、セレクタが混線しないようにした。 +- `resources` values キーを実際にコンテナへ反映されるよう修正し、**nginx・php-fpm・ + selenium で個別に設定できる構造**に変更した: + ```yaml + resources: + nginx: { requests: {...}, limits: {...} } + phpfpm: { requests: {...}, limits: {...} } + + selenium: + resources: { requests: {...}, limits: {...} } + ``` + 既定値は空(`{}`)で、requests/limits なしの現行動作を維持する。**本番運用では + 設定を強く推奨する**(推奨値の例は `values.yaml` のコメントを参照)。 + +**互換性(重要・要対応)** + +- **`selenium.enabled: true` を使っている既存リリースは、アップグレード後に + 以下の対応が必要:** + 1. Selenium コンテナがそれまで暗黙にマウントしていた PVC の `html` サブパスに + 依存していた場合(例: ブラウザのダウンロード先を公開ディレクトリに置いていた等)、 + `selenium.mountHtml: true` を設定し、`persistence.accessMode` を + `ReadWriteMany` に変更する。依存していなければ何もする必要はない + (既定 `mountHtml: false` のままでよい)。 + 2. `phpEnv.SELENIUM_URL` に `http://localhost:4444/wd/hub` 等を手動設定している場合、 + Selenium が別 Pod になったことで `localhost` には到達できなくなる。ただし + チャートが自動的に新しい Service を指す値へ上書きするため、**多くの場合は + 何もしなくても動作する**(自動注入の値が env リストの後方にあるため優先される)。 + 設定の混乱を避けるため、`phpEnv.SELENIUM_URL` の手動指定は削除することを推奨する。 +- `resources: {}` は元々どのコンテナにも一切効いていなかったため、この構造変更で + 既存の動作が変わることはない(誰も実質的な値を得ていなかったため、破壊的変更にはならない)。 + +**対象ファイル**: `templates/deployment.yaml`, `templates/deployment-selenium.yaml`(新規), +`templates/service.yaml`, `templates/service-selenium.yaml`(新規), `values.yaml`, +`README.md`, `Chart.yaml`, `CLAUDE.md`, `CHANGELOG-8.5.10-b.md` + +## アップグレード手順 + +```bash +helm repo update +helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.10-b -f values.yaml +``` + +`selenium.enabled: true` の場合、上記「互換性」を確認のうえアップグレードすること。 + +--- + +**リリース日**: 2026-09-26 +**担当**: プロサーバーエンジニア(Claude) diff --git a/CLAUDE.md b/CLAUDE.md index 3c653d3..556e348 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,9 +23,16 @@ Websites 組織の各サイト(e-learn.jp / fcdomain.com / hotels / tskholding - PVC はルートを `/var/www` にマウントする(`html/` が公開フォルダ、それ以外は非公開)。`/composer` は Pod 再起動ごとにクリーン再構築される使い捨て領域。 - `uploadMaxSize` 1箇所で nginx `client_max_body_size`・PHP `upload_max_filesize`/`post_max_size`・Ingress `proxy-body-size` の3箇所が連動する。 - Secret / ConfigMap をファイルとして PHP-FPM ワーカー(`www-data`)から読ませる場合、権限は `0644` にする(`0600` だと読めない)。 +- Selenium(`selenium.enabled: true`)は v8.5.10-b 以降、nginx/php-fpm と別の Deployment/Service(`-phpfpm-selenium`)。同一 Pod のサイドカーには**しない**(Selenium 単体の不調でメインの Pod が Service の Endpoints から外れ、静的ページ配信まで巻き込んで全断する設計だったため分離した)。 ## チャート改修履歴 +### Selenium を独立Deployment/Serviceに分離 + resources死んだ設定を修正(2026-09-26, v8.5.10-b) + +`selenium.enabled: true` 構成で断続的な php-fpm CrashLoopBackOff とサイト完全停止が続いた件の調査で、2つの設計上の欠陥を確認した。(1) `resources` values キーがテンプレート側で全く参照されておらず、nginx/php-fpm/selenium いずれのコンテナにも requests/limits が反映されない死んだ設定だった(全コンテナが QoS Class: BestEffort → ノードのメモリ逼迫時に OOM Kill の対象になりやすい)。(2) nginx・php-fpm・Selenium が同一 Pod のコンテナで、Kubernetes の Pod Ready 判定は全コンテナの AND のため、Selenium だけが不調(起動失敗・OOM 等)でも Pod 全体が Service の Endpoints から外れ、Selenium を使わない静的ページ配信まで巻き込まれてサービス全体が停止していた。対応: Selenium を独立した Deployment(`-phpfpm-selenium`)/Service に分離(`app.kubernetes.io/component: web`/`selenium` ラベルでセレクタを分離、php-fpm の `SELENIUM_URL` は新Serviceを指すよう自動注入)。`resources` を `resources.nginx`/`resources.phpfpm`/`selenium.resources` に構造化し実際にコンテナへ反映されるよう修正。既存 `selenium.enabled: true` 利用者は `selenium.mountHtml`(PVC html サブパスへの依存があれば true + `persistence.accessMode: ReadWriteMany`)を確認する必要がある。OOM Kill が実際のクラッシュトリガーだったかは本リリース時点では未確認(要検証)だが、上記2点はコード上確認済みの確定した欠陥のため先行修正した。 + +**対象ファイル**: `templates/deployment.yaml`, `templates/deployment-selenium.yaml`(新規), `templates/service.yaml`, `templates/service-selenium.yaml`(新規), `values.yaml`, `README.md`, `Chart.yaml`, `CHANGELOG-8.5.10-b.md` + ### 外部Secret連携(extraEnvFrom / extraEnv / SMTP existingSecret)を追加(2026-09-08, v8.5.10-a) **背景**: 別リポジトリの `helmchart/secret-manager` チャートが各ネームスペースへ配布する diff --git a/Chart.yaml b/Chart.yaml index 340fd23..b2344eb 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -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.10-a +version: 8.5.10-b appVersion: "8.5.10" icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png diff --git a/README.md b/README.md index 40b61c0..1516f64 100644 --- a/README.md +++ b/README.md @@ -83,20 +83,20 @@ kubectl logs -l app.kubernetes.io/name=phpfpm -c nginx │ │ Persistent Volume (PVC) │ │ │ │ /var/www/html │ │ │ └──────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────┐ │ -│ │ Selenium (Optional) │ │ -│ │ :4444 │ │ -│ └─────────────────────────────────────┘ │ -└─────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────┐ -│ External Database (Optional) │ -│ MySQL/MariaDB │ └─────────────────────────────────────────────┘ + │ │ + ▼ ▼ SELENIUM_URL(自動注入) +┌─────────────────────────────┐ ┌──────────────────────────────┐ +│ External Database (Optional)│ │ Selenium Deployment(Optional)│ +│ MySQL/MariaDB │ │ 独立Pod・独立Service :4444 │ +└─────────────────────────────┘ └──────────────────────────────┘ ``` +> **Selenium は独立した Deployment/Service(v8.5.10-b以降)**。以前は上の Pod 内の +> サイドカーコンテナだったが、Selenium 単体の不調(起動失敗・OOM等)で Pod 全体が +> Service の Endpoints から外れ、サイト全体が停止する問題があったため分離した +> (下記トラブルシューティング参照)。 + ## 主要な設定パラメータ ### 基本設定 @@ -175,11 +175,18 @@ PHPからPythonスクリプトを呼び出す用途(データ処理・機械 ### Selenium設定 +v8.5.10-b以降、Seleniumは独立したDeployment/Service(`-phpfpm-selenium`)として起動する(nginx/php-fpmと同一Podのサイドカーではない)。 + | パラメータ | 説明 | デフォルト | |-----------|------|-----------| | `selenium.enabled` | Selenium有効化 | `false` | +| `selenium.replicaCount` | Selenium Deploymentのレプリカ数 | `1` | +| `selenium.resources` | SeleniumコンテナのCPU/メモリ requests・limits | `{}` | +| `selenium.mountHtml` | PVCの`html`サブパスをSeleniumにもマウントするか(別Podからの同時マウントになるため`true`にする場合は`persistence.accessMode: ReadWriteMany`が必要) | `false` | | `image.selenium.tag` | Seleniumバージョン | `144.0-chromedriver-144.0` | +`selenium.enabled: true`のとき、php-fpmコンテナの`SELENIUM_URL`環境変数は自動的にこのServiceを指す値(`http://-phpfpm-selenium:4444/wd/hub`)に設定される。`phpEnv.SELENIUM_URL`を独自に指定していても、この自動注入された値が優先される。 + ### 外部データベース設定 | パラメータ | 説明 | デフォルト | @@ -427,19 +434,26 @@ composer: - "monolog/monolog:^3.0" selenium: - enabled: true # php-webdriver/webdriverが自動追加 + enabled: true # php-webdriver/webdriverが自動追加。独立Deployment/Serviceとして起動する + resources: + requests: + memory: "1Gi" + cpu: "500m" + limits: + memory: "3Gi" + cpu: "2000m" persistence: enabled: true size: 5Gi resources: - requests: - memory: "1Gi" - cpu: "1000m" - limits: - memory: "3Gi" - cpu: "2000m" + nginx: + requests: { memory: "64Mi", cpu: "50m" } + limits: { memory: "128Mi" } + phpfpm: + requests: { memory: "256Mi", cpu: "200m" } + limits: { memory: "512Mi", cpu: "1000m" } ``` **PHPコード例**: @@ -450,9 +464,10 @@ require_once '/composer/vendor/autoload.php'; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\DesiredCapabilities; -// Seleniumに接続 +// Seleniumに接続(SELENIUM_URLはselenium.enabled:trueのとき自動注入される。 +// 別Deploymentになったため localhost では到達できない点に注意) $driver = RemoteWebDriver::create( - 'http://localhost:4444', + getenv('SELENIUM_URL') ?: 'http://-phpfpm-selenium:4444/wd/hub', DesiredCapabilities::chrome() ); @@ -934,6 +949,25 @@ helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.ya kubectl delete pod -n -l app.kubernetes.io/name=phpfpm ``` +### `selenium.enabled: true` でコンテナが不安定になるとサイト全体が完全停止する + +**症状**: `selenium.enabled: true` の構成で、いずれかのコンテナ(php-fpm・Selenium 等)が `CrashLoopBackOff` になっている間、Selenium を全く使わない静的ページも含めてサイト全体が閲覧不能(502等)になる。`kubectl get pod` で `2/3` や `1/3` の READY 表示が続く。 + +**原因**: v8.5.10-b より前は Selenium が nginx/php-fpm と同一 Pod のサイドカーコンテナだった。Kubernetes は Pod の Ready 条件を「全コンテナが Ready」の AND で判定するため、readinessProbe を持たないコンテナは Running であれば Ready 扱いになる一方、いずれか1つでも CrashLoopBackOff で Waiting/Terminated を繰り返している間は Pod 全体が Ready=false になる。Service は Ready な Pod にしかトラフィックを流さないため、`replicaCount: 1`(冗長性なし)の構成では **1つのコンテナの不調がサイト全体の完全停止に直結していた**。 + +これに加えて、`resources` values キーが v8.5.10-a 以前はテンプレート側で参照されておらず、どのコンテナにも requests/limits が反映されない「死んだ設定」だった。全コンテナが `QoS Class: BestEffort` になり、ノードのメモリ逼迫時に OOM Killer の対象になりやすい状態だった(Chromium を含む Selenium は特にメモリを消費するため、この影響を受けやすい)。 + +**対策**: **v8.5.10-b 以降にアップグレードする**。 + +1. Selenium が独立した Deployment/Service(`-phpfpm-selenium`)になり、Selenium 単体の不調がメイン Pod(nginx/php-fpm)の Ready 状態に一切影響しなくなった。 +2. `resources.nginx` / `resources.phpfpm` / `selenium.resources` で実際に requests/limits を設定できるようになった。本番運用では設定を強く推奨する(未設定のままだと引き続き BestEffort のままで、OOM Kill のリスクは残る)。 + +```bash +helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.10-b -f values.yaml +``` + +アップグレード後に確認すべき点は `CHANGELOG-8.5.10-b.md` の「互換性(重要・要対応)」を参照(`selenium.mountHtml` / `phpEnv.SELENIUM_URL` の扱い)。 + ### データベース接続エラー **確認**: @@ -954,8 +988,8 @@ kubectl logs -c php-fpm # Nginxログ kubectl logs -c nginx -# Seleniumログ(有効時) -kubectl logs -c selenium +# Seleniumログ(有効時。v8.5.10-b以降は別Pod・別Deploymentのため -c 指定は不要) +kubectl logs -l app.kubernetes.io/component=selenium # リアルタイム監視 kubectl logs -f -c php-fpm @@ -1134,7 +1168,7 @@ kubectl cp ./my-app :/var/www/html/ -c php-fpm - [Composer使用ガイド](./COMPOSER_GUIDE.md) - [マイグレーションガイド](./MIGRATION_GUIDE.md) -- [Selenium別チャート化設計](./SELENIUM_SEPARATION_DESIGN.md) +- Selenium別Deployment化の設計・経緯は本READMEの「Selenium設定」セクションと `CHANGELOG-8.5.10-b.md` を参照(旧: 本リンク先の設計ドキュメントは作成されず実装が先行したため削除) ## ライセンス diff --git a/templates/deployment-selenium.yaml b/templates/deployment-selenium.yaml new file mode 100644 index 0000000..9534a01 --- /dev/null +++ b/templates/deployment-selenium.yaml @@ -0,0 +1,68 @@ +{{- if .Values.selenium.enabled }} +# Selenium を nginx/php-fpm と別 Deployment にする理由(v8.5.10-b): +# +# 以前は selenium/standalone-chromium を nginx・php-fpm と同一 Pod のサイドカー +# コンテナとして起動していた。Kubernetes は Pod の Ready 条件を「全コンテナが Ready」 +# の AND で判定するため、readinessProbe を持たないコンテナは「Running であれば Ready」 +# として扱われる一方、CrashLoopBackOff で Waiting/Terminated を繰り返す間は Ready=false +# になる。この間 Pod 全体が Service の Endpoints から外れるため、Selenium コンテナ +# だけが不安定(起動失敗・OOM等)でも、Selenium を全く使わない静的ページの配信まで +# 巻き込まれてサービス全体が完全停止していた。 +# +# Selenium を独立した Deployment/Service に分離することで、Selenium の不調が +# nginx/php-fpm Pod の Ready 状態に一切影響しなくなり、スクレイピング機能のみが +# 影響を受け、サイト自体は表示され続ける。 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "phpfpm.fullname" . }}-selenium + labels: + {{- include "phpfpm.labels" . | nindent 4 }} + app.kubernetes.io/component: selenium +spec: + replicas: {{ .Values.selenium.replicaCount | default 1 }} + selector: + matchLabels: + {{- include "phpfpm.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: selenium + template: + metadata: + labels: + {{- include "phpfpm.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: selenium + spec: + containers: + - name: selenium + image: "{{ .Values.image.selenium.registry }}/{{ .Values.image.selenium.repository }}:{{ .Values.image.selenium.tag }}" + imagePullPolicy: {{ .Values.image.selenium.pullPolicy }} + ports: + - containerPort: 4444 # Selenium用ポート + {{- with .Values.selenium.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.selenium.mountHtml }} + volumeMounts: + - name: app-storage + mountPath: /var/www/html + subPath: html + {{- end }} + dnsPolicy: ClusterFirst + dnsConfig: + options: + - name: ndots + value: "1" + {{- if .Values.selenium.mountHtml }} + volumes: + - name: app-storage + # 別 Pod から同じ PVC の html/ サブパスを読み書きするため、 + # persistence.accessMode を ReadWriteMany にする必要がある + # (NFS バックエンドの StorageClass なら対応可能)。 + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "phpfpm.fullname" . }}-pvc + {{- else }} + emptyDir: {} + {{- end }} + {{- end }} +{{- end }} diff --git a/templates/deployment.yaml b/templates/deployment.yaml index 1ee5716..c278750 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -9,10 +9,12 @@ spec: selector: matchLabels: {{- include "phpfpm.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: web template: metadata: labels: {{- include "phpfpm.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: web spec: containers: - name: nginx @@ -20,6 +22,10 @@ spec: imagePullPolicy: {{ .Values.image.nginx.pullPolicy }} ports: - containerPort: 80 + {{- with .Values.resources.nginx }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} volumeMounts: - name: app-storage mountPath: /var/www/html @@ -264,6 +270,10 @@ spec: exec php-fpm -F ports: - containerPort: 9000 # PHP-FPMは9000ポートでリッスン + {{- with .Values.resources.phpfpm }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} volumeMounts: # PVCルートを /var/www にマウント # - /var/www/html のみ nginx が公開(nginx側は html サブパスだけをマウント) @@ -306,6 +316,14 @@ spec: - name: {{ $key }} value: {{ $value | quote }} {{- end }} + {{- if .Values.selenium.enabled }} + # Selenium は別 Deployment/Service(templates/deployment-selenium.yaml)として + # 稼働する(v8.5.10-b 以降。selenium.enabled=true の Pod と同居させない設計に変更)。 + # phpEnv に SELENIUM_URL を書いても、この行が env リストの後方にあるため + # 最終的にこちらが優先される(Kubernetes は同名 env の重複時、後方の値を採用する)。 + - name: SELENIUM_URL + value: "http://{{ include "phpfpm.fullname" . }}-selenium:4444/wd/hub" + {{- end }} {{- with .Values.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} @@ -313,17 +331,6 @@ spec: envFrom: {{- toYaml . | nindent 12 }} {{- end }} - {{- if .Values.selenium.enabled }} - - name: selenium - image: "{{ .Values.image.selenium.registry }}/{{ .Values.image.selenium.repository }}:{{ .Values.image.selenium.tag }}" - imagePullPolicy: {{ .Values.image.selenium.pullPolicy }} - ports: - - containerPort: 4444 # Selenium用ポート - volumeMounts: - - name: app-storage - mountPath: /var/www/html - subPath: html - {{- end }} dnsPolicy: ClusterFirst dnsConfig: options: diff --git a/templates/service-selenium.yaml b/templates/service-selenium.yaml new file mode 100644 index 0000000..4e49c3a --- /dev/null +++ b/templates/service-selenium.yaml @@ -0,0 +1,19 @@ +{{- if .Values.selenium.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "phpfpm.fullname" . }}-selenium + labels: + {{- include "phpfpm.labels" . | nindent 4 }} + app.kubernetes.io/component: selenium +spec: + type: ClusterIP + ports: + - port: 4444 + targetPort: 4444 + protocol: TCP + name: selenium + selector: + {{- include "phpfpm.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: selenium +{{- end }} diff --git a/templates/service.yaml b/templates/service.yaml index 04ceee1..70538bc 100644 --- a/templates/service.yaml +++ b/templates/service.yaml @@ -13,3 +13,4 @@ spec: name: http selector: {{- include "phpfpm.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: web diff --git a/values.yaml b/values.yaml index 36608ff..03842ad 100644 --- a/values.yaml +++ b/values.yaml @@ -179,9 +179,27 @@ python: # - "python3-dev" # - "jpeg-dev" -# Selenium設定(レガシー互換性維持) +# Selenium設定 +# v8.5.10-b以降、Selenium(有効時)はnginx/php-fpmと同一Podのサイドカーではなく、 +# 独立したDeployment/Service(-phpfpm-selenium)として起動する。 +# 理由: サイドカー方式だとSelenium単体の不調(起動失敗・OOM等)でPod全体がReady=false +# になり、Seleniumを使わない静的ページ配信まで巻き込まれてサービス全体が止まっていた。 +# php-fpmコンテナのSELENIUM_URL環境変数は、enabled:true時に自動でこのServiceを指す +# (phpEnvで独自に設定しても、こちらの値が優先される)。 selenium: enabled: false + # Selenium Deployment自体のレプリカ数 + replicaCount: 1 + # Chromiumはメモリを多く使う。ノードのメモリ枯渇によるOOM Killを防ぐため、 + # 実運用では必ずrequests/limitsを設定することを推奨する(下記resourcesセクション参照)。 + resources: {} + # trueにすると、SeleniumコンテナにもPVCのhtmlサブパスを/var/www/htmlとしてマウントする + # (ブラウザのダウンロード先を公開ディレクトリに置きたい場合など)。別Podからの同時マウント + # になるため、有効にする場合はpersistence.accessModeをReadWriteMany + # (NFSバックエンドのStorageClassなら対応可能)にする必要がある。 + # 通常のスクレイピング用途(スクリーンショット等をstorage/等の非公開領域に保存する場合) + # では不要なため、既定はfalse。 + mountHtml: false externalDatabase: enabled: false @@ -254,7 +272,23 @@ smtp: existingMsmtprcSecret: "" existingMsmtprcSecretKey: "msmtprc" -resources: {} +# nginx / php-fpm コンテナの CPU/メモリ requests・limits。 +# v8.5.10-b より前は本キーがテンプレート側で参照されておらず(死んだ設定)、 +# 何を指定してもコンテナには一切反映されない不具合があった(既存デプロイは +# 全コンテナが requests/limits なしの QoS Class: BestEffort になっていた)。 +# BestEffortはノードのメモリ逼迫時にOOM Killの対象になりやすいため、 +# 本番運用では requests/limits の設定を推奨する。例: +# resources: +# nginx: +# requests: { cpu: "50m", memory: "64Mi" } +# limits: { memory: "128Mi" } +# phpfpm: +# requests: { cpu: "100m", memory: "256Mi" } +# limits: { memory: "512Mi" } +# (selenium用は selenium.resources を参照。Chromiumは256Mi等では確実に不足する) +resources: + nginx: {} + phpfpm: {} # PHP-FPM コンテナに渡す任意の環境変数 # DB接続情報(externalDatabase)と同様に、values.yamlで設定した値がPHPに環境変数として渡される