Percona Everest is a free and open source tool for running and managing databases like PostgreSQL, MySQL, and MongoDB inside Kubernetes. It simplifies things by providing three ways to work with your databases: a web interface (UI), a set of commands (API), and direct access through Kubernetes itself using built-in tools like kubectl.
Note: Before working with the CRDS shown in this blog, make sure you have Percona Everest installed in your Kubernetes cluster. You can follow the official Percona Everest installation guide.
The Percona Everest Operator is a core component of the Percona Everest platform. It defines a set of Custom Resource Definitions (CRDs) and provides Kubernetes-native abstractions to help you manage your databases declaratively. In this blog post, we’ll take a closer look at the key CRDs offered by Everest and how they fit into the overall architecture.
While we generally recommend interacting with Everest through its API or UI for ease of use and abstraction, there are several scenarios where working directly with CRDs can be advantageous:
Note: We published the Percona Everest Operator CRD Usage Guide earlier this year. This blog highlights some of the most practical and commonly used aspects of that guide.
Image: Everest Operator: Key Components and CRDs
The main CRD you’ll work with is DatabaseCluster. It defines everything about your database: the engine type (like PostgreSQL, MongoDB, or MySQL), the number of replicas, storage size, resource limits, backup settings, and how the database is exposed inside or outside the cluster. You can manage your databases just like any other Kubernetes resource, declaratively and consistently.
Example for a simple PostgreSQL cluster:
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: DatabaseCluster<br>metadata:<br> labels:<br> clusterName: my-database-cluster<br> name: my-database-cluster<br>spec:<br> backup:<br> pitr:<br> enabled: false<br> engine:<br> replicas: 1<br> resources:<br> cpu: "1"<br> memory: 2G<br> storage:<br> class: standard-rwo<br> size: 25Gi<br> type: postgresql # Can be pxc, psmdb, postgresql<br> userSecretsName: everest-secrets-my-database-cluster<br> version: "17.4"<br> monitoring:<br> resources: {}<br> proxy:<br> expose:<br> type: internal<br> replicas: 1<br> resources:<br> cpu: "1"<br> memory: 30M<br> type: pgbouncer<br> |
Percona Everest currently supports the following database engines:
The DatabaseEngine CRD represents the installation of a Percona database operator, and it keeps track of:
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: DatabaseEngine<br>metadata:<br> name: percona-postgresql-operator<br>spec:<br> type: postgresql<br> |
To check the available versions, use:
|
1 |
kubectl get dbengine percona-postgresql-operator -o jsonpath='{.status.availableVersions}'<br> |
This is useful when you want to control which version you install or upgrade to.
Before configuring backups, you need to set up a backup storage location. First, create a Kubernetes secret with your cloud storage credentials:
|
1 |
apiVersion: v1<br>data:<br> AWS_ACCESS_KEY_ID: YOUR_ACCESS_KEY_ID_BASE64_ENCODED<br> AWS_SECRET_ACCESS_KEY: YOUR_SECRET_ACCESS_KEY_BASE64_ENCODED<br>kind: Secret<br>metadata:<br> name: my-s3-backup-storage<br>type: Opaque<br> |
Then, create a BackupStorage custom resource that references this secret:
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: BackupStorage<br>metadata:<br> name: my-s3-backup-storage<br>spec:<br> bucket: my-s3-bucket<br> credentialsSecretName: my-s3-backup-storage<br> description: My S3 backup storage<br> endpointURL: https://my-s3-endpoint.com<br> forcePathStyle: false<br> region: us-west-2<br> type: s3<br> verifyTLS: true<br><br> |
Finally, configure backup schedules in your DatabaseCluster:
|
1 |
spec:<br> backup:<br> schedules:<br> - name: "daily-backup"<br> enabled: true<br> schedule: "0 0 * * *" # Daily at midnight<br> retentionCopies: 7<br> backupStorageName: "my-s3-backup-storage"<br> pitr: # Point-in-Time Recovery<br> enabled: true<br> backupStorageName: "my-s3-backup-storage"<br> uploadIntervalSec: 300 # 5 minutes<br> |
You can also create on-demand backups using the DatabaseClusterBackup custom resource.
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: DatabaseClusterBackup<br>metadata:<br> labels:<br> clusterName: my-database-cluster<br> name: my-database-cluster-backup<br>spec:<br> backupStorageName: my-s3-backup-storage<br> dbClusterName: my-database-cluster<br> |
Backups may be restored to a DatabaseCluster using the DatabaseClusterRestore custom resource:
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: DatabaseClusterRestore<br>metadata:<br> name: restore-from-backup<br>spec:<br> dbClusterName: my-database-cluster<br> dataSource:<br> dbClusterBackupName: my-database-cluster-backup<br> |
Point-in-time recovery lets you restore your database to an exact moment in time, for example, just before something went wrong.
To do this in Percona Everest, you create a DatabaseClusterRestore resource. You specify the name of the backup and the exact time (in UTC) you want to restore to.
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: DatabaseClusterRestore<br>metadata:<br> name: pitr-restore<br>spec:<br> dbClusterName: my-database<br> dataSource:<br> dbClusterBackupName: base-backup<br> pitr:<br> type: date<br> date: "2024-04-11T15:30:00Z" # UTC timestamp<br> |
You can also monitor the restore status:
|
1 |
kubectl get dbrestore restore-from-backup -o jsonpath='{.status}'<br> |
Percona Everest supports Percona Monitoring and Management (PMM) as its monitoring solution. Before enabling monitoring for your database clusters, you need to create a MonitoringConfig that defines your setup.
First, create a secret with your PMM credentials:
|
1 |
apiVersion: v1<br>kind: Secret<br>metadata:<br> name: pmm-credentials<br>type: Opaque<br>data:<br> username: <YOUR BASE64 ENCODED USERNAME><br> apiKey: <YOUR BASE64 ENCODED API KEY><br> |
Then create a MonitoringConfig:
|
1 |
apiVersion: everest.percona.com/v1alpha1<br>kind: MonitoringConfig<br>metadata:<br> name: my-monitoring-config<br>spec:<br> type: pmm<br> credentialsSecretName: pmm-credentials<br> pmm:<br> url: "https://pmm.example.com"<br> image: "percona/pmm-client:2.41.0" # Optional: specify PMM client version<br> verifyTLS: true # Optional: verify TLS certificates<br> |
Now you can enable monitoring for your database cluster:
|
1 |
spec:<br> monitoring:<br> monitoringConfigName: "my-monitoring-config"<br> resources:<br> limits:<br> cpu: "200m"<br> memory: "200Mi"<br> requests:<br> cpu: "100m"<br> memory: "100Mi"<br> |
Use the following command to quickly see the current state of your cluster (e.g., ready, creating, error, etc.):
|
1 |
kubectl get databasecluster my-database-cluster -o jsonpath='{.status}' |
To get more detailed information about the cluster, including its configuration, recent events, and any possible warnings or errors, use:
|
1 |
kubectl describe databasecluster my-database-cluster<br> |
If your database cluster is stuck or shows an error, the first place to check is the operator logs. These logs can help you understand if there was a problem applying the CRD or managing the database resources.
|
1 |
kubectl logs deployment/everest-operator-controller-manager -n everest-system |
Using Percona Everest CRDs is a powerful way to manage your databases declaratively within Kubernetes. It’s especially useful for teams adopting GitOps, building automation pipelines, or working on platform engineering.
If you want to explore more examples, the official documentation includes CRD-based setups for PostgreSQL clusters, MySQL (Percona XtraDB Cluster), and MongoDB (Percona Server for MongoDB), including sharded clusters.
Resources
Feel free to share your experience in our Percona Community Forum.