Sandbox dan kueri¶
Sandbox adalah basis data pribadi sekali pakai yang dipulihkan dari cadangan atau dari detik mana pun di dalam jendela. Sandbox adalah tujuan pemulihan bawaan, karena sekadar melihat tidak pernah membahayakan produksi.
tenax restore team-a/app --at 2026-10-07T09:41:27Z --ttl 6h --wait
tenax sandbox list
tenax sandbox show <sandbox>
Apa itu sandbox¶
- Pod basis data dengan mesin dan versi yang sama dengan target (
spec.sandbox.imagepada target), di namespace sandbox milik Tenax, dengan kredensial yang dibuat otomatis dan NetworkPolicy default-deny. - Sebuah TTL (
sandbox.defaultTTL, paling lamasandbox.maxTTL, keduanya per kebijakan dan untuk seluruh chart). Saat TTL habis, Tenax menghapus sandbox beserta penyimpanannya.tenax sandbox extend <sandbox> --by 24hmenambah waktu;tenax sandbox delete <sandbox>mengakhirinya lebih awal. - Dimiliki oleh siapa pun yang memintanya; setiap aksi terhadapnya diaudit.
Kueri¶
Halaman Kueri di konsol dan tenax query menjalankan SQL melalui proxy kueri Tenax, baca-saja secara bawaan:
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
Setiap kueri dibatasi 30 detik dan mengembalikan paling banyak 1.000 baris; --write mengizinkan penulisan (khusus
sandbox).
Di editor, Ctrl+Enter (Cmd+Enter di Mac) menjalankan kueri, atau hanya teks yang dipilih jika ada seleksi.
Pelengkapan menawarkan kata kunci, fungsi, tabel, dan kolom: mengetik membukanya setelah dua karakter, setelah
alias. ia menampilkan kolom tabel tersebut, setelah schema. tabel-tabelnya, dan Ctrl+Space membukanya di mana
saja. Tab atau Enter memilih saran, Esc menutupnya, dan selain itu Tab membuat indentasi.
Konsol memahami SQL setiap mesin (saat ini PostgreSQL dan MySQL); hasil menampilkan nilai sebagaimana dicetak oleh basis data.
Ukuran sumber daya¶
Setiap sandbox adalah pod basis data di namespace-nya sendiri. Yang didapatnya diambil dari tempat pertama yang mengaturnya:
- pemulihan: kolom CPU, Memori, Disk, dan Storage class di halaman Pulihkan (nilai abu-abu adalah
yang didapat jika Anda mengosongkannya),
tenax restore … --cpu 2 --memory 8Gi --size 50Gi --storage-class local-path, atauspec.destination.sandboxpada sebuah Restore; - target:
spec.sandbox.cpu,memory,sizeLimit,storageClasspada BackupTarget; - instalasi:
sandbox.resourcesmilik chart; - bawaan: request CPU 100m, memori 256Mi dengan limit 1Gi, dan disk sebesar dua kali data cadangan ditambah 512Mi
(minimal 1Gi) di node (
emptyDir, dihapus bersama sandbox).
| Pengaturan | Artinya |
|---|---|
| CPU | request CPU; tanpa limit CPU, sehingga pemulihan dapat memakai core yang menganggur |
| Memori | request dan limit memori |
| Disk | ukuran volume data; di disk node kecuali storage class diatur |
| Storage class | data ditempatkan di PVC dengan class ini, untuk pemulihan yang lebih besar dari yang dimungkinkan disk node |
sandbox.limits milik chart menetapkan batas atas untuk CPU, memori, dan disk. Konsol dan API menolak permintaan di
atas batas itu, dan pemulihan yang ukurannya melebihi batas (dari pengaturan target, atau ukuran otomatis cadangan
yang besar) gagal dengan alasannya alih-alih memenuhi disk di tengah jalan. Sandbox yang sedang berjalan
mempertahankan ukurannya: pulihkan lagi untuk mengubahnya.
Terhubung dari dalam klaster¶
Host, port, dan kredensial sandbox ada di halamannya (Tampilkan kredensial, diaudit) dan di tenax sandbox show.
Pod di namespace lain memerlukan label tenax.run/sandbox-client: <sandbox>; network policy sandbox
menolak semua yang lain.
Terhubung dari luar klaster¶
Cara sandbox dijangkau dari laptop ditentukan oleh instalasi (expose.provider, di bawah). Dalam setiap kasus:
- Buka akses eksternal dengan Buka akses eksternal di halaman sandbox,
tenax sandbox expose <sandbox>, atau buka akses eksternal saat memulihkan (tenax restore … --expose); ini memerlukan peranoperator. - Hubungkan dengan
tenax sandbox connect <sandbox>, yang mencetak string koneksi untuk klien basis data apa pun, atau salin dari halaman sandbox. - Tutup dengan Tutup akses eksternal atau
tenax sandbox unexpose <sandbox>. Akses juga ditutup saat sandbox kedaluwarsa atau dihapus.
expose.provider |
Yang dilakukan tenax sandbox connect |
Yang dibutuhkan klien |
|---|---|---|
none (bawaan) |
Meneruskan port lokal ke sandbox melalui kubeconfig Anda, sampai Ctrl+C | Kubeconfig yang diizinkan melakukan port-forward di tenax-sbx-<sandbox> |
service |
Mencetak alamat sandbox itu sendiri (postgres://…@sbx-7f3a.db.example.com:5432/app?sslmode=require) |
Tidak ada: klien basis data apa pun, melalui TLS |
cloudflare |
Membuka cloudflared access tcp di port lokal setelah login Access, sampai Ctrl+C |
cloudflared dan email yang diizinkan |
Sandbox Postgres melayani TLS dengan sertifikatnya sendiri (self-signed: klien memakai sslmode=require, yang
mengenkripsi tanpa memeriksa penerbit); sandbox MySQL memakai sertifikat yang dibuat MySQL.
Menjangkau sandbox dari luar klaster (administrator)¶
Tenax tidak membuka apa pun dengan sendirinya: setiap opsi memakai sesuatu yang sudah dimiliki klaster Anda.
Opsi service: satu Service Kubernetes per sandbox¶
Setiap sandbox yang diekspos mendapat Service yang dibangun dari expose.service; apa pun yang dijalankan klaster
Anda untuk Service memberinya alamat, dan Tenax menampilkan alamat itu. Ini cara paling sederhana bagi developer
(klien basis data apa pun) dan bekerja dengan Kubernetes apa pun:
| Klaster Anda memiliki | Atur | Developer terhubung ke |
|---|---|---|
| Load balancer cloud (AKS, EKS, GKE) | type: LoadBalancer, sourceRanges: [<office or VPN CIDRs>] |
IP load balancer |
| Sama seperti di atas, ditambah external-dns | juga annotations: {external-dns.alpha.kubernetes.io/hostname: "sbx-{id}.db.example.com"} dan hostnamePattern: "sbx-{id}.db.example.com" |
sbx-<id>.db.example.com |
| MetalLB (on-premises) | type: LoadBalancer |
Alamat di jaringan Anda |
| Operator Tailscale | loadBalancerClass: tailscale |
Nama tailnet sandbox; tidak ada yang publik |
| Tidak satu pun di atas | type: NodePort, hostnamePattern: "nodes.example.com" dengan nama yang sesuai untuk node Anda |
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
Sandbox menyimpan salinan data produksi
Load balancer publik melindungi sandbox hanya dengan kata sandi acaknya, TLS, dan batas waktunya. Atur
sourceRanges ke alamat asal developer Anda, atau gunakan opsi privat (Tailscale, load balancer internal melalui
anotasi cloud Anda, MetalLB di jaringan privat).
Selama sandbox diekspos, NetworkPolicy tambahan mengizinkan expose.service.allowFrom (bawaan: semuanya; penyaringan
dilakukan oleh sourceRanges milik load balancer, karena lalu lintasnya sering datang dari alamat node) pada port
basis data. Pada load balancer bawaan k3s, setiap sandbox yang diekspos mengikat port basis data di node, sehingga di
sana hanya satu sandbox Postgres dan satu sandbox MySQL yang dapat diekspos pada satu waktu.
Opsi cloudflare: tunnel di balik login Access¶
Tunnel memerlukan satu token API Cloudflare, yang dimiliki instalasi, bukan pengguna. Token ini adalah Secret Kubernetes di namespace Tenax, disiapkan sekali seperti kredensial lainnya (dengan alat secret GitOps Anda, misalnya SOPS). Konsol tidak pernah memintanya, menyimpannya, atau menampilkannya: token ini dapat mengubah DNS dan aplikasi Access di zone tersebut.
- Di Cloudflare, My Profile → API Tokens → Create Token → Custom token dengan izin berikut, untuk zone tempat
hostname berada:
- Account: Cloudflare Tunnel: Edit
- Account: Access: Apps and Policies: Edit
- Zone: DNS: Edit
- Zone: Zone: Read
-
Simpan token:
-
Konfigurasikan chart:
Letakkan hostname satu tingkat di bawah zone (sbx-{id}.example.com, bukan sbx-{id}.db.example.com): sertifikat
gratis Cloudflare hanya mencakup *.example.com, dan klien menjangkau hostname melalui HTTPS. Port basis data tidak
dapat dilindungi oleh login browser, jadi developer menjalankan cloudflared, yang dilakukan oleh
tenax sandbox connect untuk mereka.
Dengan token tersebut, Tenax menemukan akun dari zone, membuat tunnel bernama tenax (expose.cloudflare.tunnelName)
atau memakainya kembali, dan menulis token konektor tunnel ke Secret <release>-tunnel-token, yang dipakai pod
cloudflared untuk memulai. Tenax memeriksa Secret itu setiap 15 menit, sehingga token yang dirotasi di Cloudflare
sampai ke Secret dengan sendirinya (mulai ulang pod cloudflared agar token baru terpakai). allowEmails menerima
alamat dan seluruh domain (*@example.com); allowGroups menerima id grup Access.
Tunnel yang sudah Anda kelola
Atur expose.cloudflare.tunnelID untuk memakai tunnel remotely-managed yang sudah ada alih-alih tenax, dan
expose.cloudflared.tunnelTokenSecret ke Secret (key token) yang menyimpan token konektornya jika Anda lebih
suka menyediakannya sendiri; Tenax kemudian tidak menyentuh Secret itu. Tenax hanya menambah dan menghapus aturan
sbx-… miliknya sendiri, sehingga rute lain pada tunnel tetap seperti semula. accountID dan zoneID dapat
diatur untuk melewati pencarian.
Tunnel yang sama juga dapat melayani konsol itu sendiri: tambahkan public hostname untuk tenax-api pada tunnel
(Zero Trust → Networks → Tunnels → tenax → Public hostnames) di balik aplikasi Access, lalu atur
expose.cloudflared.consoleHostname dengan auth.provider: cloudflare-access: lihat
Konsol, CLI, dan akses.