cron.jobs(配列)にジョブを定義すると、php-fpmと同じPHPイメージを使う Kubernetes CronJobをジョブごとに生成する。 - templates/cronjob.yaml(新規): PVCルートを/var/wwwにマウントし、 externalDatabase/phpEnv/extraEnv/extraEnvFrom/SELENIUM_URLをphp-fpm コンテナと同じ内容で注入。smtp.enabled時はmsmtpも自動導入。 - templates/_helpers.tpl: phpfpm.cron.name/selectorLabelsを追加。 Selenium分離と同じ理由で、生成PodのラベルをDeploymentのselectorと 衝突しないバリアント名(<chart>-cron)にする。 - values.yaml: cronセクションを追加(既定は空配列で無効)。 - README.md: パラメータ表と使用例、Composer/Pythonとの併用時の注意点 (デフォルトの使い捨て領域はCronJobから見えないため、永続化パスへの 変更が必要)を追加。 templates/deployment.yamlは変更していない(既存Deploymentへの影響なし)。 手動リリース 8.5.10-e。
This commit is contained in:
@@ -27,6 +27,16 @@ Websites 組織の各サイト(e-learn.jp / fcdomain.com / hotels / tskholding
|
|||||||
|
|
||||||
## チャート改修履歴
|
## チャート改修履歴
|
||||||
|
|
||||||
|
### Cron(CronJob)定期実行機能を追加(2026-09-27, v8.5.10-e)
|
||||||
|
|
||||||
|
- **背景**: 定期実行したいPHPスクリプト(レポート送信・バッチ処理等)を動かす手段がなく、外部で別途スケジューラを用意する必要があった。
|
||||||
|
- **追加内容**: `cron.jobs`(配列)にジョブを定義すると、`templates/cronjob.yaml`がジョブごとにKubernetes CronJobを生成する。php-fpmと同じPHPイメージを使用し、PVCルートを`/var/www`にマウント、`externalDatabase`/`phpEnv`/`extraEnv`/`extraEnvFrom`/`SELENIUM_URL`をphp-fpmコンテナと同じ内容で注入する。`smtp.enabled: true`の場合はCronJob内でも自動的にmsmtpを導入する(`templates/deployment.yaml`のSMTP設定と重複実装、変更時は両方揃えること)。
|
||||||
|
- **設計上の注意点**:
|
||||||
|
- CronJobが生成するPodのラベル(`app.kubernetes.io/name`)は`phpfpm.cron.name`ヘルパーで`<chart>-cron`というバリアント名にしている。Selenium分離(v8.5.10-b)と同じ理由で、nginx/php-fpm DeploymentのmatchLabels(`name: phpfpm, instance: <release>`)と一致させると、ReplicaSetコントローラーがCronJob由来のPodを誤って自身の管理対象とみなし削除する事故につながるため。
|
||||||
|
- CronJob名は`trunc 52`で切り詰めている(Kubernetesの実務上の制約。CronJobは生成するJob/Pod名にタイムスタンプ等のsuffixが付くため、フルの253/63文字ではなく52文字程度に収める必要がある)。
|
||||||
|
- Composer(`/composer`)・Python venv(`/venv`)はデフォルトでPVC非マウントの使い捨て領域のため、CronJobのPodには存在しない。意図的にCronJob側では再インストールを行わない設計とした(頻繁な実行での再インストールコストを避けるため)。CronJobから使いたい場合は`composer.workingDir`/`python.venvDir`を`/var/www`配下に変更しPVC上へ永続化することをREADMEで案内している。
|
||||||
|
- **対象ファイル**: `templates/cronjob.yaml`(新規), `templates/_helpers.tpl`, `values.yaml`, `README.md`, `Chart.yaml`
|
||||||
|
|
||||||
### ingress.tls[].secretNameをhostから自動導出可能に(2026-09-27, v8.5.10-d)
|
### ingress.tls[].secretNameをhostから自動導出可能に(2026-09-27, v8.5.10-d)
|
||||||
|
|
||||||
- **背景**: `ingress.hosts[].host` は既にYAMLアンカー(`&appDomain`)で `ingress.tls[].hosts` と値を共有できるようになっていたが、`ingress.tls[].secretName` は独立した文字列指定が必須で、ドメイン変更時に別途書き換えが必要だった。
|
- **背景**: `ingress.hosts[].host` は既にYAMLアンカー(`&appDomain`)で `ingress.tls[].hosts` と値を共有できるようになっていたが、`ingress.tls[].secretName` は独立した文字列指定が必須で、ドメイン変更時に別途書き換えが必要だった。
|
||||||
|
|||||||
+1
-1
@@ -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-d
|
version: 8.5.10-e
|
||||||
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
|
||||||
|
|||||||
@@ -187,6 +187,43 @@ v8.5.10-b以降、Seleniumは独立したDeployment/Service(`<release>-phpfpm-
|
|||||||
|
|
||||||
`selenium.enabled: true`のとき、php-fpmコンテナの`SELENIUM_URL`環境変数は自動的にこのServiceを指す値(`http://<release>-phpfpm-selenium:4444/wd/hub`)に設定される。`phpEnv.SELENIUM_URL`を独自に指定していても、この自動注入された値が優先される。
|
`selenium.enabled: true`のとき、php-fpmコンテナの`SELENIUM_URL`環境変数は自動的にこのServiceを指す値(`http://<release>-phpfpm-selenium:4444/wd/hub`)に設定される。`phpEnv.SELENIUM_URL`を独自に指定していても、この自動注入された値が優先される。
|
||||||
|
|
||||||
|
### Cron(定期実行)設定
|
||||||
|
|
||||||
|
`cron.jobs`に1件以上定義すると、php-fpmと同じPHPイメージ(`image.php`)を使ってスケジュール実行するKubernetes CronJobが、ジョブごとに1つずつ作成される。既定は空配列で、何も作成されない。
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `cron.jobs` | CronJob定義の配列 | `[]` |
|
||||||
|
| `cron.jobs[].name` | ジョブ名(英数字とハイフン、CronJob名の一部に使用) | 必須 |
|
||||||
|
| `cron.jobs[].schedule` | 標準cron形式のスケジュール | 必須 |
|
||||||
|
| `cron.jobs[].command` | 実行するシェルコマンド(文字列) | 必須 |
|
||||||
|
| `cron.jobs[].timeZone` | タイムゾーン(Kubernetes 1.27+) | 省略時UTC |
|
||||||
|
| `cron.jobs[].concurrencyPolicy` | `Allow`/`Forbid`/`Replace` | `Forbid` |
|
||||||
|
| `cron.jobs[].restartPolicy` | `OnFailure`/`Never` | `OnFailure` |
|
||||||
|
| `cron.jobs[].successfulJobsHistoryLimit` | 成功ジョブの保持数 | `3` |
|
||||||
|
| `cron.jobs[].failedJobsHistoryLimit` | 失敗ジョブの保持数 | `1` |
|
||||||
|
| `cron.jobs[].activeDeadlineSeconds` | 実行タイムアウト(秒) | 省略可 |
|
||||||
|
| `cron.jobs[].suspend` | `true`でこのジョブだけ一時停止 | `false` |
|
||||||
|
| `cron.jobs[].resources` | CPU/メモリ requests・limits | `resources.phpfpm`を流用 |
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
cron:
|
||||||
|
jobs:
|
||||||
|
- name: daily-report
|
||||||
|
schedule: "0 18 * * *"
|
||||||
|
timeZone: "Asia/Tokyo"
|
||||||
|
command: "php /var/www/html/cron/daily-report.php"
|
||||||
|
```
|
||||||
|
|
||||||
|
> **📌 CronJobの構成について**
|
||||||
|
> - PVCルートを`/var/www`にマウントする(php-fpmコンテナと同じ)。`html/`配下の公開コード、または非公開ディレクトリのスクリプト・出力先どちらも利用できる。
|
||||||
|
> - `externalDatabase` / `phpEnv` / `extraEnv` / `extraEnvFrom` / `SELENIUM_URL`(selenium有効時)は、php-fpmコンテナと同じ内容が渡される。
|
||||||
|
> - `smtp.enabled: true`の場合、CronJobのPodでも自動的にmsmtpを導入してmsmtprcを配置するため、PHPの`mail()`関数がそのまま使える。
|
||||||
|
> - **Composer/Pythonとの併用**: `composer.workingDir`/`python.venvDir`が既定の`/composer`・`/venv`(PVC非マウントの使い捨て領域)のままだと、php-fpmの常駐Pod内にしか存在しないためCronJobからは使えない。CronJobから使いたい場合は`composer.workingDir: "/var/www/composer"`のように`/var/www`配下へ変更し、PVC上に永続化すること。
|
||||||
|
> - CronJobの名前は52文字を超えないよう自動的に切り詰められる(Kubernetesの制約)。`cron.jobs[].name`は短く分かりやすい名前にすること。
|
||||||
|
> - 生成されるPodのラベル(`app.kubernetes.io/name`)は`<chart>-cron`というバリアント名になっており、nginx/php-fpmのDeploymentのselectorとは一致しない(Selenium分離と同じ設計)。
|
||||||
|
|
||||||
### 外部データベース設定
|
### 外部データベース設定
|
||||||
|
|
||||||
| パラメータ | 説明 | デフォルト |
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|||||||
@@ -41,3 +41,23 @@ name を variant にすることで、この重複を構造的に防止する。
|
|||||||
app.kubernetes.io/name: {{ include "phpfpm.selenium.name" . }}
|
app.kubernetes.io/name: {{ include "phpfpm.selenium.name" . }}
|
||||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Cron(CronJob)用の名前・ラベル(v8.5.10-e)。
|
||||||
|
|
||||||
|
Selenium と同じ理由で、CronJobが生成するPodのラベルにも nginx/php-fpm の
|
||||||
|
Deployment と同じ app.kubernetes.io/name("phpfpm")+ instance を持たせては
|
||||||
|
いけない。同じ組み合わせだとDeploymentのReplicaSetコントローラーが
|
||||||
|
matchLabels(name=phpfpm, instance=<release>)に一致するPodとしてCronJob由来
|
||||||
|
のPodまで対象に含めてしまい、replicaCountとの差分調整でCronJobのPodを
|
||||||
|
意図せず削除する等の事故につながる。name自体をvariant("phpfpm-cron")に
|
||||||
|
することで構造的に衝突を防ぐ。
|
||||||
|
*/}}
|
||||||
|
{{- define "phpfpm.cron.name" -}}
|
||||||
|
{{- printf "%s-cron" (include "phpfpm.name" .) | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "phpfpm.cron.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "phpfpm.cron.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
{{- range .Values.cron.jobs }}
|
||||||
|
---
|
||||||
|
# CronJobのPodは、nginx/php-fpmのDeploymentとは別のReplicaSetに属するため、
|
||||||
|
# jobTemplate.spec.template.metadata.labels には phpfpm.cron.selectorLabels
|
||||||
|
# (app.kubernetes.io/name: <chart>-cron)を使う。ここで通常の
|
||||||
|
# phpfpm.selectorLabels(name: phpfpm)を使ってしまうと、nginx/php-fpm
|
||||||
|
# DeploymentのmatchLabelsと一致するPodが増え、ReplicaSetコントローラーが
|
||||||
|
# replicaCountとの差分調整でCronJob由来のPodを意図せず削除する事故につながる
|
||||||
|
# (Selenium分離(v8.5.10-b)と同じ理由)。
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: {{ printf "%s-cron-%s" (include "phpfpm.fullname" $) .name | trunc 52 | trimSuffix "-" }}
|
||||||
|
labels:
|
||||||
|
{{- include "phpfpm.labels" $ | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: cron
|
||||||
|
spec:
|
||||||
|
schedule: {{ .schedule | quote }}
|
||||||
|
{{- if .timeZone }}
|
||||||
|
timeZone: {{ .timeZone | quote }}
|
||||||
|
{{- end }}
|
||||||
|
concurrencyPolicy: {{ .concurrencyPolicy | default "Forbid" }}
|
||||||
|
{{- if hasKey . "suspend" }}
|
||||||
|
suspend: {{ .suspend }}
|
||||||
|
{{- end }}
|
||||||
|
successfulJobsHistoryLimit: {{ .successfulJobsHistoryLimit | default 3 }}
|
||||||
|
failedJobsHistoryLimit: {{ .failedJobsHistoryLimit | default 1 }}
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
{{- if .activeDeadlineSeconds }}
|
||||||
|
activeDeadlineSeconds: {{ .activeDeadlineSeconds }}
|
||||||
|
{{- end }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{- include "phpfpm.cron.selectorLabels" $ | nindent 12 }}
|
||||||
|
app.kubernetes.io/component: cron
|
||||||
|
spec:
|
||||||
|
restartPolicy: {{ .restartPolicy | default "OnFailure" }}
|
||||||
|
containers:
|
||||||
|
- name: cron
|
||||||
|
image: "{{ $.Values.image.php.registry }}/{{ $.Values.image.php.repository }}:{{ $.Values.image.php.tag }}"
|
||||||
|
imagePullPolicy: {{ $.Values.image.php.pullPolicy }}
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
echo "Starting cron job: {{ .name }}"
|
||||||
|
|
||||||
|
{{- if $.Values.smtp.enabled }}
|
||||||
|
# ========================================
|
||||||
|
# SMTP設定(msmtp) — templates/deployment.yaml のSMTP設定と同じ内容。
|
||||||
|
# 変更する場合は両方のファイルを揃えること。
|
||||||
|
# ========================================
|
||||||
|
echo "Installing msmtp for mail sending..."
|
||||||
|
apk add --no-cache msmtp ca-certificates
|
||||||
|
|
||||||
|
cp /etc/smtp-config/msmtprc /etc/msmtprc
|
||||||
|
chmod 644 /etc/msmtprc
|
||||||
|
|
||||||
|
cat > /usr/local/etc/php/conf.d/99-smtp.ini << 'PHP_SMTP_EOF'
|
||||||
|
sendmail_path = "/usr/bin/msmtp -t"
|
||||||
|
sendmail_from = "{{ $.Values.smtp.from }}"
|
||||||
|
PHP_SMTP_EOF
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
echo "Running: {{ .command }}"
|
||||||
|
{{ .command }}
|
||||||
|
{{- with (.resources | default $.Values.resources.phpfpm) }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml . | nindent 16 }}
|
||||||
|
{{- end }}
|
||||||
|
volumeMounts:
|
||||||
|
# php-fpmコンテナと同様、PVCルートを/var/wwwにマウントする。
|
||||||
|
# html/ は公開コード、それ以外は非公開ファイルの置き場として利用できる。
|
||||||
|
- name: app-storage
|
||||||
|
mountPath: /var/www
|
||||||
|
{{- if $.Values.smtp.enabled }}
|
||||||
|
- name: smtp-config
|
||||||
|
mountPath: /etc/smtp-config
|
||||||
|
readOnly: true
|
||||||
|
{{- if and $.Values.smtp.auth.enabled (not $.Values.smtp.existingMsmtprcSecret) }}
|
||||||
|
- name: smtp-secrets
|
||||||
|
mountPath: /etc/smtp-secrets
|
||||||
|
readOnly: true
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
env:
|
||||||
|
{{- if $.Values.externalDatabase.enabled }}
|
||||||
|
- name: DB_HOST
|
||||||
|
value: {{ $.Values.externalDatabase.host | quote }}
|
||||||
|
- name: DB_PORT
|
||||||
|
value: {{ $.Values.externalDatabase.port | quote }}
|
||||||
|
- name: DB_NAME
|
||||||
|
value: {{ $.Values.externalDatabase.database | quote }}
|
||||||
|
- name: DB_USER
|
||||||
|
value: {{ $.Values.externalDatabase.username | quote }}
|
||||||
|
- name: DB_PASS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "phpfpm.fullname" $ }}-db-secret
|
||||||
|
key: {{ include "phpfpm.fullname" $ }}-db-key
|
||||||
|
{{- end }}
|
||||||
|
{{- range $key, $value := $.Values.phpEnv }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if $.Values.selenium.enabled }}
|
||||||
|
- name: SELENIUM_URL
|
||||||
|
value: "http://{{ include "phpfpm.fullname" $ }}-selenium:4444/wd/hub"
|
||||||
|
{{- end }}
|
||||||
|
{{- with $.Values.extraEnv }}
|
||||||
|
{{- toYaml . | nindent 16 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with $.Values.extraEnvFrom }}
|
||||||
|
envFrom:
|
||||||
|
{{- toYaml . | nindent 16 }}
|
||||||
|
{{- end }}
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
dnsConfig:
|
||||||
|
options:
|
||||||
|
- name: ndots
|
||||||
|
value: "1"
|
||||||
|
volumes:
|
||||||
|
- name: app-storage
|
||||||
|
{{- if $.Values.persistence.enabled }}
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: {{ include "phpfpm.fullname" $ }}-pvc
|
||||||
|
{{- else }}
|
||||||
|
emptyDir: {}
|
||||||
|
{{- end }}
|
||||||
|
{{- if $.Values.smtp.enabled }}
|
||||||
|
- name: smtp-config
|
||||||
|
{{- if $.Values.smtp.existingMsmtprcSecret }}
|
||||||
|
secret:
|
||||||
|
secretName: {{ $.Values.smtp.existingMsmtprcSecret }}
|
||||||
|
items:
|
||||||
|
- key: {{ $.Values.smtp.existingMsmtprcSecretKey | default "msmtprc" }}
|
||||||
|
path: msmtprc
|
||||||
|
{{- else }}
|
||||||
|
configMap:
|
||||||
|
name: {{ include "phpfpm.fullname" $ }}-smtp-config
|
||||||
|
items:
|
||||||
|
- key: msmtprc
|
||||||
|
path: msmtprc
|
||||||
|
{{- end }}
|
||||||
|
{{- if and $.Values.smtp.auth.enabled (not $.Values.smtp.existingMsmtprcSecret) }}
|
||||||
|
- name: smtp-secrets
|
||||||
|
secret:
|
||||||
|
secretName: {{ $.Values.smtp.auth.existingSecret | default (printf "%s-smtp" (include "phpfpm.fullname" $)) }}
|
||||||
|
items:
|
||||||
|
- key: {{ $.Values.smtp.auth.existingSecretKey | default "password" }}
|
||||||
|
path: password
|
||||||
|
mode: 0644
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
+35
@@ -204,6 +204,41 @@ selenium:
|
|||||||
# では不要なため、既定はfalse。
|
# では不要なため、既定はfalse。
|
||||||
mountHtml: false
|
mountHtml: false
|
||||||
|
|
||||||
|
# 定期実行タスク(Kubernetes CronJob)
|
||||||
|
# php-fpmと同じPHPイメージ(image.php)を使い、指定したスケジュールで
|
||||||
|
# 1回限りのコマンドを実行するCronJobを作成する。複数ジョブを配列で定義できる。
|
||||||
|
# jobsが空の場合、CronJobは1つも作成されない。
|
||||||
|
#
|
||||||
|
# 【マウント/環境変数】/var/wwwにPVCルートをマウントし、externalDatabase/phpEnv/
|
||||||
|
# extraEnv/extraEnvFrom/SELENIUM_URLはphp-fpmコンテナと同じ内容が渡される。
|
||||||
|
# html/ 配下の公開コード、または /var/www/<非公開フォルダ> 配下の
|
||||||
|
# 非公開スクリプト・出力先のどちらも利用できる。
|
||||||
|
#
|
||||||
|
# 【Composer/Pythonとの併用について】
|
||||||
|
# composer.workingDir / python.venvDir が既定の /composer, /venv
|
||||||
|
# (PVC非マウントの使い捨て領域)のままの場合、CronJobのPodには存在しない
|
||||||
|
# (php-fpmの長時間稼働Pod内だけに存在する)ため利用できない。
|
||||||
|
# CronJobからComposer/Pythonの成果物を使いたい場合は、
|
||||||
|
# composer.workingDir: "/var/www/composer" のように/var/www配下へ変更し、
|
||||||
|
# PVC上に永続化すること(本体Deployment側で一度セットアップされていれば、
|
||||||
|
# CronJob側は改めてインストールし直す必要はない)。
|
||||||
|
#
|
||||||
|
# 【SMTPとの併用】smtp.enabled: true の場合、CronJobのPodでもmsmtpの導入・
|
||||||
|
# msmtprc配置・sendmail_path設定を自動で行うため、PHPのmail()関数がそのまま使える。
|
||||||
|
cron:
|
||||||
|
jobs: []
|
||||||
|
# - name: daily-report # 必須。CronJob名の一部に使用(英数字とハイフンのみ、小文字推奨)
|
||||||
|
# schedule: "0 18 * * *" # 必須。標準cron形式(timeZone省略時はUTC基準)
|
||||||
|
# command: "php /var/www/html/cron/daily-report.php"
|
||||||
|
# timeZone: "Asia/Tokyo" # 省略時はUTC(Kubernetes 1.27+で安定サポート)
|
||||||
|
# concurrencyPolicy: "Forbid" # Allow / Forbid / Replace(既定: Forbid。前回実行の長期化による多重起動を防止)
|
||||||
|
# restartPolicy: "OnFailure" # OnFailure / Never(既定: OnFailure)
|
||||||
|
# successfulJobsHistoryLimit: 3
|
||||||
|
# failedJobsHistoryLimit: 1
|
||||||
|
# activeDeadlineSeconds: 3600 # 実行タイムアウト(秒)。省略可
|
||||||
|
# suspend: false # trueにするとコード変更なしでこのジョブだけ一時停止できる
|
||||||
|
# resources: {} # 未指定時は resources.phpfpm を流用
|
||||||
|
|
||||||
externalDatabase:
|
externalDatabase:
|
||||||
enabled: false
|
enabled: false
|
||||||
host: mariadb-hostname
|
host: mariadb-hostname
|
||||||
|
|||||||
Reference in New Issue
Block a user