fix: v8.5.10-bのDeployment.spec.selector変更が既存リリースのアップグレードを壊す不具合を修正
Helm Chart Release / release-chart (push) Successful in 9s

既存のnginx/php-fpm Deploymentのspec.selector.matchLabelsにapp.kubernetes.io/component:webを追加していたが、Deployment.spec.selectorは作成後immutableのためhelm upgradeが'field is immutable'で失敗していた。既存Deploymentのselectorは元の内容(name+instanceのみ)に戻し、Selenium側はcomponentラベルではなくapp.kubernetes.io/name自体を<chart名>-seleniumという別名にする方式(新ヘルパーphpfpm.selenium.name/phpfpm.selenium.selectorLabels)に変更した。componentラベルだけを足す設計だとSeleniumのPodもnginx/php-fpm側Deploymentのselectorに一致してしまいReplicaSetの選択重複を起こすため、name自体をvariantにして構造的に防止する。v8.5.10-bは既存リリースへの適用不可のためスキップし、v8.5.10-c以降を使うこと。
This commit is contained in:
2026-09-26 09:46:56 +09:00
parent 86cd705d06
commit abb5dba4a1
9 changed files with 107 additions and 10 deletions
+5
View File
@@ -1,5 +1,10 @@
# Changelog - Version 8.5.10-b # Changelog - Version 8.5.10-b
> ⚠️ **v8.5.10-b は単体では既存リリースの `helm upgrade` が失敗する不具合を含む**
> (`Deployment.spec.selector: ... field is immutable`)。設計・原因の記録として
> 本ファイルは残すが、**実際の適用は v8.5.10-c 以降を使うこと**。修正内容は
> `CHANGELOG-8.5.10-c.md` を参照。
## 不具合修正・アーキテクチャ変更 ## 不具合修正・アーキテクチャ変更
### Selenium を独立した Deployment/Service に分離(サービス完全停止の防止) ### Selenium を独立した Deployment/Service に分離(サービス完全停止の防止)
+60
View File
@@ -0,0 +1,60 @@
# Changelog - Version 8.5.10-c
## 不具合修正
### v8.5.10-b の Selenium分離が既存リリースのアップグレードを壊す問題を修正
v8.5.10-b で Selenium を独立 Deployment/Service に分離した際、既存の nginx/php-fpm
Deployment の `spec.selector.matchLabels` に `app.kubernetes.io/component: web` を
追加した。しかし **`Deployment.spec.selector` は作成後 immutable** であり、
既存リリースを `helm upgrade` すると次のエラーで失敗する。
```
cannot patch "<release>-phpfpm" with kind Deployment: Deployment.apps "<release>-phpfpm"
is invalid: spec.selector: Invalid value: ...: field is immutable.
```
**対応**
- 既存の nginx/php-fpm Deployment の `spec.selector.matchLabels` は
元の内容(`app.kubernetes.io/name` + `app.kubernetes.io/instance` のみ)に戻し、
以後も変更しない。
- Selenium 側は `app.kubernetes.io/component` ラベルではなく、
**`app.kubernetes.io/name` 自体を `<chart名>-selenium` という別名にする**方式に変更した
(新ヘルパー `phpfpm.selenium.name` / `phpfpm.selenium.selectorLabels`。
`templates/_helpers.tpl`)。component ラベルを足すだけの設計だと、Selenium の Pod も
nginx/php-fpm 側 Deployment の selector(name+instance)に一致してしまい、
2つの Deployment(ReプリカSet)が同じ Pod 集合を取り合う selector 重複を起こすため、
name 自体を variant にして構造的に重複を防止する。
- `templates/deployment-selenium.yaml` / `templates/service-selenium.yaml` の
selector・pod template labels をこの新ヘルパーに合わせて修正。
`app.kubernetes.io/component: selenium` は情報用のラベルとして pod template には
引き続き付与する(selector には使わない。README の `kubectl logs -l
app.kubernetes.io/component=selenium` 等の運用コマンドはそのまま使える)。
- メインの Service(`<release>-phpfpm`)の selector に残した
`app.kubernetes.io/component: web` は Service の selector なので immutable 制約は
受けず、そのまま維持している(Selenium 側が別名になったことで実質不要になったが、
害はないため多層防御として残す)。
**v8.5.10-b をまだ適用していない場合**: 8.5.10-b は上記のバグを含むため、
直接 **8.5.10-c 以降**を適用すること。
**v8.5.10-b の適用に失敗した場合**(今回のエラーが出た場合): リリースは
アップグレードに失敗した時点のリビジョンのままのはずなので、Chart version を
`8.5.10-c` に変更して再度アップグレードすればよい(追加の手動復旧は不要)。
**対象ファイル**: `templates/_helpers.tpl`, `templates/deployment.yaml`,
`templates/deployment-selenium.yaml`, `templates/service-selenium.yaml`, `Chart.yaml`,
`CHANGELOG-8.5.10-c.md`
## アップグレード手順
```bash
helm repo update
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.10-c -f values.yaml
```
---
**リリース日**: 2026-09-26
**担当**: プロサーバーエンジニア(Claude)
+6
View File
@@ -27,6 +27,12 @@ Websites 組織の各サイト(e-learn.jp / fcdomain.com / hotels / tskholding
## チャート改修履歴 ## チャート改修履歴
### v8.5.10-bのDeployment.spec.selector変更が既存リリースのアップグレードを壊す不具合を修正(2026-09-26, v8.5.10-c)
v8.5.10-bでnginx/php-fpm Deploymentのspec.selector.matchLabelsに`app.kubernetes.io/component: web`を追加したが、Deployment.spec.selectorは作成後immutableのため既存リリースの`helm upgrade`が「field is immutable」で失敗する不具合を確認・修正した。既存Deploymentのselectorは元の内容(name+instanceのみ)に戻し、Selenium側はcomponentラベルではなく`app.kubernetes.io/name`自体を`<chart名>-selenium`という別名にする方式(新ヘルパー`phpfpm.selenium.name`/`phpfpm.selenium.selectorLabels`)に変更した。componentラベルだけを足す設計だと、SeleniumのPodもnginx/php-fpm側Deploymentのselector(name+instance)に一致してしまい2つのDeployment(ReplicaSet)が同じPod集合を取り合う選択重複を起こすため、name自体をvariantにして構造的に防止する。v8.5.10-bは未適用ならスキップしてv8.5.10-c以降を直接使うこと。
**対象ファイル**: `templates/_helpers.tpl`, `templates/deployment.yaml`, `templates/deployment-selenium.yaml`, `templates/service-selenium.yaml`, `Chart.yaml`, `CHANGELOG-8.5.10-c.md`
### Selenium を独立Deployment/Serviceに分離 + resources死んだ設定を修正(2026-09-26, v8.5.10-b) ### 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(`<release>-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点はコード上確認済みの確定した欠陥のため先行修正した。 `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(`<release>-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点はコード上確認済みの確定した欠陥のため先行修正した。
+1 -1
View File
@@ -2,6 +2,6 @@ apiVersion: v2
name: phpfpm name: phpfpm
description: Nginx + PHP-FPM Helm Chart with external DB and optional Selenium support description: Nginx + PHP-FPM Helm Chart with external DB and optional Selenium support
type: application type: application
version: 8.5.10-b version: 8.5.10-c
appVersion: "8.5.10" appVersion: "8.5.10"
icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png
+5 -3
View File
@@ -957,13 +957,15 @@ kubectl delete pod -n <namespace> -l app.kubernetes.io/name=phpfpm
これに加えて、`resources` values キーが v8.5.10-a 以前はテンプレート側で参照されておらず、どのコンテナにも requests/limits が反映されない「死んだ設定」だった。全コンテナが `QoS Class: BestEffort` になり、ノードのメモリ逼迫時に OOM Killer の対象になりやすい状態だった(Chromium を含む Selenium は特にメモリを消費するため、この影響を受けやすい)。 これに加えて、`resources` values キーが v8.5.10-a 以前はテンプレート側で参照されておらず、どのコンテナにも requests/limits が反映されない「死んだ設定」だった。全コンテナが `QoS Class: BestEffort` になり、ノードのメモリ逼迫時に OOM Killer の対象になりやすい状態だった(Chromium を含む Selenium は特にメモリを消費するため、この影響を受けやすい)。
**対策**: **v8.5.10-b 以降にアップグレードする**。 **対策**: **v8.5.10-c 以降にアップグレードする**(v8.5.10-b は既存リリースの
アップグレードが `spec.selector: ... field is immutable` で失敗する不具合を含むため、
v8.5.10-b を経由せず直接 v8.5.10-c 以降を使うこと。詳細は `CHANGELOG-8.5.10-c.md`)。
1. Selenium が独立した Deployment/Service(`<release>-phpfpm-selenium`)になり、Selenium 単体の不調がメイン Pod(nginx/php-fpm)の Ready 状態に一切影響しなくなった。 1. Selenium が独立した Deployment/Service(`<release>-phpfpm-selenium`)になり、Selenium 単体の不調がメイン Pod(nginx/php-fpm)の Ready 状態に一切影響しなくなった。
2. `resources.nginx` / `resources.phpfpm` / `selenium.resources` で実際に requests/limits を設定できるようになった。本番運用では設定を強く推奨する(未設定のままだと引き続き BestEffort のままで、OOM Kill のリスクは残る)。 2. `resources.nginx` / `resources.phpfpm` / `selenium.resources` で実際に requests/limits を設定できるようになった。本番運用では設定を強く推奨する(未設定のままだと引き続き BestEffort のままで、OOM Kill のリスクは残る)。
```bash ```bash
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.10-b -f values.yaml helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.10-c -f values.yaml
``` ```
アップグレード後に確認すべき点は `CHANGELOG-8.5.10-b.md` の「互換性(重要・要対応)」を参照(`selenium.mountHtml` / `phpEnv.SELENIUM_URL` の扱い)。 アップグレード後に確認すべき点は `CHANGELOG-8.5.10-b.md` の「互換性(重要・要対応)」を参照(`selenium.mountHtml` / `phpEnv.SELENIUM_URL` の扱い)。
@@ -1168,7 +1170,7 @@ kubectl cp ./my-app <pod-name>:/var/www/html/ -c php-fpm
- [Composer使用ガイド](./COMPOSER_GUIDE.md) - [Composer使用ガイド](./COMPOSER_GUIDE.md)
- [マイグレーションガイド](./MIGRATION_GUIDE.md) - [マイグレーションガイド](./MIGRATION_GUIDE.md)
- Selenium別Deployment化の設計・経緯は本READMEの「Selenium設定」セクションと `CHANGELOG-8.5.10-b.md` を参照(旧: 本リンク先の設計ドキュメントは作成されず実装が先行したため削除) - Selenium別Deployment化の設計・経緯は本READMEの「Selenium設定」セクションと `CHANGELOG-8.5.10-b.md`(設計)・`CHANGELOG-8.5.10-c.md`(既存リリースのアップグレードを壊す不具合の修正)を参照(旧: 本リンク先の設計ドキュメントは作成されず実装が先行したため削除)
## ライセンス ## ライセンス
+22
View File
@@ -19,3 +19,25 @@ app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/name: {{ include "phpfpm.name" . }} app.kubernetes.io/name: {{ include "phpfpm.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }} {{- end }}
{{/*
Selenium 用の名前・セレクタラベル(v8.5.10-b)。
nginx/php-fpm の既存 Deployment は spec.selector が作成後 immutable なため、
そちらの selector には手を加えられない("field is immutable" でアップグレードが
失敗する)。そのため Selenium 側は app.kubernetes.io/name 自体を variant
("phpfpm-selenium")にして、nginx/php-fpm の Deployment の selector
(name=phpfpm, instance=<release>)とラベルの組が完全に一致しないようにする。
component ラベルだけを足す設計だと、Selenium の Pod も name=phpfpm/instance=<release>
を持つため nginx/php-fpm 側 Deployment の selector にも一致してしまい、
2つの Deployment(ReplicaSet)が同じ Pod 集合を取り合う selector 重複を起こす。
name を variant にすることで、この重複を構造的に防止する。
*/}}
{{- define "phpfpm.selenium.name" -}}
{{- printf "%s-selenium" (include "phpfpm.name" .) | trunc 63 | trimSuffix "-" -}}
{{- end }}
{{- define "phpfpm.selenium.selectorLabels" -}}
app.kubernetes.io/name: {{ include "phpfpm.selenium.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
+2 -3
View File
@@ -23,12 +23,11 @@ spec:
replicas: {{ .Values.selenium.replicaCount | default 1 }} replicas: {{ .Values.selenium.replicaCount | default 1 }}
selector: selector:
matchLabels: matchLabels:
{{- include "phpfpm.selectorLabels" . | nindent 6 }} {{- include "phpfpm.selenium.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: selenium
template: template:
metadata: metadata:
labels: labels:
{{- include "phpfpm.selectorLabels" . | nindent 8 }} {{- include "phpfpm.selenium.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: selenium app.kubernetes.io/component: selenium
spec: spec:
containers: containers:
+5 -1
View File
@@ -7,9 +7,13 @@ metadata:
spec: spec:
replicas: {{ .Values.replicaCount }} replicas: {{ .Values.replicaCount }}
selector: selector:
# 注意: Deployment.spec.selector は作成後 immutable。既存リリースの
# アップグレードを壊さないため、ここに app.kubernetes.io/component は
# 追加しない(component ラベルは下の pod template と Service の
# selector のみに付与する。template.metadata.labels は matchLabels の
# superset であればよいため、追加ラベルを持たせても問題ない)。
matchLabels: matchLabels:
{{- include "phpfpm.selectorLabels" . | nindent 6 }} {{- include "phpfpm.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: web
template: template:
metadata: metadata:
labels: labels:
+1 -2
View File
@@ -14,6 +14,5 @@ spec:
protocol: TCP protocol: TCP
name: selenium name: selenium
selector: selector:
{{- include "phpfpm.selectorLabels" . | nindent 4 }} {{- include "phpfpm.selenium.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: selenium
{{- end }} {{- end }}