414 lines
18 KiB
YAML
414 lines
18 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.31.6-alpine"
|
||
pullPolicy: IfNotPresent
|
||
# 制御プレーン(Python 標準ライブラリのみ・追加 pip 不要)
|
||
manager:
|
||
registry: docker.io
|
||
repository: library/python
|
||
tag: "3.14-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.283"
|
||
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:
|
||
# authMode:
|
||
# credentials : ~/.claude/.credentials.json 全体(refreshToken 込み)を注入(推奨)。
|
||
# 各セッションはこのファイルを $HOME/.claude/.credentials.json に配置し、
|
||
# claude が自身でアクセストークンをリフレッシュする。加えて下記
|
||
# refresher CronJob がクラスタ内で Secret を最新に保つ。
|
||
# → API 課金なし。トークンが定期的に変わっても再デプロイ不要。
|
||
# oauth : CLAUDE_CODE_OAUTH_TOKEN を注入(`claude setup-token` の単発トークン。
|
||
# refreshToken を含まないため自動更新されない)。
|
||
# apiKey : ANTHROPIC_API_KEY を注入(API 従量課金)。
|
||
authMode: credentials
|
||
apiKey: ""
|
||
oauthToken: ""
|
||
# credentials モード: claude ログイン済みマシンの ~/.claude/.credentials.json の中身。
|
||
# 例: {"claudeAiOauth":{"accessToken":"...","refreshToken":"...","expiresAt":...,
|
||
# "scopes":["user:inference","user:profile"],"subscriptionType":"max"}}
|
||
# 注入は平文で書かず: --set-file anthropic.credentialsJson=$HOME/.claude/.credentials.json
|
||
credentialsJson: ""
|
||
# 上記の代わりに既存 Secret を参照
|
||
existingSecret: ""
|
||
existingSecretKeyApiKey: "ANTHROPIC_API_KEY"
|
||
existingSecretKeyOauthToken: "CLAUDE_CODE_OAUTH_TOKEN"
|
||
existingSecretKeyCredentials: ".credentials.json"
|
||
# 全セッションへ渡す追加環境変数(例: ANTHROPIC_BASE_URL / ANTHROPIC_MODEL)
|
||
extraEnv: {}
|
||
|
||
# ---- refresher: credentials モードのトークン自動更新 CronJob ----
|
||
# Secret 内の refreshToken を使って新しい accessToken を取得し、Secret を書き戻す。
|
||
# これで自マシンがオフラインでも新規セッションは常に有効なトークンで起動できる。
|
||
# ⚠ Claude Code CLI の OAuth クライアント値(tokenUrl / clientId)に依存する。
|
||
# これらは非公式であり、仕様変更で動かなくなる可能性がある。その場合でも
|
||
# セッション内 claude の自己リフレッシュは独立して機能する。
|
||
refresher:
|
||
enabled: true
|
||
schedule: "*/30 * * * *" # 30 分ごと
|
||
# 期限まで残りこの秒数を切っていたら更新する(十分な余裕を持たせる)
|
||
refreshIfExpiresInSeconds: 3600
|
||
tokenUrl: "https://console.anthropic.com/v1/oauth/token"
|
||
clientId: "9d1c250a-e61b-44d9-88ed-5944d1962f5e"
|
||
resources:
|
||
requests:
|
||
cpu: 10m
|
||
memory: 32Mi
|
||
limits:
|
||
cpu: 200m
|
||
memory: 96Mi
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 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"
|
||
|
||
# GUI(Web UI)からの認証情報 identity 登録を許可する。
|
||
# 有効にすると、UI の「認証情報」カードから SSH 秘密鍵 + known_hosts / HTTPS トークンを
|
||
# 登録・削除できる。登録内容はセッション NS の Secret として保存される。
|
||
# トレードオフ:
|
||
# - manager にセッション NS の secrets への get/list/create/update/delete 権限が付く
|
||
# (同 NS には Claude 認証情報 Secret も存在する点に留意)。
|
||
# - 秘密鍵はブラウザ→gateway→manager をリクエストボディで通る。経路の TLS
|
||
# (Ingress の tls / LB の TLS 終端)を必ず有効にすること。
|
||
# 下の git.identities(Helm 管理)は常に読み取り専用で UI に表示される。
|
||
guiIdentities:
|
||
enabled: true
|
||
|
||
# 認証アイデンティティ(Helm 管理)。セッション作成時に名前で選択する。
|
||
# GitHub / Gitea / GitLab など SSH または HTTPS トークンで認証する任意のホストに対応。
|
||
# GUI から登録したものと合わせて使える(同名は不可)。
|
||
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
|
||
# 終了済み(Succeeded / Failed)セッション Pod を回収せず残す秒数。
|
||
# 死因を UI の「ログ」ボタンや kubectl logs で確認できるよう猶予を持たせる。
|
||
# 0 にすると即回収(旧挙動)。
|
||
terminatedRetentionSeconds: 900
|
||
# 予備の孤児掃除 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:
|
||
# LoadBalancer : ローカルネットワークの LB(kube-vip / MetalLB / Cilium LB-IPAM 等)から
|
||
# IP を払い出し、その IP で管理画面へアクセスする(Ingress 不要・既定)
|
||
# ClusterIP : Service IP のみ。port-forward か Ingress 経由でアクセス
|
||
# NodePort : 各ノードの高位ポートで公開
|
||
type: LoadBalancer
|
||
port: 80
|
||
# NodePort を固定したい場合のみ(type: NodePort)
|
||
nodePort: null
|
||
# Service に付与するアノテーション。kube-vip で VIP を指定する例:
|
||
# kube-vip.io/loadbalancerIPs: "192.168.9.50"
|
||
# kube-vip.io/vipHost: "cpi11"
|
||
# MetalLB でプールを指定する例:
|
||
# metallb.universe.tf/address-pool: "lan"
|
||
annotations: {}
|
||
# 払い出す IP を直接指定(LB 実装が対応していれば)。annotations 指定を推奨。
|
||
loadBalancerIP: ""
|
||
loadBalancerClass: ""
|
||
# 接続元をローカルネットワークに限定する(LB 実装が対応していれば)。
|
||
# Ingress を張らない構成では、ここで許可レンジを絞ることが第一の防御線になる。
|
||
loadBalancerSourceRanges: []
|
||
# - 192.168.9.0/24
|
||
# - 10.0.0.0/8
|
||
# Local にすると実クライアント IP を保持する(kube-proxy/LB 実装依存)
|
||
externalTrafficPolicy: ""
|
||
# Service 自体への追加ラベル
|
||
labels: {}
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 制御プレーンの 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
|