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 検証済み
339 lines
13 KiB
YAML
339 lines
13 KiB
YAML
# ==========================================================================
|
||
# claude-code — Claude Code リモート実行 Helm チャート
|
||
# --------------------------------------------------------------------------
|
||
# 構成:
|
||
# gateway ... 受付 nginx。ブラウザ ↔ セッションの単一入口。認証・WebSocket
|
||
# プロキシ・アクティビティ計測を担う。
|
||
# manager ... 制御プレーン(Python 標準ライブラリのみ)。セッションの
|
||
# 作成/一覧/破棄 API、Web UI、アイドル回収ループ。
|
||
# session ... セッションごとに作られる使い捨て Pod。Alpine ベースで
|
||
# git clone → 編集 → 検証 → push を行い、claude を ttyd 経由で
|
||
# ブラウザに提供する。アイドルで自動破棄。
|
||
#
|
||
# セキュリティ上の注意(必読):
|
||
# - この values.yaml に平文の API キー / SSH 秘密鍵 / トークンを書かない。
|
||
# Git にコミットしない。実値は CI の --set / --set-file か existingSecret で注入する。
|
||
# - セッション Pod は API サーバーへアクセスできない(SA トークン非マウント)。
|
||
# - セッション Pod の egress は Git ホストと api.anthropic.com のみに制限される
|
||
# (networkPolicy.enabled: true のとき)。
|
||
# - 詳細は README.md「セキュリティモデル」を参照。
|
||
# ==========================================================================
|
||
|
||
nameOverride: ""
|
||
fullnameOverride: ""
|
||
|
||
# --------------------------------------------------------------------------
|
||
# image: すべて Alpine ベース / linux/arm64 対応イメージ
|
||
# --------------------------------------------------------------------------
|
||
image:
|
||
# 受付 nginx(非 root 版)
|
||
gateway:
|
||
registry: docker.io
|
||
repository: nginxinc/nginx-unprivileged
|
||
tag: "1.29.1-alpine"
|
||
pullPolicy: IfNotPresent
|
||
# 制御プレーン(Python 標準ライブラリのみ・追加 pip 不要)
|
||
manager:
|
||
registry: docker.io
|
||
repository: library/python
|
||
tag: "3.13-alpine"
|
||
pullPolicy: IfNotPresent
|
||
# セッションの使い捨てコンテナ。
|
||
# 既定は CI(session-image.yaml)がビルドする事前ビルドイメージ
|
||
# (git + openssh + ttyd + node + @anthropic-ai/claude-code 同梱、非 root 実行)。
|
||
# restricted PodSecurity / readOnlyRootFilesystem 下で確実に動くのはこの方式。
|
||
#
|
||
# 事前ビルドを使わず素の node:alpine 等を指定することも可能だが、その場合
|
||
# ブート時に $HOME へ claude を npm インストールし、ttyd が同梱されていないと
|
||
# 起動に失敗する(apk は非 root では不可)。フォールバック例:
|
||
# registry: docker.io / repository: library/node / tag: "22-alpine"
|
||
session:
|
||
registry: git.cafepieters.com
|
||
repository: helmchart/claude-code/session
|
||
tag: "2.1.259"
|
||
pullPolicy: IfNotPresent
|
||
|
||
imagePullSecrets: []
|
||
|
||
# --------------------------------------------------------------------------
|
||
# gateway: 受付・ルーティング
|
||
# --------------------------------------------------------------------------
|
||
gateway:
|
||
replicaCount: 1
|
||
# gateway コンテナの待受ポート(Service / Ingress のバックエンド)
|
||
port: 8080
|
||
resources:
|
||
requests:
|
||
cpu: 25m
|
||
memory: 32Mi
|
||
limits:
|
||
cpu: 250m
|
||
memory: 128Mi
|
||
|
||
# --------------------------------------------------------------------------
|
||
# manager: 制御プレーン
|
||
# --------------------------------------------------------------------------
|
||
manager:
|
||
# debug | info | warning | error
|
||
logLevel: info
|
||
resources:
|
||
requests:
|
||
cpu: 50m
|
||
memory: 64Mi
|
||
limits:
|
||
cpu: 500m
|
||
memory: 256Mi
|
||
|
||
# --------------------------------------------------------------------------
|
||
# sessionsNamespace: セッション Pod を隔離するネームスペース
|
||
# --------------------------------------------------------------------------
|
||
sessionsNamespace:
|
||
# 空 = リリース先ネームスペースを使う。セキュリティ上、専用ネームスペースを推奨。
|
||
name: "claude-code-sessions"
|
||
# true ならこのチャートがネームスペースを作成し PodSecurity ラベルを付与する。
|
||
# 既存ネームスペースを使う場合は false にし、下記ラベルを手動で付与すること。
|
||
create: true
|
||
# PodSecurity admission レベル(restricted 準拠のセッション Pod を強制)
|
||
podSecurityLevel: restricted
|
||
|
||
# セッション NS 全体の使用量上限(暴走・過剰生成のブラスト半径を限定)
|
||
resourceQuota:
|
||
enabled: true
|
||
# 省略値は session.maxSessions と session.resources から算出される。
|
||
# 明示指定するとそのまま ResourceQuota.spec.hard になる。
|
||
hard: {}
|
||
# requests.cpu: "4"
|
||
# requests.memory: 8Gi
|
||
# limits.cpu: "16"
|
||
# limits.memory: 32Gi
|
||
|
||
# セッション NS のコンテナ既定値 / 上限
|
||
limitRange:
|
||
enabled: true
|
||
max:
|
||
cpu: "4"
|
||
memory: 4Gi
|
||
default:
|
||
cpu: "1"
|
||
memory: 1Gi
|
||
defaultRequest:
|
||
cpu: 100m
|
||
memory: 256Mi
|
||
|
||
# --------------------------------------------------------------------------
|
||
# auth: ブラウザからのアクセス認証
|
||
# --------------------------------------------------------------------------
|
||
auth:
|
||
# token : Bearer トークン / Cookie / ?token= で検証(既定)
|
||
# basic : HTTP Basic 認証(htpasswd)
|
||
# forward : 外部認証プロキシ(oauth2-proxy 等)へ auth_request を委譲
|
||
# none : 認証なし(信頼済みネットワーク限定・非推奨)
|
||
mode: token
|
||
|
||
token:
|
||
# 空なら install 時に自動生成される(helm get manifest で参照可能なため、
|
||
# 運用では existingSecret を使うのが望ましい)。
|
||
value: ""
|
||
existingSecret: ""
|
||
existingSecretKey: "token"
|
||
|
||
basic:
|
||
# `htpasswd -nbB user pass` の出力を1行以上。existingSecret 優先。
|
||
users: []
|
||
existingSecret: ""
|
||
existingSecretKey: "htpasswd"
|
||
|
||
forward:
|
||
# nginx auth_request の転送先(例: http://oauth2-proxy.auth.svc.cluster.local:4180/oauth2/auth)
|
||
url: ""
|
||
# 未認証時のリダイレクト先(任意)
|
||
signInUrl: ""
|
||
|
||
# --------------------------------------------------------------------------
|
||
# anthropic: Claude Code の認証情報
|
||
# --------------------------------------------------------------------------
|
||
anthropic:
|
||
# apiKey : ANTHROPIC_API_KEY を使う
|
||
# oauth : CLAUDE_CODE_OAUTH_TOKEN を使う(`claude setup-token` で発行)
|
||
authMode: apiKey
|
||
apiKey: ""
|
||
oauthToken: ""
|
||
# 上記の代わりに既存 Secret を参照
|
||
existingSecret: ""
|
||
existingSecretKeyApiKey: "ANTHROPIC_API_KEY"
|
||
existingSecretKeyOauthToken: "CLAUDE_CODE_OAUTH_TOKEN"
|
||
# 全セッションへ渡す追加環境変数(例: ANTHROPIC_BASE_URL / ANTHROPIC_MODEL)
|
||
extraEnv: {}
|
||
|
||
# --------------------------------------------------------------------------
|
||
# git: 接続先ホストと認証アイデンティティ
|
||
# --------------------------------------------------------------------------
|
||
git:
|
||
# チェックアウトを許可するホスト allow-list。manager はこれ以外のホストを拒否する。
|
||
allowedHosts:
|
||
- github.com
|
||
- gitlab.com
|
||
- 192.168.9.65
|
||
- git.cafepieters.com
|
||
# allow-list を無効化し任意 URL を許可する(非推奨)
|
||
allowArbitraryRepos: false
|
||
|
||
# コミット時の既定 author(セッション作成時に上書き可)
|
||
defaultAuthorName: "Claude"
|
||
defaultAuthorEmail: "claude@cafepieters.com"
|
||
|
||
# 認証アイデンティティ。セッション作成時に名前で選択する。
|
||
# GitHub / Gitea / GitLab など SSH または HTTPS トークンで認証する任意のホストに対応。
|
||
identities: {}
|
||
# gitea-ssh:
|
||
# type: ssh # ssh | https-token
|
||
# # --- ssh のとき ---
|
||
# sshPrivateKey: "" # PEM 形式。existingSecret 優先
|
||
# knownHosts: "" # `ssh-keyscan <host>` の出力(必須/ホスト鍵TOFUを無効化)
|
||
# # --- 既存 Secret を使う場合 ---
|
||
# existingSecret: ""
|
||
# existingSecretKeyPrivateKey: "id"
|
||
# existingSecretKeyKnownHosts: "known_hosts"
|
||
# github-https:
|
||
# type: https-token
|
||
# username: "x-access-token" # GitHub は任意文字列、Gitea はユーザー名
|
||
# token: "" # PAT。existingSecret 優先
|
||
# existingSecret: ""
|
||
# existingSecretKeyToken: "token"
|
||
|
||
# --------------------------------------------------------------------------
|
||
# session: 使い捨てセッションの挙動とライフサイクル
|
||
# --------------------------------------------------------------------------
|
||
session:
|
||
# ブート完了後に `claude` を自動起動する(false ならログインシェルで待受)
|
||
autoStartClaude: true
|
||
# リポジトリを clone する作業ディレクトリ
|
||
workspaceDir: /workspace
|
||
# ttyd の待受ポート(Pod 内からのみ到達可能)
|
||
ttydPort: 7681
|
||
# ブート時に追加インストールする apk パッケージ(言語ランタイム等)
|
||
extraApkPackages: []
|
||
# インストールする @anthropic-ai/claude-code のバージョン(空 = チャート appVersion)
|
||
claudeCodeVersion: ""
|
||
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 256Mi
|
||
limits:
|
||
cpu: "2"
|
||
memory: 2Gi
|
||
ephemeral-storage: 4Gi
|
||
|
||
# ---- lifecycle: 破棄条件 ----
|
||
# 無通信がこの秒数継続したセッションを破棄する(Pod 内ウォッチドッグ + manager 回収)
|
||
idleTimeoutSeconds: 1800
|
||
# 生成からの最大寿命(Pod の activeDeadlineSeconds)。到達で強制終了。
|
||
maxLifetimeSeconds: 43200
|
||
|
||
reaper:
|
||
# manager 内アイドル回収ループの実行間隔
|
||
intervalSeconds: 60
|
||
# 予備の孤児掃除 CronJob(manager 障害時の保険)
|
||
cronjob:
|
||
enabled: true
|
||
schedule: "*/15 * * * *"
|
||
|
||
# 同時に存在できるセッション数の上限(manager が enforce)
|
||
maxSessions: 10
|
||
|
||
# ---- verify / push ----
|
||
# セッション内の `claude-verify` が実行するコマンド(例: "npm test" / "make check")
|
||
verifyCommand: ""
|
||
autoPush:
|
||
# true でもデフォルトブランチや protectedBranches への push、--force は禁止。
|
||
enabled: false
|
||
branchPrefix: "claude/"
|
||
protectedBranches:
|
||
- main
|
||
- master
|
||
- develop
|
||
- release
|
||
|
||
# セッション Pod への追加メタデータ / スケジューリング
|
||
podLabels: {}
|
||
podAnnotations: {}
|
||
nodeSelector: {}
|
||
tolerations: []
|
||
# セッション Pod の優先度クラス(任意)
|
||
priorityClassName: ""
|
||
|
||
# --------------------------------------------------------------------------
|
||
# networkPolicy: 通信制限(CNI が NetworkPolicy 対応であること)
|
||
# --------------------------------------------------------------------------
|
||
networkPolicy:
|
||
enabled: true
|
||
# DNS 解決を許可する kube-dns の namespace セレクタ
|
||
dnsNamespaceSelector:
|
||
kubernetes.io/metadata.name: kube-system
|
||
# api.anthropic.com / GitHub は IP 固定できないため、既定でセッションの
|
||
# 443/tcp(HTTPS git・Claude API)と 22/tcp(SSH git)の外向きを許可する。
|
||
# 完全に閉じる場合は egress プロキシを用意し false にする。
|
||
allowInternetHttps: true
|
||
allowSshGit: true
|
||
# allowInternetHttps 時に egress から除外する CIDR(SSRF 対策)。
|
||
# クラウドのメタデータ IP は既定で遮断。自クラスターの Pod/Service CIDR を
|
||
# 追加すると、セッションから内部サービスへの到達を防げる。
|
||
blockedEgressCIDRs:
|
||
- 169.254.169.254/32
|
||
# 追加で許可する egress(社内ミラー / プロキシ用)
|
||
sessionEgressExtra: []
|
||
# - cidr: 10.0.0.0/8
|
||
# ports:
|
||
# - protocol: TCP
|
||
# port: 443
|
||
|
||
# --------------------------------------------------------------------------
|
||
# ingress / service
|
||
# --------------------------------------------------------------------------
|
||
ingress:
|
||
enabled: false
|
||
className: ""
|
||
annotations: {}
|
||
# nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||
# nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||
hosts:
|
||
- host: claude-code.example.com
|
||
paths:
|
||
- path: /
|
||
pathType: Prefix
|
||
tls: []
|
||
# - secretName: claude-code-tls
|
||
# hosts:
|
||
# - claude-code.example.com
|
||
|
||
service:
|
||
type: ClusterIP
|
||
port: 80
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 制御プレーンの Pod / コンテナセキュリティ
|
||
# --------------------------------------------------------------------------
|
||
podSecurityContext:
|
||
runAsNonRoot: true
|
||
runAsUser: 65532
|
||
runAsGroup: 65532
|
||
fsGroup: 65532
|
||
seccompProfile:
|
||
type: RuntimeDefault
|
||
|
||
containerSecurityContext:
|
||
allowPrivilegeEscalation: false
|
||
readOnlyRootFilesystem: true
|
||
capabilities:
|
||
drop:
|
||
- ALL
|
||
|
||
# 全リソースへ付与する追加ラベル / アノテーション
|
||
commonLabels: {}
|
||
commonAnnotations: {}
|
||
|
||
podDisruptionBudget:
|
||
enabled: false
|
||
minAvailable: 1
|