Lewati ke isi

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.image pada target), di namespace sandbox milik Tenax, dengan kredensial yang dibuat otomatis dan NetworkPolicy default-deny.
  • Sebuah TTL (sandbox.defaultTTL, paling lama sandbox.maxTTL, keduanya per kebijakan dan untuk seluruh chart). Saat TTL habis, Tenax menghapus sandbox beserta penyimpanannya. tenax sandbox extend <sandbox> --by 24h menambah 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:

  1. 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, atau spec.destination.sandbox pada sebuah Restore;
  2. target: spec.sandbox.cpu, memory, sizeLimit, storageClass pada BackupTarget;
  3. instalasi: sandbox.resources milik chart;
  4. 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 peran operator.
  • 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.

  1. 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
  2. Simpan token:

    kubectl -n tenax-system create secret generic tenax-cloudflare-api --from-file=token=api-token.txt
    
  3. Konfigurasikan chart:

    expose:
      provider: cloudflare
      cloudflare:
        zone: example.com
        apiTokenSecret: tenax-cloudflare-api
        hostnamePattern: "sbx-{id}.example.com"
        allowEmails: ["*@example.com"]      # who may connect to an open tunnel
      cloudflared:
        enabled: true
    

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.