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 検証済み
This commit is contained in:
+338
@@ -0,0 +1,338 @@
|
||||
# ==========================================================================
|
||||
# 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
|
||||
Reference in New Issue
Block a user