サンドボックスとクエリ¶
サンドボックスは、バックアップまたはウィンドウ内の任意の 1 秒から復元された、専用の使い捨てデータベースです。 見るだけなら本番環境を危険にさらすことがないため、これがデフォルトの復元先です。
tenax restore team-a/app --at 2026-10-07T09:41:27Z --ttl 6h --wait
tenax sandbox list
tenax sandbox show <sandbox>
サンドボックスとは¶
- ターゲットと同じエンジンとバージョン (ターゲットの
spec.sandbox.image) のデータベース Pod です。Tenax のサンドボックス用 Namespace に置かれ、生成された認証情報とデフォルト拒否の NetworkPolicy を持ちます。 - TTL があります (
sandbox.defaultTTL、最大sandbox.maxTTL。どちらもポリシーごととチャート全体で設定可能)。期限が切れると Tenax はサンドボックスとそのストレージを削除します。tenax sandbox extend <sandbox> --by 24hで時間を延ばし、tenax sandbox delete <sandbox>で早めに終了できます。 - 作成を依頼した人が所有者になり、それに対するすべての操作は監査されます。
クエリ¶
コンソールの クエリ ページと tenax query は、Tenax のクエリプロキシを通して SQL を実行します。デフォルトでは読み取り専用です。
tenax query <sandbox> -e "select count(*) from orders where created_at > now() - interval '1 day'"
tenax query <sandbox> -e "select * from coupons" -o csv > coupons.csv
各クエリには 30 秒の制限があり、返すのは最大 1,000 行です。--write で書き込みを許可できます (サンドボックスのみ)。
エディターでは Ctrl+Enter (Mac では Cmd+Enter) でクエリを実行します。選択範囲がある場合は選択したテキストだけを実行します。
補完はキーワード、関数、テーブル、列を候補に出します。2 文字入力すると開き、alias. の後ではそのテーブルの列を、
schema. の後ではそのスキーマのテーブルを一覧し、Ctrl+Space でどこでも開けます。Tab または Enter で候補を選び、
Esc で閉じます。それ以外のときは Tab でインデントします。
コンソールは各エンジンの SQL (現在は PostgreSQL と MySQL) を扱います。結果の値はデータベースが表示するとおりに表示されます。
サイズ設定¶
各サンドボックスは専用の Namespace にあるデータベース Pod です。割り当てられるリソースは、次のうち最初に設定されている場所から決まります。
- 復元: Restore ページの CPU、メモリ、ディスク、ストレージクラス フィールド (グレーの値は空欄のままにした場合に
割り当てられる値です)、
tenax restore … --cpu 2 --memory 8Gi --size 50Gi --storage-class local-path、または Restore のspec.destination.sandbox。 - ターゲット: BackupTarget の
spec.sandbox.cpu、memory、sizeLimit、storageClass。 - インストール: チャートの
sandbox.resources。 - 組み込みの値: CPU 100m、メモリ 256Mi のリクエストと 1Gi のリミット、そしてノード上のディスク (
emptyDir、サンドボックスと ともに削除) としてバックアップのデータの 2 倍に 512Mi を足したサイズ (最小 1Gi)。
| 設定 | 意味 |
|---|---|
| CPU | CPU リクエスト。CPU リミットはないため、復元はアイドル状態のコアを使えます |
| Memory | メモリのリクエストとリミット |
| Disk | データボリュームのサイズ。ストレージクラスを設定しない限りノードのディスク上 |
| Storage class | データはこのクラスの PVC に置かれます。ノードのディスクに収まらない大きな復元向け |
チャートの sandbox.limits は CPU、メモリ、ディスクの上限を設定します。コンソールと API は上限を超えるリクエストを拒否し、
サイズが上限を超える復元 (ターゲットの設定、または大きなバックアップの自動サイズ) は、途中でディスクを埋めるのではなく理由を
示して失敗します。実行中のサンドボックスのサイズは変わりません。変更するには再度復元してください。
クラスター内から接続する¶
サンドボックスのホスト、ポート、認証情報は、そのページ (認証情報を表示、監査対象) と tenax sandbox show で確認できます。
他の Namespace の Pod には tenax.run/sandbox-client: <sandbox> ラベルが必要です。サンドボックスの
ネットワークポリシーはそれ以外をすべて拒否します。
クラスター外から接続する¶
ノート PC からサンドボックスにどう到達するかは、インストール時の選択です (expose.provider、後述)。どの場合も次のとおりです。
- サンドボックスのページの 外部アクセスを開く、
tenax sandbox expose <sandbox>、または復元時の open external access (tenax restore … --expose) で外部アクセスを 開きます。operatorロールが必要です。 tenax sandbox connect <sandbox>で 接続します。任意のデータベースクライアント用の接続文字列が表示されます。 サンドボックスのページからコピーすることもできます。- 外部アクセスを閉じる または
tenax sandbox unexpose <sandbox>で 閉じます。サンドボックスの期限切れや削除でも閉じられます。
expose.provider |
tenax sandbox connect の動作 |
クライアントに必要なもの |
|---|---|---|
none (デフォルト) |
kubeconfig を通してローカルポートをサンドボックスに転送します (Ctrl+C まで) | tenax-sbx-<sandbox> で port-forward が許可された kubeconfig |
service |
サンドボックス自身のアドレスを表示します (postgres://…@sbx-7f3a.db.example.com:5432/app?sslmode=require) |
不要: 任意のデータベースクライアントで TLS 接続 |
cloudflare |
Access ログイン後、ローカルポートで cloudflared access tcp を開きます (Ctrl+C まで) |
cloudflared と許可されたメールアドレス |
Postgres のサンドボックスは独自の証明書で TLS を提供します (自己署名: クライアントは sslmode=require を使い、発行者を
確認せずに暗号化します)。MySQL のサンドボックスは MySQL が生成する証明書を使います。
クラスター外からサンドボックスに到達させる (管理者向け)¶
Tenax は自分では何も開きません。どの方式も、クラスターにすでにあるものを使います。
方式 service: サンドボックスごとの Kubernetes Service¶
公開された各サンドボックスには expose.service から作られる Service が付きます。クラスターで Service を処理しているものが
アドレスを割り当て、Tenax はそのアドレスを表示します。開発者にとって最も簡単で (任意のデータベースクライアント)、どの
Kubernetes でも動きます。
| クラスターにあるもの | 設定 | 開発者の接続先 |
|---|---|---|
| クラウドのロードバランサー (AKS、EKS、GKE) | type: LoadBalancer、sourceRanges: [<office or VPN CIDRs>] |
ロードバランサーの IP |
| 上記に加えて external-dns | さらに annotations: {external-dns.alpha.kubernetes.io/hostname: "sbx-{id}.db.example.com"} と hostnamePattern: "sbx-{id}.db.example.com" |
sbx-<id>.db.example.com |
| MetalLB (オンプレミス) | type: LoadBalancer |
ネットワーク上のアドレス |
| Tailscale オペレーター | loadBalancerClass: tailscale |
サンドボックスの tailnet 名。何も公開されません |
| 上記のいずれもない | type: NodePort、ノードに対応する名前を付けた hostnamePattern: "nodes.example.com" |
nodes.example.com:<node port> |
expose:
provider: service
service:
type: LoadBalancer
sourceRanges: ["203.0.113.0/24"] # who may connect; leave empty only on a private network
サンドボックスには本番データのコピーが入っています
パブリックなロードバランサーでは、サンドボックスを守るのはランダムなパスワード、TLS、時間制限だけです。
sourceRanges を開発者の接続元アドレスに設定するか、プライベートな方式 (Tailscale、クラウドのアノテーションによる
内部ロードバランサー、プライベートネットワーク上の MetalLB) を使ってください。
サンドボックスが公開されている間は、追加の NetworkPolicy がデータベースポートで expose.service.allowFrom を許可します
(デフォルト: すべて。ロードバランサーのトラフィックはノードのアドレスから届くことが多いため、フィルタリングはロードバランサーの
sourceRanges が担います)。k3s の組み込みロードバランサーでは、公開された各サンドボックスがノード上のデータベースポートを
バインドするため、同時に公開できるのは Postgres と MySQL のサンドボックスそれぞれひとつだけです。
方式 cloudflare: Access ログインの背後のトンネル¶
トンネルには Cloudflare API トークンがひとつ 必要です。これはユーザーではなくインストールに属します。Tenax の Namespace にある Kubernetes Secret で、他の認証情報と同様に一度だけ設定します (GitOps のシークレットツール、たとえば SOPS を使って)。 コンソールはこのトークンを要求も保持も表示もしません。ゾーンの DNS と Access アプリケーションを変更できるトークンだからです。
- Cloudflare で My Profile → API Tokens → Create Token → Custom token を開き、ホスト名が属するゾーンに対して
次の権限を付けます。
- Account: Cloudflare Tunnel: Edit
- Account: Access: Apps and Policies: Edit
- Zone: DNS: Edit
- Zone: Zone: Read
-
保存します。
-
チャートを設定します。
ホスト名はゾーンの 1 階層下にしてください (sbx-{id}.db.example.com ではなく sbx-{id}.example.com)。Cloudflare の
無料証明書がカバーするのは *.example.com だけで、クライアントは HTTPS でホスト名に到達するからです。データベースのポートは
ブラウザーのログインでは保護できないため、開発者は cloudflared を実行します。これは tenax sandbox connect が代わりに行います。
トークンがあれば、Tenax はゾーンからアカウントを見つけ、tenax という名前のトンネル (expose.cloudflare.tunnelName) を
作成または再利用し、トンネルのコネクタートークンを Secret <release>-tunnel-token に書き込みます。cloudflared Pod は
この Secret から起動します。Tenax は 15 分ごとにこの Secret を確認するので、Cloudflare でローテーションされたトークンは
自動的に Secret に反映されます (反映するには cloudflared Pod を再起動します)。allowEmails にはアドレスとドメイン全体
(*@example.com) を、allowGroups には Access グループの ID を指定します。
すでに管理しているトンネルを使う
tenax の代わりに既存のリモート管理トンネルを使うには expose.cloudflare.tunnelID を設定します。コネクタートークンを
自分で用意したい場合は、それを保持する Secret (キー token) を expose.cloudflared.tunnelTokenSecret に設定します。
その場合 Tenax はその Secret に手を触れません。Tenax が追加・削除するのは自身の sbx-… ルールだけなので、トンネルの
他のルートはそのまま残ります。accountID と zoneID を設定すると検索を省略できます。
同じトンネルでコンソール自体を提供することもできます。Access アプリケーションの背後で tenax-api のパブリックホスト名を
トンネルに追加し (Zero Trust → Networks → Tunnels → tenax → Public hostnames)、auth.provider: cloudflare-access とともに
expose.cloudflared.consoleHostname を設定します。コンソール、CLI とアクセス を参照してください。