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 検証済み
72 lines
2.8 KiB
YAML
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 }}
|