feat: 定期実行(CronJob)機能を追加
Helm Chart Release / release-chart (push) Successful in 5s

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:
2026-09-27 16:26:18 +09:00
parent c7397b3c9d
commit 6cd35ce023
6 changed files with 260 additions and 1 deletions
+20
View File
@@ -41,3 +41,23 @@ name を variant にすることで、この重複を構造的に防止する。
app.kubernetes.io/name: {{ include "phpfpm.selenium.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- 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 }}
+157
View File
@@ -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 }}