Skip to content

About

OpenEverest provider for TiDB - uses official operator

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

TiDB Provider

Warning

Pre-alpha. OpenEverest v2 and this provider are under active development. CRD schemas, chart values and defaults change frequently, including in breaking ways, and there is no supported upgrade path between versions yet. Not for production use.

Status CI Release Go Reference License

Run TiDB — a distributed, MySQL-compatible SQL database — on Kubernetes through OpenEverest, backed by TiDB Operator v2.

What this is

OpenEverest providers translate a single, technology-agnostic Instance custom resource into the native custom resources of an upstream Kubernetes operator. This repository is the provider for TiDB: it owns the technology-specific knowledge — components, topologies, versions and parameters — so that users, the API server, and the UI stay technology-agnostic.

A TiDB cluster is composed of three mandatory components plus optional TiFlash, each reconciled into its own TiDB Operator v2 resource:

Component Role Operator resource
pd Placement Driver — metadata, timestamps (TSO), scheduling PDGroup
tikv Distributed key-value storage engine TiKVGroup
tidb Stateless SQL layer (MySQL protocol) TiDBGroup
tiflash (optional) Columnar replicas for analytical queries (HTAP) TiFlashGroup

Important

This provider is not standalone. It requires an OpenEverest installation (core CRDs and controller) in the cluster. Installing this chart on its own does nothing. See Install OpenEverest.

flowchart LR
    U([User / API / UI]) -->|creates| I["Instance<br/>core.openeverest.io"]
    I --> P["provider-tidb<br/>(this repository)"]
    P -->|reconciles into| O["Cluster + PDGroup +<br/>TiKVGroup + TiDBGroup<br/>core.pingcap.com"]
    O --> W["TiDB Operator v2"]
    W --> R[("Pods, Services,<br/>Secrets, PVCs")]
    P -->|status, endpoint,<br/>credentials| I
Loading

The provider watches Instance resources whose spec.providerRef.name is tidb, generates a shared Cluster plus one component group per component, and reports cluster health and the MySQL connection endpoint back onto Instance.status. It never manages pods directly — all lifecycle work is delegated to the operator.

Compatibility

provider-tidb OpenEverest TiDB Operator Kubernetes
0.1.x >= 2.0.0 v2.0.1 1.30 – 1.36

The bundled operator manages TiDB engine versions independently (see Versions).

Capabilities

What you can do to a running instance through the Instance API. Upgrading the provider itself is covered under Installation.

Capability Status Notes
Provisioning ✅ PD + TiKV + TiDB, optionally TiFlash
Horizontal scaling ✅ Per-component replicas
Vertical scaling (CPU / memory) ✅ Per-component resources
Custom configuration ✅ Inline TOML config per component
Scheduling policy ✅ Per-component schedulingPolicy (node selector, affinity, tolerations, topology spread, scheduler)
Version upgrades ❌ Planned — ordered rolling upgrade
Monitoring ❌ Planned
TLS ❌ Planned

Stateful components (PD, TiKV, TiFlash) additionally report:

Capability Status Notes
Persistent storage ✅ Per-component size and storage class
Storage expansion ✅ Grow storage.size; shrinking is rejected. Needs an expandable StorageClass (see below)
Backups (on demand) ✅ Full snapshot to S3-compatible storage (BR)
Backups (scheduled) ✅ Cron schedules per storage with count or time retention (see below)
Point-in-time recovery ❌ Planned
Restore ✅ Into an existing Instance, or seed a new one via spec.dataSource

See ROADMAP.md for the planned work.

Important

Growing spec.components.{pd,tikv,tiflash}.storage.size resizes the existing PVCs in place, which only works if their StorageClass sets allowVolumeExpansion: true (kubectl get storageclass <name> -o jsonpath='{.allowVolumeExpansion}'). On a StorageClass without it — e.g. the k3s/kind local-path default — the TiDB Operator leaves the volumes at their old size. Volumes can never be shrunk; Validate rejects a smaller size.

Important

TiFlash runs while spec.components.tiflash is present with a replica count other than 0 (the UI defaults to 0). Tables are only copied to TiFlash once you ask for it, e.g. ALTER TABLE t SET TIFLASH REPLICA 1. Setting the replica count to 0 (or removing the component) deletes the TiFlash nodes after the operator takes their stores offline. A store can't go offline while tables still need more TiFlash replicas than the nodes left, so run ALTER TABLE ... SET TIFLASH REPLICA 0 on those tables before scaling TiFlash in or turning it off. PD also refuses to remove a store if fewer stores than its max-replicas (3 by default) would be left, so a cluster with fewer TiKV nodes than that can't turn TiFlash off. The Instance reports Updating with tiflash (removing) until the nodes are gone.

Note

TiDB Operator v2 has no controller for BackupSchedule, so the provider runs spec.backup.storages[].schedules itself: each cron slot creates a Backup (with spec.scheduleName) that runs like an on-demand one. A slot fires only while the Instance is Ready or Updating and no earlier run of the same schedule is in progress, and is skipped if it can't start within 10 minutes. Retention is anchored on successful backups: count: N keeps the N newest successful backups, and time keeps everything inside the window plus the newest successful backup. Pruned backups follow their own deletionPolicy. An invalid cron expression sets the BackupConfigured condition to False with reason BackupScheduleInvalid.

Installation

The provider chart is published as an OCI artifact:

helm install provider-tidb \
  oci://ghcr.io/openeverest/charts/provider-tidb \
  --version <chart-version> \
  --namespace everest-system

The chart is self-contained:

  • TiDB Operator v2 is bundled as a chart dependency and installed automatically. Disable it with --set operator.enabled=false to run against an externally managed operator.
  • The TiDB CRDs are installed by a pre-install hook. They are ~15 MB — too large to ship inside the Helm release — so a Job applies the pinned CRD manifest from the operator's GitHub release before the operator and provider start. This requires cluster egress to that URL; point --set crds.url=... at a mirror for air-gapped clusters, or --set crds.install=false to manage the CRDs yourself.

Upgrade and uninstall:

helm upgrade provider-tidb oci://ghcr.io/openeverest/charts/provider-tidb
helm uninstall provider-tidb --namespace everest-system

Uninstalling the chart does not delete running Instance resources, the TiDB CRDs, or any data.

Air-gapped installs

Set --set crds.install=false to skip the CRD network pull entirely, then install the CRDs yourself first (server-side apply is required — the schemas exceed the client-side limit):

# From your own mirror of the pinned manifest:
kubectl apply --server-side -f tidb-operator.crds.yaml

helm install provider-tidb oci://ghcr.io/openeverest/charts/provider-tidb \
  --version <chart-version> --namespace everest-system \
  --set crds.install=false

Alternatively keep the hook and only repoint it at an internal mirror with --set crds.url=https://mirror.internal/tidb-operator.crds.yaml.

Usage

Verify that the provider registered itself:

kubectl get providers.core.openeverest.io tidb

Create an instance:

apiVersion: core.openeverest.io/v1alpha1
kind: Instance
metadata:
  name: my-tidb
spec:
  providerRef:
    name: tidb
  version: "8.5.2"
  topology:
    type: cluster
  components:
    pd:
      type: pd
      replicas: 3
      storage:
        size: 20Gi
    tikv:
      type: tikv
      replicas: 3
      storage:
        size: 50Gi
    tidb:
      type: tidb
      replicas: 2

spec.version and spec.topology are optional; the provider defaults apply (PD 3, TiKV 3, TiDB 2, default version bundle). More examples live in examples/.

Watch it come up and read the connection details:

kubectl get instances.core.openeverest.io my-tidb -w
kubectl get instances.core.openeverest.io my-tidb -o jsonpath='{.status.connectionSecretRef.name}'

The connection secret holds the MySQL host, port (4000), username (root) and password. The provider generates a random root password on first bootstrap (via the operator's bootstrapSQL), stores it in a Secret, and surfaces it here. Connect with any MySQL client:

mysql -h my-tidb-tidb.<namespace> -P 4000 -u root -p"$(kubectl get secret my-tidb-conn -o jsonpath='{.data.password}' | base64 -d)"

Note

Each component group expands into one instance resource per replica — e.g. spec.components.tidb.replicas: 2 yields two TiDB resources (kubectl get tidb) and two pods, all belonging to one TiDBGroup (kubectl get tidbgroup). This mirrors how a Deployment owns its Pods.

Presets

The chart ships InstancePresets, so the UI can create a working cluster in one click:

Preset PD TiKV TiDB TiFlash Use it for
tidb-dev 1 1 1 — A laptop or CI: the smallest cluster that runs (about 4 GiB)
tidb-standard 3 3 2 — A highly available transactional database
tidb-analytics 3 3 2 2 Transactions plus analytics on the same data

tidb-dev has no redundancy and sets PD's max-replicas to 1, so PD stops trying to place three copies of the data on its single TiKV node. To try TiFlash on it, add a tiflash component with at least 4 GiB of memory; TiFlash is killed for running out of memory at 3 GiB. Presets pin the default version bundle; a unit test fails if they fall behind it. Sizes and the list itself live under presets: in values.yaml; set enabled: false to hide one.

Topologies

Topology Default Description
cluster ✅ Standard distributed TiDB: PD + TiKV + TiDB, optionally TiFlash

Versions

Version bundle Default Components
8.5.2 ✅ PD / TiKV / TiDB / TiFlash v8.5.2
7.5.5 PD / TiKV / TiDB / TiFlash v7.5.5

Source of truth: definition/versions.yaml. Each bundle pins every component to the same TiDB release; the user selects one via Instance.spec.version.

Configuration

  • Chart values: charts/provider-tidb/values.yaml — provider deployment settings and the bundled operator subchart values.
  • Instance parameters: per-component config (inline TOML) and per-topology parameters, defined under definition/ and published on the Provider resource (kubectl get provider tidb -o yaml). The API server and the UI validate user input against these schemas.

Development

Requires Go (see go.mod), Docker, Helm, kubectl, and a Kubernetes cluster you can reach. dev/README.md covers the environment end to end: the recommended local k3d setup, running against a cluster you already have, and every dev/.env setting.

make dev-up             # local cluster + Tilt dev environment (see dev/README.md)
make generate           # RBAC, provider spec, Helm chart sync
make run                # run the provider locally against the cluster
make test-unit
make test-integration   # chainsaw suites under test/integration/
make dev-down

make help lists every target. make verify fails when generated files are stale — run make generate and commit the result.

The provider contract (Validate / Sync / Status / Cleanup), RBAC markers, watches, code generation, and the backup/restore interfaces are documented once for all providers in PROVIDER_DEVELOPMENT.md.

Layout

Path Purpose
cmd/provider/ Entry point
internal/provider/ ProviderInterface implementation (Sync/Validate/Status/Cleanup), RBAC markers
internal/common/ Component name constants
definition/ Provider identity, component types, versions, topologies
charts/provider-tidb/ Helm chart — bundles the operator subchart and TiDB crds/; generated/ is produced by make generate
config/rbac/role.yaml Generated ClusterRole — do not edit
test/integration/ Chainsaw suites (see its README.md)
test/vars.sh Pinned operator and engine versions used by tests
examples/ Example Instance resources
dev/ Tilt dev environment, .env configuration, k3d cluster config
.github/workflows/ CI: lint, build, unit and integration tests, release

Testing

  • Unit tests — make test-unit (mapping helpers + the provider-runtime conformance suite, which asserts every UI-schema field is reconciled by Sync).
  • Integration tests — chainsaw suites under test/integration/. The core/ suite exercises the full lifecycle: create an Instance, assert the provider produces the Cluster and component groups, simulate operator readiness, assert the Instance reports Ready, and delete. The operator itself is disabled for these tests (readiness is simulated). See test/integration/README.md.
  • CI — .github/workflows/ci.yaml runs lint, build, unit tests, generated-file verification, Helm lint, and each integration suite on every pull request.

Troubleshooting

kubectl logs -n everest-system deploy/provider-tidb -f
Symptom Where to look
Instance stuck in Provisioning kubectl describe instances.core.openeverest.io <name> conditions, then the provider logs
No Provider resource in the cluster Is the chart installed? Check the provider deployment logs
Instance ignored entirely spec.providerRef.name must be tidb
Provider logs no matches for kind "TiKVGroup" TiDB CRDs missing. The chart's pre-install hook installs them; check the <release>-crd-installer Job (and its egress to crds.url), or apply them manually: kubectl apply --server-side -f <crds.url>
Operator pod CrashLoopBackOff at startup The TiDB CRDs must exist before the operator starts (see the row above)
Groups created but no pods Inspect the group/instance status (kubectl get tidbgroup,tikvgroup,pdgroup) — the failure is upstream in the operator
Storage size raised but PVCs unchanged The StorageClass must allow volume expansion; check kubectl get pvc and the operator logs

Contributing

Issues and pull requests are welcome. See PROVIDER_DEVELOPMENT.md and the OpenEverest Code of Conduct.

Security

Report vulnerabilities per the OpenEverest security policy. Please do not open public issues for security reports.

License

Apache License 2.0 — see LICENSE for details.

About

OpenEverest provider for TiDB - uses official operator

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages