Files
claude-code/templates/cronjob-reaper.yaml
T
claude 1bd0fec23a
Helm Chart Release / release-chart (push) Successful in 12s
Build Session Image / build-push (push) Successful in 2m15s
feat: Alpine ベースの Claude Code リモート実行 Helm チャート初版 (v2.1.259)
gateway(nginx) + manager(python 標準ライブラリ) + セッションごとの使い捨て Pod +
reaper CronJob の構成。ブラウザ(PC/スマホ)からアクセスし、セッション単位で
独立した Alpine コンテナに Git リポジトリ(GitHub/Gitea など)をチェックアウトして
編集・検証・プッシュする。無操作が続いたセッションは Pod ごと自動破棄。

- セキュリティ: セッション NS 分離 / restricted PodSecurity / RBAC はセッション NS の
  pods,services のみの Role / セッション Pod は SA トークン非マウント・非 root・
  readOnlyRootFilesystem・drop ALL caps・seccomp / NetworkPolicy で egress を
  DNS+HTTPS+SSH に限定 / Git ホスト allow-list / ResourceQuota+LimitRange
- ライフサイクル: idleTimeout(Pod 内ウォッチドッグ + manager 回収) / maxLifetime
  (activeDeadlineSeconds) / maxSessions / 予備の孤児掃除 CronJob
- 認証: token(既定) / basic / forward(外部SSO) / none。WebSocket は Cookie トークン
- Claude 認証: ANTHROPIC_API_KEY または CLAUDE_CODE_OAUTH_TOKEN
- CI: helm-release.yaml(未リリース版のみ tag+release+publish) /
  image-update-and-release.yaml(週次 npm 追従) / session-image.yaml(multi-arch build)
- files/ 実体を .Files.Get で ConfigMap 化。helm lint / template 検証済み
2026-09-03 08:10:12 +09:00

72 lines
2.8 KiB
YAML

{{- if .Values.session.reaper.cronjob.enabled }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{ include "claude-code.fullname" . }}-reaper
namespace: {{ .Release.Namespace }}
labels:
{{- include "claude-code.labels" . | nindent 4 }}
app.kubernetes.io/component: reaper
spec:
schedule: {{ .Values.session.reaper.cronjob.schedule | quote }}
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
startingDeadlineSeconds: 120
jobTemplate:
spec:
activeDeadlineSeconds: 300
backoffLimit: 1
template:
metadata:
labels:
{{- include "claude-code.selectorLabels" . | nindent 12 }}
app.kubernetes.io/component: reaper
spec:
restartPolicy: Never
serviceAccountName: {{ include "claude-code.managerServiceAccountName" . }}
automountServiceAccountToken: true
securityContext:
{{- include "claude-code.podSecurityContext" . | nindent 12 }}
containers:
- name: reaper
image: "{{ .Values.image.manager.registry }}/{{ .Values.image.manager.repository }}:{{ .Values.image.manager.tag }}"
imagePullPolicy: {{ .Values.image.manager.pullPolicy }}
command: ["python3", "-u", "/app/manager.py", "--reap-once"]
env:
- name: PYTHONDONTWRITEBYTECODE
value: "1"
- name: LOG_LEVEL
value: {{ .Values.manager.logLevel | quote }}
- name: SESSIONS_NAMESPACE
value: {{ include "claude-code.sessionsNamespace" . | quote }}
- name: FULLNAME
value: {{ include "claude-code.fullname" . | quote }}
- name: IDLE_TIMEOUT_SECONDS
value: {{ .Values.session.idleTimeoutSeconds | quote }}
- name: MAX_LIFETIME_SECONDS
value: {{ .Values.session.maxLifetimeSeconds | quote }}
- name: TTYD_PORT
value: {{ .Values.session.ttydPort | quote }}
securityContext:
{{- include "claude-code.containerSecurityContext" . | nindent 16 }}
resources:
requests: { cpu: 20m, memory: 32Mi }
limits: { cpu: 200m, memory: 128Mi }
volumeMounts:
- name: manager-app
mountPath: /app
readOnly: true
- name: tmp
mountPath: /tmp
volumes:
- name: manager-app
configMap:
name: {{ include "claude-code.fullname" . }}-manager
defaultMode: 0555
- name: tmp
emptyDir:
medium: Memory
sizeLimit: 8Mi
{{- end }}