Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
MariaDB Enterprise Kubernetes Operator automates provisioning, scaling, backups, and high availability, making cloud-native database operations efficient and reliable.

Learn about migrations with MariaDB Enterprise Kubernetes Operator. This section covers strategies and procedures for smoothly migrating your MariaDB databases within Kubernetes environments.
Detailed guide on installing the MariaDB Enterprise Kubernetes Operator using Helm charts or manual manifests within a Kubernetes environment.
Explains supported deployment patterns such as standalone instances, Primary/Replica replication, and Galera Cluster configurations for high availability.
Overview of available plugins and extensions that can be used to enhance the functionality of the MariaDB Enterprise Kubernetes Operator.
Procedures for configuring automated and on-demand backups using MariaDB Enterprise Backup, including restoration steps to recover data.
This guide covers configuring standalone MariaDB Enterprise Server with minimal settings for development. Avoid using it in production due to risks like single point of failure and necessary downtime
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: password
replicas: 1
port: 3306
storage:
size: 1Gi
myCnf: |
[mariadb]
bind-address=*
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
innodb_buffer_pool_size=800M
max_allowed_packet=256M
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
memory: 1Gi
metrics:
enabled: truehelm uninstall mariadb-enterprise-operatorA collection of YAML manifests and configuration examples for various common deployment scenarios and resource management tasks.
kubectl scale deployment mariadb-enterprise-operator --replicas=0
kubectl scale deployment mariadb-enterprise-operator-webhook --replicas=0
kubectl delete validatingwebhookconfiguration mariadb-enterprise-operator-webhook
kubectl delete mutatingwebhookconfiguration mariadb-enterprise-operator-webhookcurl -sLO https://operator.mariadb.com/examples/manifests.tar.gz
mkdir -p examples
tar -xzf manifests.tar.gz -C exampleskubectl apply -f examples/configStorageClassmariadb-dump --user=${MARIADB_USER} --password=${MARIADB_PASSWORD} --host=${MARIADB_HOST} --single-transaction --events --routines --all-databases > backup.2024-08-26T12:24:34Z.sqlapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
+ maxScaleRef:
+ name: mariadb-maxscale
- # Provision a MaxScale instance and set 'spec.maxScaleRef' automatically.
- maxScale:
- enabled: true
- connection:
- secretName: mxs-repl-conn
- port: 3306
- metrics:
- enabled: truehelm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator-crds mariadb-enterprise-operator/mariadb-enterprise-operator-crds --version 25.8.0apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: blob-fuse
provisioner: blob.csi.azure.com
parameters:
protocol: fuse2
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true
mountOptions:
# Resolves the issue where non-root containers cannot access the mounted blob container.
- -o allow_other
# Ensures list operations (critical for backups/deletion) work immediately upon mount.
- --cancel-list-on-mount-seconds=0apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
# ...
storage:
persistentVolumeClaim:
# Specify your own class
storageClassName: blob-fusemariadb-dump --user=${MARIADB_USER} --password=${MARIADB_PASSWORD} --host=${MARIADB_HOST} --single-transaction --events --routines --all-databases --skip-add-locks --ignore-table=mysql.global_priv > backup.2024-08-26T12:24:34Z.sqlapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
replicas: 3
galera:
enabled: true
storage:
size: 1Gi
bootstrapFrom:
s3:
bucket: backups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: tls.crt
targetRecoveryTime: 2024-08-26T12:24:34ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
updateStrategy:
+ autoUpdateDataPlane: truehelm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator-crds mariadb-enterprise-operator/mariadb-enterprise-operator-crds --version 26.3.1helm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator --version 26.3.1oc get installplan
NAME CSV APPROVAL APPROVED
install-sjgcs mariadb-enterprise-operator.v25.10.4 Manual false
oc patch installplan install-sjgcs --type merge -p '{"spec":{"approved":true}}'
installplan.operators.coreos.com/install-sjgcs patchedapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
updateStrategy:
+ autoUpdateDataPlane: false
- autoUpdateDataPlane: truecurl -sLO https://operator.mariadb.com/scripts/migrate_maxscale_to_resource.sh
chmod +x migrate_maxscale_to_resource.sh./migrate_maxscale_to_resource.sh <mariadb_manifest.yaml>apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
suspend: truekubectl get mariadbs
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-galera True Suspended mariadb-galera-0 ReplicasFirstPrimaryLast 12mapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
updateStrategy:
+ autoUpdateDataPlane: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
galera:
agent:
- image: docker.mariadb.com/mariadb-enterprise-operator:1.0.0
+ image: docker.mariadb.com/mariadb-enterprise-operator:25.8.0
initContainer:
- image: docker.mariadb.com/mariadb-enterprise-operator:1.0.0
+ image: docker.mariadb.com/mariadb-enterprise-operator:25.8.0helm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator --version 25.8.0 kubectl scale deployment mariadb-enterprise-operator --replicas=1
kubectl scale deployment mariadb-enterprise-operator-webhook --replicas=1apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
updateStrategy:
+ autoUpdateDataPlane: false
- autoUpdateDataPlane: truekubectl apply -f examples/mariadb.yamlapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
+ enabled: true
+ required: false
+ galeraSSTEnabled: false
+ galeraServerSSLMode: PROVIDER
+ galeraClientSSLMode: DISABLEDA fast-track guide to deploying your first MariaDB Enterprise instance using the Operator, from initial configuration to a running database.
kubectl create secret docker-registry mariadb-enterprise \
--docker-server=docker.mariadb.com \
--docker-username=<email> \
--docker-password=<customer-download-token>oc extract secret/pull-secret -n openshift-config --confirmoc registry login \
--registry="docker.mariadb.com" \
--auth-basic="<email>:<customer-download-token>" \
--to=.dockerconfigjsonoc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjsonoc create secret docker-registry mariadb-enterprise \
--docker-server=docker.mariadb.com \
--docker-username=<email> \
--docker-password=<customer-download-token>apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
image: docker.mariadb.com/enterprise-server:11.4.4-2
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: mariadb-enterpriseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale
spec:
...
image: docker.mariadb.com/maxscale-enterprise:25.01.1
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: mariadb-enterpriseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
image: docker.mariadb.com/enterprise-server:11.4.4-2
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: mariadb-enterpriseapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
...
mariaDbRef:
name: mariadb
imagePullSecrets:
- name: backup-registrycurl -sLO https://operator.mariadb.com/scripts/migrate_enterprise.sh
chmod +x migrate_enterprise.shRESOURCE="<mariadb-name>" \
OLD_API_GROUP="k8s.mariadb.com" \
NEW_API_GROUP="enterprise.mariadb.com" \
NEW_MARIADB_IMAGE="docker.mariadb.com/enterprise-server:11.4.4-2" \
NEW_MARIADB_OPERATOR_IMAGE="docker.mariadb.com/mariadb-enterprise-operator:<operator-version>" \
./migrate_enterprise.shhelm uninstall mariadb-operatorkubectl delete role <mariadb-name>for crd in $(kubectl get crds -o json | jq -r '.items[] | select(.spec.group=="k8s.mariadb.com") | .metadata.name'); do
kubectl get "$crd" -A -o json | jq -r '.items[] | "\(.metadata.namespace)/\(.metadata.name)"' | while read cr; do
ns=$(echo "$cr" | cut -d'/' -f1)
name=$(echo "$cr" | cut -d'/' -f2)
echo "Removing finalizers from $crd: $name in $ns..."
kubectl patch "$crd" "$name" -n "$ns" --type merge -p '{"metadata":{"finalizers":[]}}'
done
done
helm uninstall mariadb-operator-crdsfor pod in $(kubectl get pods -l app.kubernetes.io/instance=<mariadb-name> -o jsonpath='{.items[*].metadata.name}'); do
kubectl exec "$pod" -- sh -c 'mariadb-upgrade -u root -p${MARIADB_ROOT_PASSWORD} -f'
donekubectl rollout restart deployment mariadb-enterprise-operatorapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
updateStrategy:
+ autoUpdateDataPlane: truehelm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator-crds mariadb-enterprise-operator/mariadb-enterprise-operator-crds --version 25.10.4helm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator --version 25.10.4oc get installplan
NAME CSV APPROVAL APPROVED
install-sjgcs mariadb-enterprise-operator.v25.10.4 Manual false
oc patch installplan install-sjgcs --type merge -p '{"spec":{"approved":true}}'
installplan.operators.coreos.com/install-sjgcs patchedapiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: mariadb-enterprise-operator
namespace: openshift-operators
spec:
channel: stable-v25.10
installPlanApproval: Automatic
name: mariadb-enterprise-operator
source: certified-operators
sourceNamespace: openshift-marketplaceapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
updateStrategy:
+ autoUpdateDataPlane: false
- autoUpdateDataPlane: truekubectl get mxs maxscale-galera -o yaml > maxscale-galera.yaml
kubectl delete mxs maxscale-galeraapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
+ required: true
+ galeraServerSSLMode: SERVER_X509curl -sLO https://operator.mariadb.com/scripts/migrate_galera_ssl.sh
chmod +x migrate_galera_ssl.sh./migrate_galera_ssl.sh <mariadb-name>apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
+ galeraSSTEnabled: true
+ galeraClientSSLMode: VERIFY_IDENTITYapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
+ tls:
+ enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replication:
agent:
kubernetesAuth:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replication:
agent:
basicAuth:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
storage:
size: 1GiPodmaxScaleRef: The name of the MaxScale CR that we will be creating right after.replicas: The number of MaxScale instances to deploy.Explains how to manage database objects like users, databases, and privileges natively through Kubernetes Custom Resources (CRDs).
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
updateStrategy:
type: ReplicasFirstPrimaryLastapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
- image: docker.mariadb.com/enterprise-server:10.6.18-14.2
+ image: docker.mariadb.com/enterprise-server:10.6.19-15.1
resources:
requests:
cpu: 200m
memory: 128Mi
limits:
- memory: 1Gi
+ memory: 2GiapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1kubectl get mariadbs
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-galera True Pending update mariadb-galera-0 OnDelete 5m17skubectl get mariadbs
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-galera True Updating mariadb-galera-0 OnDelete 9m50sNAME READY STATUS PRIMARY UPDATES AGE
mariadb-galera True Running mariadb-galera-0 OnDelete 12mapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
updateStrategy:
autoUpdateDataPlane: trueapiVersion: v1
kind: Secret
metadata:
name: mariadb
stringData:
password: MariaDB11!kubectl apply -f secret.yamlapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: password
imagePullSecrets:
- name: mariadb-enterprise
maxScaleRef:
name: maxscale-galera
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
storage:
size: 1Gi
replicas: 3
galera:
enabled: truekubectl apply -f mariadb-galera.yaml❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-galera-0 2/2 Running 0 101s
mariadb-galera-1 2/2 Running 0 101s
mariadb-galera-2 2/2 Running 0 101sapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
imagePullSecrets:
- name: mariadb-enterprise
mariaDbRef:
name: mariadb-galera
replicas: 2kubectl apply -f maxscale-galera.yaml❯ kubectl get pods
mariadb-galera-0 2/2 Running 0 10m
mariadb-galera-1 2/2 Running 0 10m
mariadb-galera-2 2/2 Running 0 10m
maxscale-galera-0 1/1 Running 0 81s
maxscale-galera-1 1/1 Running 0 81s
❯ kubectl get maxscale
NAME READY STATUS PRIMARY AGE
maxscale-galera True Running mariadb-galera-0 65s
❯ kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-galera True Running mariadb-galera-0 ReplicasFirstPrimaryLast 10m❯ kubectl run mariadb-connect --rm -it --image=docker.mariadb.com/enterprise-server:11.4 -- bash -c "mariadb -u mariadb -p'MariaDB11!' --ssl=false -h maxscale-galera"
If you don't see a command prompt, try pressing enter.
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mariadb |
+--------------------+
2 rows in set (0.001 sec)apiVersion: enterprise.mariadb.com/v1alpha1
kind: ExternalMariaDB
metadata:
name: external-mariadb
spec:
host: mariadb.example.com
port: 3306
username: root
passwordSecretKeyRef:
name: mariadb
key: password
connection:
secretName: external-mariadb
healthCheck:
interval: 5sapiVersion: enterprise.mariadb.com/v1alpha1
kind: ExternalMariaDB
metadata:
name: external-mariadb
spec:
host: mariadb.example.com
port: 3306
username: root
passwordSecretKeyRef:
name: mariadb
key: password
tls:
enabled: true
clientCertSecretRef:
name: client-cert-secret
serverCASecretRef:
name: ca-cert-secret
connection:
secretName: external-mariadb
healthCheck:
interval: 5s
retryInterval: 10sapiVersion: enterprise.mariadb.com/v1alpha1
kind: ExternalMariaDB
metadata:
name: external-mariadb
spec:
host: mariadb.example.com
port: 3306
username: root
passwordSecretKeyRef:
name: mariadb
key: password
tls:
enabled: true
mutual: false
clientCASecretRef:
name: client-ca-secret
connection:
secretName: external-mariadb
healthCheck:
interval: 5s
retryInterval: 10sapiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user-external
spec:
name: user
mariaDbRef:
name: external-mariadb
kind: ExternalMariaDB
passwordSecretKeyRef:
name: mariadb
key: password
maxUserConnections: 20
host: "%"
cleanupPolicy: Delete
requeueInterval: 10h
retryInterval: 30sapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
inheritMetadata:
labels:
database.myorg.io: mariadb
annotations:
database.myorg.io: mariadbapiVersion: v1
kind: Service
metadata:
annotations:
database.myorg.io: mariadb
labels:
database.myorg.io: mariadb
name: mariadb-galera-primaryapiVersion: v1
kind: Pod
metadata:
annotations:
database.myorg.io: mariadb
labels:
database.myorg.io: mariadb
name: mariadb-galera-0apiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
inheritMetadata:
labels:
sidecar.istio.io/inject: "true"
annotations:
database.myorg.io: mariadb
podMetadata:
labels:
sidecar.istio.io/inject: "false"apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
service:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.150
primaryService:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.160
secondaryService:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.161apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
storage:
size: 1Gi
volumeClaimTemplate:
metadata:
annotations:
database.myorg.io: mariadb
labels:
database.myorg.io: mariadb
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1GiapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
service:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.150apiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
podMetadata:
labels:
sidecar.istio.io/inject: "false"apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
storage:
size: 1Gi
storageClassName: gp3apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
storage:
size: 1Gi
storageClassName: gp3
volumeClaimTemplate:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: gp3apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
storage:
size: 2Gi
resizeInUseVolumes: true
waitForVolumeResize: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
storage:
ephemeral: truemariadb-enterprise imagePullSecret configured by default. This means that you can configure a Secret named mariadb-enterprise in same namespace where the operator will be installed in order to pull images from the MariaDB Enterprise registry.oc get packagemanifests -n openshift-marketplace mariadb-enterprise-operator
NAME CATALOG AGE
mariadb-enterprise-operator Certified Operators 21hsecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsNonRoot: true
runAsUser: 1000650000apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: mariadb-enterprise-operator
namespace: openshift-operators
spec:
channel: stable
installPlanApproval: Automatic
name: mariadb-enterprise-operator
source: certified-operators
sourceNamespace: openshift-marketplaceapiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: mariadb-enterprise-operator
namespace: my-namespace
spec:
targetNamespaces:
- my-namespace
- my-other-namespace
- my-other-other-namespace
upgradeStrategy: DefaultapiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: mariadb-enterprise-operator
namespace: my-namespace
spec:
channel: stable
installPlanApproval: Automatic
name: mariadb-enterprise-operator
source: certified-operators
sourceNamespace: openshift-marketplaceapiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: mariadb-enterprise-operator
namespace: openshift-operators
spec:
channel: stable # Change this to the actual channel you want
installPlanApproval: Automatic
name: mariadb-enterprise-operator
source: certified-operators
sourceNamespace: openshift-marketplaceoc delete subscription mariadb-enterprise-operatoroc delete clusterserviceversion mariadb-enterprise-operator.v1.0.0apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
myCnf: |
[mariadb]
bind-address=*
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
innodb_buffer_pool_size=1024M
max_allowed_packet=256MapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
myCnfConfigMapKeyRef:
name: mariadb
key: mycnfapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
resources:
requests:
cpu: 1
memory: 4Gi
limits:
memory: 4GiapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
myCnf: |
[mariadb]
innodb_buffer_pool_size=3200MapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
timeZone: "UTC"apiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup-scheduled
spec:
mariaDbRef:
name: mariadb
schedule:
cron: "*/1 * * * *"
suspend: false
timeZone: "UTC"apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-passwordapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
generate: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
generate: falseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
myCnfConfigMapKeyRef:
name: mariadb
key: mycnfapiVersion: v1
kind: ConfigMap
metadata:
name: mariadb
labels:
enterprise.mariadb.com/watch: ""
data:
mycnf: |
[mariadb]
bind-address=*
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
innodb_buffer_pool_size=1024M
max_allowed_packet=256MapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
# Tune your liveness probe accordingly to avoid Pod restarts.
livenessProbe:
periodSeconds: 10
timeoutSeconds: 5
# Tune your readiness probe accordingly to prevent disruptions in network traffic.
readinessProbe:
periodSeconds: 10
timeoutSeconds: 5
# Tune your startup probe accordingly to ensure that the SST completes with a large amount of data.
# failureThreshold × periodSeconds = 30 × 10 = 300s = 5m until the container gets restarted if unhealthy
startupProbe:
failureThreshold: 30
periodSeconds: 10
timeoutSeconds: 5apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: bob
spec:
mariaDbRef:
name: mariadb
passwordSecretKeyRef:
name: bob-password
key: password
maxUserConnections: 20
host: "%"
cleanupPolicy: DeleteapiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user
spec:
name: user-customapiVersion: enterprise.mariadb.com/v1alpha1
kind: Grant
metadata:
name: grant-bob
spec:
mariaDbRef:
name: mariadb
privileges:
- "SELECT"
- "INSERT"
- "UPDATE"
database: "*"
table: "*"
username: bob
grantOption: true
host: "%"apiVersion: enterprise.mariadb.com/v1alpha1
kind: Database
metadata:
name: wordpress
spec:
mariaDbRef:
name: mariadb
characterSet: utf8
collate: utf8_general_ciapiVersion: enterprise.mariadb.com/v1alpha1
kind: Database
metadata:
name: database
spec:
name: database-customapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
username: bob
passwordSecretKeyRef:
name: bob-password
key: password
database: wordpressapiVersion: v1
kind: Secret
metadata:
name: mariadb-auth
stringData:
passwordHash: "*57685B4F0FF9D049082E296E2C39354B7A98774E"
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user-password-hash
spec:
mariaDbRef:
name: mariadb
passwordHashSecretKeyRef:
name: mariadb-auth
key: passwordHash
host: "%"apiVersion: v1
kind: Secret
metadata:
name: mariadb-auth
stringData:
passwordHash: "*57685B4F0FF9D049082E296E2C39354B7A98774E"
nativePasswordPlugin: mysql_native_password
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user-password-plugin
spec:
mariaDbRef:
name: mariadb
passwordPlugin:
pluginNameSecretKeyRef:
name: mariadb-auth
key: nativePasswordPlugin
pluginArgSecretKeyRef:
name: mariadb-auth
key: passwordHash
host: "%"apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user
spec:
requeueInterval: 30s
retryInterval: 5sapiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user
spec:
cleanupPolicy: Delete

Explains how application clients connect to databases managed by the Operator, including the use of Kubernetes Services and MaxScale proxies.
# Log in to the official MariaDB registry
docker login docker.mariadb.com
# Log in to your private registry
docker login <private-registry-url>docker pull docker.mariadb.com/mariadb-enterprise-operator:25.8.0docker tag docker.mariadb.com/mariadb-enterprise-operator:25.8.0 <private-registry-url>/mariadb/mariadb-enterprise-operator:25.8.0docker login docker.mariadb.com
docker pull docker.mariadb.com/mariadb-enterprise-operator:25.8.0docker save [docker.mariadb.com/mariadb-enterprise-operator:25.8.0 -o mariadb-enterprise-operator_25.8.0.tardocker load -i mariadb-enterprise-operator_25.8.0.tardocker login <private-registry-url>docker tag docker.mariadb.com/mariadb-enterprise-operator:25.8.0 <private-registry-url>/mariadb/mariadb-enterprise-operator:25.8.0ctr image pull docker.mariadb.com/mariadb-enterprise-operator:25.8.0ctr -n=k8s.io image import mariadb-enterprise-operator-25.8.0.tarctr image lsapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
bootstrapFrom:
restoreJob:
affinity:
antiAffinityEnabled: true
...
metrics:
exporter:
affinity:
antiAffinityEnabled: true
...
affinity:
antiAffinityEnabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb-galera
...
affinity:
antiAffinityEnabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb-galera
...
affinity:
antiAffinityEnabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
mariaDbRef:
name: mariadb-galera
...
metrics:
exporter:
affinity:
antiAffinityEnabled: true
...
affinity:
antiAffinityEnabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
mariaDbRef:
name: mariadb-galera
...
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/instance
operator: In
values:
- maxscale-galera
# 'mariadb-galera' instance omitted (default anti-affinity rule)
topologyKey: kubernetes.io/hostnameapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tolerations:
- key: "enterprise.mariadb.com/ha"
operator: "Exists"
effect: "NoSchedule"
nodeSelector:
"enterprise.mariadb.com/node": "ha"
affinity:
antiAffinityEnabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
podDisruptionBudget:
maxUnavailable: 33%1docker push <private-registry-url>/mariadb/mariadb-enterprise-operator:25.8.0docker push <private-registry-url>/mariadb/mariadb-enterprise-operator:25.8.0ctr image export mariadb-enterprise-operator-25.8.0.tar docker.mariadb.com/mariadb-enterprise-operator:25.8.0crictl imagesapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
secretName: connection
healthCheck:
interval: 30s
retryInterval: 3sapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb
serviceName: mariadb-primary
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
secretName: connectionapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
username: app
passwordSecretKeyRef:
name: app-password
key: password
generate: true
database: appapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: app-connection
spec:
mariaDbRef:
name: mariadb
username: app
passwordSecretKeyRef:
name: app-password
key: password
database: app
secretName: app-connectionapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
secretName: connection
secretTemplate:
metadata:
labels:
app.kubernetes.io/name: myapp
annotations:
app.kubernetes.io/managed-by: mariadb-enterprise-operator
key: dsn
usernameKey: username
passwordKey: password
hostKey: host
portKey: port
databaseKey: databaseapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
params:
parseTime: "true"
timeout: "5s"
secretName: connection
secretTemplate:
key: dsn
format: mysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }}apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: app
spec:
mariaDbRef:
name: mariadb-galera
require:
issuer: "/CN=mariadb-galera-ca"
subject: "/CN=mariadb-galera-client"
host: "%"
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: Grant
metadata:
name: grant-app
spec:
mariaDbRef:
name: mariadb-galera
privileges:
- "ALL PRIVILEGES"
database: "*"
table: "*"
username: app
host: "%"
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb-galera
username: app
tlsClientCertSecretRef:
name: mariadb-galera-client-cert
healthCheck:
interval: 30sapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
namespace: app
spec:
mariaDbRef:
name: mariadb
namespace: mariadb
username: app
passwordSecretKeyRef:
name: app
key: password
database: app
secretName: connectionapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection-maxscale
spec:
maxScaleRef:
name: maxscale-galera
username: maxscale-galera-client
passwordSecretKeyRef:
name: maxscale-galera-client
key: password
secretName: conn-mxs
port: 3306
healthCheck:
interval: 30sapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection-external
spec:
mariaDbRef:
name: external-mariadb
kind: ExternalMariaDB
username: user
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
secretName: connection-external
healthCheck:
interval: 5sapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
secretName: connection
healthCheck:
interval: 30s
retryInterval: 3scat <<'EOF' | vault policy write -non-interactive mariadb -
# Allow access to MariaDB secrets
path "mariadb/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
# Allow reading the mount configuration
path "sys/mounts/mariadb/tune" {
capabilities = ["read"]
}
EOFvault token create -policy mariadbKey Value
--- -----
token EXAMPLE_TOKEN
token_accessor utFtmh98YAAJyYdxEVN3SFQA
token_duration 768h
token_renewable true
token_policies ["default" "mariadb"]
identity_policies []
policies ["default" "mariadb"]export TOKEN="EXAMPLE_TOKEN"
kubeclt create secret generic mariadb-vault-token --from-literal=token="$TOKEN"kubectl create secret generic vault-tls --from-file=./ca.crt---
apiVersion: v1
kind: Secret
metadata:
name: mariadb # Used to hold the mariadb and root user passwords
labels:
enterprise.mariadb.com/watch: ""
stringData:
password: MariaDB11!
root-password: MariaDB11!
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
image: docker.mariadb.com/enterprise-server:11.4.7-4.3
rootPasswordSecretKeyRef:
name: mariadb
key: password
username: mariadb
passwordSecretKeyRef:
name: mariadb-password
key: password
generate: true
database: mariadb
port: 3306
storage:
size: 1Gi
# storageClassName: csi-hostpath-sc
myCnf: |
[mariadb]
bind-address=*
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
innodb_buffer_pool_size=800M
max_allowed_packet=256M
plugin_load_add = hashicorp_key_management
hashicorp-key-management-vault-url=https://vault-0.vault-internal.default.svc.cluster.local:8200/v1/mariadb
hashicorp-key-management-caching-enabled=ON
hashicorp-key-management-vault-ca=/etc/vault/certs/ca.crt
innodb_encrypt_tables = FORCE
innodb_encrypt_log = ON
innodb_encrypt_temporary_tables = ON
encrypt_tmp_disk_tables = ON
encrypt_tmp_files = ON
encrypt_binlog = ON
aria_encrypt_tables = ON
innodb_encryption_threads = 4
innodb_encryption_rotation_iops = 2000
env:
- name: VAULT_TOKEN # This is where our token is defined!
valueFrom:
secretKeyRef:
name: mariadb-vault-token
key: token
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 1Gi
metrics:
enabled: true
volumes:
- name: vault-certificates
secret:
secretName: vault-tls
defaultMode: 0600
volumeMounts:
- name: vault-certificates
mountPath: /etc/vault/certs/kubectl run mariadb-connect --rm -it --image=mariadb:11.4 -- bash -c "mariadb -u root -p'MariaDB11!' --ssl=false -h mariadb"If you don't see a command prompt, try pressing enter.
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 95
Server version: 11.4.7-4-MariaDB-enterprise MariaDB Enterprise Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>SELECT * from information_schema.INNODB_TABLESPACES_ENCRYPTION;MariaDB [my_db]> SELECT * from information_schema.INNODB_TABLESPACES_ENCRYPTION;
+-----------------+-------------------+-----------------+---------------------+----------------+----------------------+
| NAME | ENCRYPTION_SCHEME | MIN_KEY_VERSION | CURRENT_KEY_VERSION | CURRENT_KEY_ID | ROTATING_OR_FLUSHING |
+-----------------+-------------------+-----------------+---------------------+----------------+----------------------+
| innodb_system | 1 | 1 | 1 | 1 | 0 |
| innodb_undo001 | 1 | 1 | 1 | 1 | 0 |
| innodb_undo002 | 1 | 1 | 1 | 1 | 0 |
| innodb_undo003 | 1 | 1 | 1 | 1 | 0 |
| mysql/innodb_ta | 1 | 1 | 1 | 1 | 0 |
| mysql/innodb_in | 1 | 1 | 1 | 1 | 0 |
| mysql/gtid_slav | 1 | 1 | 1 | 1 | 0 |
| mysql/transacti | 1 | 1 | 1 | 1 | 0 |
| my_db/people | 1 | 1 | 1 | 1 | 0 |
+-----------------+-------------------+-----------------+---------------------+----------------+----------------------+vault secrets enable -path /mariadb -version=2 kvvault kv put /mariadb/1 data="$(openssl rand -hex 32)"
vault kv put /mariadb/2 data="$(openssl rand -hex 32)"kubectl run mariadb-connect --rm -it --image=mariadb:11.4 -- bash -c "mariadb -u root -p'MariaDB11!' --ssl=false -h mariadb"SELECT * from information_schema.INNODB_TABLESPACES_ENCRYPTION;export TOKEN="EXAMPLE_TOKEN"
kubeclt create secret generic mariadb-vault-token --from-literal=token="$TOKEN"apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
podMetadata:
annotations:
enterprise.mariadb.com/restarted-at: "2025-09-19T12:54:10Z"openssl rand -hex 32SELECT * from information_schema.INNODB_TABLESPACES_ENCRYPTION;vault kv put /mariadb/1 data="$(openssl rand -hex 32)"
vault kv put /mariadb/2 data="$(openssl rand -hex 32)"MariaDB [my_db]> SELECT * from information_schema.INNODB_TABLESPACES_ENCRYPTION;
+-----------------+-------------------+-----------------+---------------------+----------------+----------------------+
| NAME | ENCRYPTION_SCHEME | MIN_KEY_VERSION | CURRENT_KEY_VERSION | CURRENT_KEY_ID | ROTATING_OR_FLUSHING |
+-----------------+-------------------+-----------------+---------------------+----------------+----------------------+
| innodb_system | 1 | 1 | 2 | 1 | 0 |
| innodb_undo001 | 1 | 1 | 2 | 1 | 0 |
| innodb_undo002 | 1 | 1 | 2 | 1 | 0 |
| innodb_undo003 | 1 | 1 | 2 | 1 | 0 |
| mysql/innodb_ta | 1 | 1 | 2 | 1 | 0 |
| mysql/innodb_in | 1 | 1 | 2 | 1 | 0 |
| mysql/gtid_slav | 1 | 1 | 2 | 1 | 0 |
| mysql/transacti | 1 | 1 | 2 | 1 | 0 |
| my_db/people | 1 | 1 | 2 | 1 | 0 |
+-----------------+-------------------+-----------------+---------------------+----------------+----------------------+# /etc/nslcd.conf: Configuration file for nslcd(8)
# The user/group nslcd will run as. Note that these should not be LDAP users.
# required to be `mysql`
uid mysql
# required to be `mysql`
gid mysql
# The location of the LDAP server.
uri ldap://openldap-service.default.svc.cluster.local:389
# The search base that will be used for all queries.
base dc=openldap-service,dc=default,dc=svc,dc=cluster,dc=local
# The distinguished name with which to bind to the directory server for lookups.
# This is a service account used by the daemon.
binddn cn=admin,dc=openldap-service,dc=default,dc=svc,dc=cluster,dc=local
bindpw PASSWORD_REPLACE-ME# Change the protocol to `ldaps`
+uri ldaps://openldap-service.default.svc.cluster.local:636
-uri ldap://openldap-service.default.svc.cluster.local:389
# ...
+tls_reqcert demand # Look at: https://linux.die.net/man/5/ldap.conf then search for TLS_REQCERT
+tls_cacertfile /etc/openldap/certs/tls.crt # You will need to mount this certificate (from a secret) laterpasswd: files ldap
group: files ldap
shadow: files ldap # ....
myCnf: |
[mariadb]
plugin_load_add = auth_pam # Load auth plugin
# ....---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: mariadb-nslcd-secret
stringData:
nslcd.conf: |
# /etc/nslcd.conf: Configuration file for nslcd(8)
# The user/group nslcd will run as. Note that these should not be LDAP users.
uid mysql # required to be `mysql`
gid mysql # required to be `mysql`
# The location of the LDAP server.
uri ldap://openldap-service.default.svc.cluster.local:389
# The search base that will be used for all queries.
base dc=openldap-service,dc=default,dc=svc,dc=cluster,dc=local
# The distinguished name with which to bind to the directory server for lookups.
# This is a service account used by the daemon.
binddn cn=admin,dc=openldap-service,dc=default,dc=svc,dc=cluster,dc=local
bindpw PASSWORD_REPLACE-ME
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-nsswitch-configmap
labels:
enterprise.mariadb.com/watch: ""
data:
nsswitch.conf: |
passwd: files ldap
group: files ldap
shadow: files ldap
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-pam-configmap
labels:
enterprise.mariadb.com/watch: ""
data:
mariadb: |
# This is needed to tell PAM to use pam_ldap.so
auth required pam_ldap.so
account required pam_ldap.so---
apiVersion: v1
kind: Secret
metadata:
name: mariadb # Used to hold the mariadb and root user passwords
labels:
enterprise.mariadb.com/watch: ""
stringData:
password: MariaDB11!
root-password: MariaDB11!
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
generate: true
database: mariadb
port: 3306
storage:
size: 1Gi
service:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.20
myCnf: |
[mariadb]
bind-address=*
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
innodb_buffer_pool_size=800M
max_allowed_packet=256M
plugin_load_add = auth_pam # Load auth plugin
resources:
requests:
cpu: 1
memory: 128Mi
limits:
memory: 1Gi
metrics:
enabled: true
volumes: # Attach `nslcd.conf`, `nsswitch.conf` and `mariadb` (pam). Also add an emptyDir volume for `nslcd` socket
- name: nslcd
secret:
secretName: mariadb-nslcd-secret
defaultMode: 0600
- name: nsswitch
configMap:
name: mariadb-nsswitch-configmap
defaultMode: 0600
- name: mariadb-pam
configMap:
name: mariadb-pam-configmap
defaultMode: 0600
- name: nslcd-run
emptyDir: {}
sidecarContainers:
# The `nslcd` daemon is ran as a sidecar container
- name: nslcd
image: docker.mariadb.com/nslcd:0.9.10-13
volumeMounts:
- name: nslcd
mountPath: /etc/nslcd.conf
subPath: nslcd.conf
- name: nsswitch
mountPath: /etc/nsswitch.conf
subPath: nsswitch.conf
# nslcd-run is missing because volumeMounts from main container are shared with sidecar
volumeMounts:
- name: mariadb-pam
mountPath: /etc/pam.d/mariadb
subPath: mariadb
- name: nslcd-run
mountPath: /var/run/nslcd---
apiVersion: v1
kind: Secret
metadata:
name: mariadb-ldap
stringData:
plugin: pam # name of the plugin, must be `pam`
pamModule: mariadb # This is the name of the pam config file placed in `/etc/pam.d/`
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: ldap-user # This user must exist already in your ldap server.
spec:
mariaDbRef:
name: mariadb
host: "%" # Don't specify the ldap host here. Keep this as is
passwordPlugin:
pluginNameSecretKeyRef:
name: mariadb-ldap
key: plugin
pluginArgSecretKeyRef:
name: mariadb-ldap
key: pamModule
cleanupPolicy: Delete
requeueInterval: 10h
retryInterval: 30skubectl run mariadb-connect --rm -it --image=mariadb:11.4 -- bash -c "mariadb -u ldap-user -p'<secret>' --ssl=false -h mariadb"If you don't see a command prompt, try pressing enter.
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 95
Server version: 11.4.7-4-MariaDB-enterprise MariaDB Enterprise Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>kubectl create secret generic mariadb-ldap-tls --from-file=./tls.crt volumes: # Attach `nslcd.conf`, `nsswitch.conf` and `mariadb` (pam). Also add an emptyDir volume for `nslcd` socket
- name: nslcd
secret:
secretName: mariadb-nslcd-secret
defaultMode: 0600
- name: nsswitch
configMap:
name: mariadb-nsswitch-configmap
defaultMode: 0600
- name: mariadb-pam
configMap:
name: mariadb-pam-configmap
defaultMode: 0600
- name: nslcd-run
emptyDir: {}
+ - name: ldap-tls
+ secret:
+ secretName: mariadb-ldap-tls
+ defaultMode: 0600
sidecarContainers:
# The `nslcd` daemon is ran as a sidecar container
- name: nslcd
image: docker.mariadb.com/nslcd:0.9.10-13
volumeMounts:
- name: nslcd
mountPath: /etc/nslcd.conf
subPath: nslcd.conf
- name: nsswitch
mountPath: /etc/nsswitch.conf
subPath: nsswitch.conf
+ - name: ldap-tls
+ mountPath: /etc/openldap/certs/
# nslcd-run is missing because volumeMounts from main container are shared with sidecar
volumeMounts:
- name: mariadb-pam
mountPath: /etc/pam.d/mariadb
subPath: mariadb
- name: nslcd-run
mountPath: /var/run/nslcdapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-repl
spec:
services:
- name: rw-router
router: readwritesplit
listener:
port: 3306
+ params: # Configure the following options for all services that should be PAM-enabled.
+ authenticator: pamauth
+ authenticator_options: "skip_authentication=true"sudo sysctl -w fs.nr_open=1048576
kind create clusterMariaDB configurationJobBackup CRRestore CRMariaDB instancesmysql.global_privLOCK TABLESMariaDB running in KubernetesMariaDB with different topologyMariaDBsMariaDBsPods restarting after bootstrapping from a backupgalera-0, galera-1 and galera-2.apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
replicas: 3
galera:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
galera:
enabled: true
config:
reuseStorageVolume: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
galera:
providerOptions:
gcs.fc_limit: '64'apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
galera:
enabled: true
recovery:
enabled: true
minClusterSize: 1
clusterMonitorInterval: 10s
clusterHealthyTimeout: 30s
clusterBootstrapTimeout: 10m
podRecoveryTimeout: 5m
podSyncTimeout: 5mapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
galera:
enabled: true
recovery:
job:
metadata:
labels:
sidecar.istio.io/inject: "false"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256MiapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
galera:
enabled: true
recovery:
enabled: true
forceClusterBootstrapInPod: "mariadb-galera-0"kubectl get mariadb mariadb-galera -o jsonpath="{.status.galeraRecovery}" | jq
{
"recovered": {
"mariadb-galera-0": {
"seqno": 350454,
"uuid": "67a44ea9-63a8-11ef-98a2-2b0c0aa0a627"
},
"mariadb-galera-1": {
"seqno": 350450,
"uuid": "67a44ea9-63a8-11ef-98a2-2b0c0aa0a627"
}
},
"state": {
"mariadb-galera-0": {
"safeToBootstrap": false,
"seqno": -1,
"uuid": "67a44ea9-63a8-11ef-98a2-2b0c0aa0a627",
"version": "2.1"
},
"mariadb-galera-1": {
"safeToBootstrap": false,
"seqno": -1,
"uuid": "67a44ea9-63a8-11ef-98a2-2b0c0aa0a627",
"version": "2.1"
},
"mariadb-galera-2": {
"safeToBootstrap": false,
"seqno": -1,
"uuid": "67a44ea9-63a8-11ef-98a2-2b0c0aa0a627",
"version": "2.1"
}
}
}apiVersion: v1
kind: Secret
metadata:
name: mariadb
stringData:
root-password: MariaDB11!
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
storage:
size: 1Gi
replicas: 3
galera:
enabled: truekubectl get mariadbs
NAME READY STATUS PRIMARY POD AGE
mariadb-galera True Running mariadb-galera-0 48m
kubectl get events --field-selector involvedObject.name=mariadb-galera --sort-by='.lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
...
45m Normal GaleraClusterHealthy mariadb/mariadb-galera Galera cluster is healthy
kubectl get mariadb mariadb-galera -o jsonpath="{.status.conditions[?(@.type=='GaleraReady')]}" | jq
{
"lastTransitionTime": "2023-07-13T18:22:31Z",
"message": "Galera ready",
"reason": "GaleraReady",
"status": "True",
"type": "GaleraReady"
}
kubectl get mariadb mariadb-galera -o jsonpath="{.status.conditions[?(@.type=='GaleraConfigured')]}" | jq
{
"lastTransitionTime": "2023-07-13T18:22:31Z",
"message": "Galera configured",
"reason": "GaleraConfigured",
"status": "True",
"type": "GaleraConfigured"
}
kubectl get statefulsets
NAME READY AGE
mariadb-galera 3/3 58m
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mariadb-galera-0 2/2 Running 0 58m 10.244.2.4 mdb-worker3 <none> <none>
mariadb-galera-1 2/2 Running 0 58m 10.244.1.9 mdb-worker2 <none> <none>
mariadb-galera-2 2/2 Running 0 58m 10.244.5.4 mdb-worker4 <none> <none>kubectl delete pods -l app.kubernetes.io/instance=mariadb-galera
pod "mariadb-galera-0" deleted
pod "mariadb-galera-1" deleted
pod "mariadb-galera-2" deletedkubectl get mariadb mariadb-galera
NAME READY STATUS PRIMARY POD AGE
mariadb-galera False Galera not ready mariadb-galera-0 67m
kubectl get events --field-selector involvedObject.name=mariadb-galera --sort-by='.lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
...
48s Warning GaleraClusterNotHealthy mariadb/mariadb-galera Galera cluster is not healthy
kubectl get mariadb mariadb-galera -o jsonpath="{.status.conditions[?(@.type=='GaleraReady')]}" | jq
{
"lastTransitionTime": "2023-07-13T19:25:17Z",
"message": "Galera not ready",
"reason": "GaleraNotReady",
"status": "False",
"type": "GaleraReady"
}kubectl get events --field-selector involvedObject.name=mariadb-galera --sort-by='.lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
...
16m Warning GaleraClusterNotHealthy mariadb/mariadb-galera Galera cluster is not healthy
16m Normal GaleraPodStateFetched mariadb/mariadb-galera Galera state fetched in Pod 'mariadb-galera-2'
16m Normal GaleraPodStateFetched mariadb/mariadb-galera Galera state fetched in Pod 'mariadb-galera-1'
16m Normal GaleraPodStateFetched mariadb/mariadb-galera Galera state fetched in Pod 'mariadb-galera-0'
16m Normal GaleraPodRecovered mariadb/mariadb-galera Recovered Galera sequence in Pod 'mariadb-galera-1'
16m Normal GaleraPodRecovered mariadb/mariadb-galera Recovered Galera sequence in Pod 'mariadb-galera-2'
17m Normal GaleraPodRecovered mariadb/mariadb-galera Recovered Galera sequence in Pod 'mariadb-galera-0'
17m Normal GaleraClusterBootstrap mariadb/mariadb-galera Bootstrapping Galera cluster in Pod 'mariadb-galera-2'
20m Normal GaleraClusterHealthy mariadb/mariadb-galera Galera cluster is healthy
kubectl get mariadb mariadb-galera -o jsonpath="{.status.galeraRecovery}" | jq
{
"bootstrap": {
"pod": "mariadb-galera-2",
"time": "2023-07-13T19:25:28Z"
},
"recovered": {
"mariadb-galera-0": {
"seqno": 3,
"uuid": "bf00b9c3-21a9-11ee-984f-9ba9ff0e9285"
},
"mariadb-galera-1": {
"seqno": 3,
"uuid": "bf00b9c3-21a9-11ee-984f-9ba9ff0e9285"
},
"mariadb-galera-2": {
"seqno": 3,
"uuid": "bf00b9c3-21a9-11ee-984f-9ba9ff0e9285"
}
},
"state": {
"mariadb-galera-0": {
"safeToBootstrap": false,
"seqno": -1,
"uuid": "bf00b9c3-21a9-11ee-984f-9ba9ff0e9285",
"version": "2.1"
},
"mariadb-galera-1": {
"safeToBootstrap": false,
"seqno": -1,
"uuid": "bf00b9c3-21a9-11ee-984f-9ba9ff0e9285",
"version": "2.1"
},
"mariadb-galera-2": {
"safeToBootstrap": false,
"seqno": -1,
"uuid": "bf00b9c3-21a9-11ee-984f-9ba9ff0e9285",
"version": "2.1"
}
}
}kubectl get mariadb mariadb-galera -o jsonpath="{.status.conditions[?(@.type=='GaleraReady')]}" | jq
{
"lastTransitionTime": "2023-07-13T19:27:51Z",
"message": "Galera ready",
"reason": "GaleraReady",
"status": "True",
"type": "GaleraReady"
}
kubectl get mariadb mariadb-galera
NAME READY STATUS PRIMARY POD AGE
mariadb-galera True Running mariadb-galera-0 82mkubectl get mariadb mariadb-galera -o jsonpath="{.status.conditions}" | jq
[
{
"lastTransitionTime": "2023-08-05T14:58:57Z",
"message": "Galera not ready",
"reason": "GaleraNotReady",
"status": "False",
"type": "Ready"
},
{
"lastTransitionTime": "2023-08-05T14:58:57Z",
"message": "Galera not ready",
"reason": "GaleraNotReady",
"status": "False",
"type": "GaleraReady"
},
{
"lastTransitionTime": "2023-08-03T19:21:16Z",
"message": "Galera configured",
"reason": "GaleraConfigured",
"status": "True",
"type": "GaleraConfigured"
}
]kubectl get endpoints mariadb-galera-internal -o yaml
apiVersion: v1
kind: Endpoints
metadata:
name: mariadb-internal
subsets:
- addresses:
- hostname: mariadb-1
ip: 10.255.140.181
nodeName: k8s-worker-1
targetRef:
kind: Pod
name: mariadb-1
namespace: mariadb
- hostname: mariadb-2
ip: 10.255.20.156
nodeName: k8s-worker-2
targetRef:
kind: Pod
name: mariadb-2
namespace: mariadb
- hostname: mariadb-0
ip: 10.255.214.164
nodeName: k8s-worker-0
targetRef:
kind: Pod
name: mariadb-0
namespace: mariadb
ports:
- name: sst
port: 4568
protocol: TCP
- name: ist
port: 4567
protocol: TCP
- name: mariadb
port: 3306
protocol: TCP
- name: agent
port: 5555
protocol: TCP
- name: cluster
port: 4444
protocol: TCPkubectl get events --field-selector involvedObject.name=mariadb-galera --sort-by='.lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
...
16m Warning GaleraClusterNotHealthy mariadb/mariadb-galera Galera cluster is not healthy
16m Normal GaleraPodStateFetched mariadb/mariadb-galera Galera state fetched in Pod 'mariadb-galera-2'
16m Normal GaleraPodStateFetched mariadb/mariadb-galera Galera state fetched in Pod 'mariadb-galera-1'
16m Normal GaleraPodStateFetched mariadb/mariadb-galera Galera state fetched in Pod 'mariadb-galera-0'
16m Normal GaleraPodRecovered mariadb/mariadb-galera Recovered Galera sequence in Pod 'mariadb-galera-1'
16m Normal GaleraPodRecovered mariadb/mariadb-galera Recovered Galera sequence in Pod 'mariadb-galera-2'
17m Normal GaleraPodRecovered mariadb/mariadb-galera Recovered Galera sequence in Pod 'mariadb-galera-0'
17m Normal GaleraClusterBootstrap mariadb/mariadb-galera Bootstrapping Galera cluster in Pod 'mariadb-galera-2'
20m Normal GaleraClusterHealthy mariadb/mariadb-galera Galera cluster is healthyhelm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator --set logLevel=debug
kubectl logs mariadb-enterprise-operator-546c78f4f5-gq44k
{"level":"info","ts":1691090524.4911606,"logger":"galera.health","msg":"Checking Galera cluster health","controller":"statefulset","controllerGroup":"apps","controllerKind":"StatefulSet","statefulSet":{"name":"mariadb-galera","namespace":"default"},"namespace":"default","name":"mariadb-galera","reconcileID":"098620db-4486-45cc-966a-9f3fec0d165e"}
{"level":"debug","ts":1691090524.4911761,"logger":"galera.health","msg":"StatefulSet ready replicas","controller":"statefulset","controllerGroup":"apps","controllerKind":"StatefulSet","statefulSet":{"name":"mariadb-galera","namespace":"default"},"namespace":"default","name":"mariadb-galera","reconcileID":"098620db-4486-45cc-966a-9f3fec0d165e","replicas":1}kubectl logs mariadb-galera-0 -c init
{"level":"info","ts":1691090778.5239124,"msg":"Starting init"}
{"level":"info","ts":1691090778.5305626,"msg":"Configuring Galera"}
{"level":"info","ts":1691090778.5307593,"msg":"Already initialized. Init done"}
kubectl logs mariadb-galera-0 -c agent
{"level":"info","ts":1691090779.3193653,"logger":"server","msg":"server listening","addr":":5555"}
2023/08/03 19:26:28 "POST http://mariadb-galera-0.mariadb-galera-internal.default.svc.cluster.local:5555/api/recovery HTTP/1.1" from 10.244.4.2:39162 - 200 58B in 4.112086ms
2023/08/03 19:26:28 "DELETE http://mariadb-galera-0.mariadb-galera-internal.default.svc.cluster.local:5555/api/recovery HTTP/1.1" from 10.244.4.2:39162 - 200 0B in 883.544µs
kubectl logs mariadb-galera-0 -c mariadb
2023-08-03 19:27:10 0 [Note] WSREP: Member 2.0 (mariadb-galera-0) synced with group.
2023-08-03 19:27:10 0 [Note] WSREP: Processing event queue:...100.0% (1/1 events) complete.
2023-08-03 19:27:10 0 [Note] WSREP: Shifting JOINED -> SYNCED (TO: 6)
2023-08-03 19:27:10 2 [Note] WSREP: Server mariadb-galera-0 synced with group
2023-08-03 19:27:10 2 [Note] WSREP: Server status change joined -> synced
2023-08-03 19:27:10 2 [Note] WSREP: Synchronized with group, ready for connectionskubectl get mariadb mariadb-galera -o jsonpath="{.status.galeraRecovery}" | jqkubectl get events --field-selector involvedObject.name=mariadb-galeraError writing Galera config: open /etc/mysql/mariadb.conf.d/0-galera.cnf: permission deniedapiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb-galera
spec:
securityContext:
fsGroup: 999
runAsGroup: 999
runAsNonRoot: true
runAsUser: 999Error reconciling Galera: error disabling bootstrap in Pod 0: unauthorizedkubectl auth can-i --list --as=system:serviceaccount:default:mariadb-enterprise-operator | grep tokenreview
tokenreviews.authentication.k8s.io [] [] [create]
kubectl auth can-i --list --as=system:serviceaccount:default:mariadb-galera | grep tokenreview
tokenreviews.authentication.k8s.io [] [] [create]kubectl get clusterrole system:auth-delegator
NAME CREATED AT
system:auth-delegator 2023-08-03T19:12:37Z
kubectl get clusterrolebinding | grep mariadb | grep auth-delegator
mariadb-galera:auth-delegator ClusterRole/system:auth-delegator 108m
mariadb-enterprise-operator:auth-delegator ClusterRole/system:auth-delegator 112mhelm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operatorTimeout waiting for Pod 'mariadb-galera-2' to be SyncedGalera cluster bootstrap timed out. Resetting recovery statusapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
storage:
persistentVolumeClaim:
resources:
requests:
storage: 100Mi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
storage:
s3:
bucket: backups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: tls.crtapiVersion: v1
kind: ServiceAccount
metadata:
name: mariadb-backup
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<<account_id>>:role/my-role-irsaapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
serviceAccountName: mariadb-backup
storage:
s3:
bucket: backups
prefix: mariadb
endpoint: s3.us-east-1.amazonaws.com
region: us-east-1
tls:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
schedule:
cron: "*/1 * * * *"
suspend: falseapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
maxRetention: 720h # 30 daysapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
compression: gzipapiVersion: v1
kind: Secret
type: Opaque
metadata:
name: ssec-key
stringData:
# 32-byte key encoded in base64 (use: openssl rand -base64 32)
customer-key: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=apiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
storage:
s3:
bucket: backups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: tls.crt
ssec:
customerKeySecretKeyRef:
name: ssec-key
key: customer-keyapiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb
backupRef:
name: backupapiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb
s3:
bucket: backups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: tls.crtapiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb
backupRef:
name: backup
targetRecoveryTime: 2023-12-19T09:00:00ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-from-backup
spec:
storage:
size: 1Gi
bootstrapFrom:
backupRef:
name: backup
targetRecoveryTime: 2023-12-19T09:00:00ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-from-backup
spec:
storage:
size: 1Gi
bootstrapFrom:
s3:
bucket: backups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: tls.crt
targetRecoveryTime: 2023-12-19T09:00:00ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
databases:
- db1
- db2
- db3apiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb
backupRef:
name: backup
database: db1apiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
args:
- --verboseapiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb
backupRef:
name: backup
args:
- --verboseapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
storage:
s3:
...
stagingStorage:
persistentVolumeClaim:
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
spec:
s3:
...
stagingStorage:
persistentVolumeClaim:
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
bootstrapFrom:
s3:
...
stagingStorage:
persistentVolumeClaim:
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
storage:
size: 1Gi
bootstrapFrom:
restoreJob:
args:
- --verbose
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 1GiapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
spec:
mariaDbRef:
name: mariadb
ignoreGlobalPriv: falsemariadb-dump --user=${MARIADB_USER} --password=${MARIADB_PASSWORD} --host=${MARIADB_HOST} --single-transaction --events --routines --all-databases > backup.2024-08-26T12:24:34Z.sqlmariadb-dump --user=${MARIADB_USER} --password=${MARIADB_PASSWORD} --host=${MARIADB_HOST} --single-transaction --events --routines --all-databases --skip-add-locks --ignore-table=mysql.global_priv > backup.2024-08-26T12:24:34Z.sqlapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
replicas: 3
galera:
enabled: true
storage:
size: 1Gi
bootstrapFrom:
s3:
bucket: backups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: tls.crt
targetRecoveryTime: 2024-08-26T12:24:34ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup-standalone
spec:
mariaDbRef:
name: mariadb-standalone
ignoreGlobalPriv: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
replicas: 3
galera:
enabled: true
storage:
size: 1Gi
bootstrapFrom:
backupRef:
name: backup-standaloneVolumeSnapshotsJobReadWriteOncePod access mode partially supportedPhysicalBackup Jobs schedulingmariadb-backup log copy incomplete: consider increasing innodb_log_file_sizemariadb-backup Job fails to start because the Pod cannot mount MariaDB PVC created with StorageClass providerapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
mariaDbRef:
name: mariadb-galeraapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
mariaDbRef:
name: mariadb-galera
services:
- name: rw-router
router: readwritesplit
listener:
port: 3306
monitor:
interval: 2s
cooperativeMonitoring: majority_of_all
params:
disable_master_failback: "false"
available_when_donor: "false"
disable_master_role_setting: "false"
kubernetesService:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.224apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-repl
spec:
...
mariaDbRef:
name: mariadb-repl
services:
- name: rw-router
router: readwritesplit
params:
transaction_replay: "true"
transaction_replay_attempts: "10"
transaction_replay_timeout: "5s"
max_slave_connections: "255"
max_replication_lag: "3s"
master_accept_reads: "true"
listener:
port: 3306
protocol: MariaDBProtocol
params:
connection_metadata: "tx_isolation=auto"
- name: rconn-master-router
router: readconnroute
params:
router_options: "master"
max_replication_lag: "3s"
master_accept_reads: "true"
listener:
port: 3307
- name: rconn-slave-router
router: readconnroute
params:
router_options: "slave"
max_replication_lag: "3s"
listener:
port: 3308
monitor:
interval: 2s
cooperativeMonitoring: majority_of_all
params:
auto_failover: "true"
auto_rejoin: "true"
switchover_on_low_disk_space: "true"
kubernetesService:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.214apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
maxScaleRef:
name: maxscale-galera
galera:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
servers:
- name: mariadb-0
address: mariadb-galera-0.mariadb-galera-internal.default.svc.cluster.local
- name: mariadb-1
address: mariadb-galera-1.mariadb-galera-internal.default.svc.cluster.local
- name: mariadb-2
address: mariadb-galera-2.mariadb-galera-internal.default.svc.cluster.localapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
servers:
- name: mariadb-0
address: 172.18.0.140
port: 3306
- name: mariadb-1
address: 172.18.0.141
- name: mariadb-2
address: 172.18.0.142
monitor:
name: mariadb-monitor
module: galeramon
interval: 2s
cooperativeMonitoring: majority_of_all
params:
disable_master_failback: "false"
available_when_donor: "false"
disable_master_role_setting: "false"
auth:
adminUsername: mariadb-enterprise-operator
adminPasswordSecretKeyRef:
name: maxscale
key: password
clientUsername: maxscale-client
clientPasswordSecretKeyRef:
name: maxscale
key: password
serverUsername: maxscale-server
serverPasswordSecretKeyRef:
name: maxscale
key: password
monitorUsername: maxscale-monitor
monitorPasswordSecretKeyRef:
name: maxscale
key: password
syncUsername: maxscale-sync
syncPasswordSecretKeyRef:
name: maxscale
key: passwordapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-repl
spec:
primaryServer: mariadb-repl-1kubectl patch maxscale maxscale-repl \
--type='merge' \
-p '{"spec":{"primaryServer":"mariadb-repl-1"}}'
kubectl get maxscale
NAME READY STATUS PRIMARY AGE
maxscale-repl False Switching primary to 'mariadb-repl-1' mariadb-repl-0 2m15sapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
servers:
- name: mariadb-0
address: mariadb-galera-0.mariadb-galera-internal.default.svc.cluster.local
port: 3306
protocol: MariaDBBackend
maintenance: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
config:
params:
log_info: "true"
volumeClaimTemplate:
resources:
requests:
storage: 100Mi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
auth:
generate: false
adminUsername: mariadb-enterprise-operator
adminPasswordSecretKeyRef:
name: maxscale
key: password
deleteDefaultAdmin: true
clientUsername: maxscale-client
clientPasswordSecretKeyRef:
name: maxscale
key: password
clientMaxConnections: 90
serverUsername: maxscale-server
serverPasswordSecretKeyRef:
name: maxscale
key: password
serverMaxConnections: 90
monitorUsername: maxscale-monitor
monitorPasswordSecretKeyRef:
name: maxscale
key: password
monitorMaxConnections: 90
syncUsername: maxscale-sync
syncPasswordSecretKeyRef:
name: maxscale
key: password
syncMaxConnections: 90apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
kubernetesService:
type: LoadBalancer
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.224apiVersion: v1
kind: Service
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.229
name: maxscale-galera
spec:
...
ports:
- name: admin
port: 8989
targetPort: 8989
- name: rw-router-listener
port: 3306
targetPort: 3306
selector:
app.kubernetes.io/instance: maxscale-galera
app.kubernetes.io/name: maxscale
type: LoadBalancerapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection-maxscale
spec:
maxScaleRef:
name: maxscale-galera
username: maxscale-galera-client
passwordSecretKeyRef:
name: maxscale-galera-client
key: password
secretName: conn-mxs
port: 3306apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
connection:
secretName: mxs-galera-conn
port: 3306apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
replicas: 2
monitor:
name: mariadb-monitor
module: galeramon
interval: 2s
cooperativeMonitoring: majority_of_all
params:
disable_master_failback: "false"
available_when_donor: "false"
disable_master_role_setting: "false"
config:
sync:
database: mysql
interval: 5s
timeout: 10skubectl scale maxscale maxscale-galera --replicas 3helm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator --set extraArgs={--feature-maxscale-suspend}apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
monitor:
name: mariadb-monitor
module: galeramon
interval: 2s
cooperativeMonitoring: majority_of_all
params:
disable_master_failback: "false"
available_when_donor: "false"
disable_master_role_setting: "false"
suspend: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
admin:
port: 8989
guiEnabled: true
guiKubernetesService:
type: LoadBalancer
metadata:
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: 172.18.0.231status:
conditions:
- lastTransitionTime: "2024-02-08T17:29:01Z"
message: Running
reason: MaxScaleReady
status: "True"
type: Ready
configSync:
databaseVersion: 20
maxScaleVersion: 20
listeners:
- name: rw-router-listener
state: Running
monitor:
name: galeramon-monitor
state: Running
primaryServer: mariadb-galera-1
replicas: 1
servers:
- name: mariadb-galera-0
state: Slave, Synced, Running
- name: mariadb-galera-1
state: Master, Synced, Running
- name: mariadb-galera-2
state: Slave, Synced, Running
services:
- name: rw-router
state: Startedkubectl get events --field-selector involvedObject.name=mariadb-repl-maxscale --sort-by='.lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
24s Normal MaxScalePrimaryServerChanged maxscale/mariadb-repl-maxscale MaxScale primary server changed from 'mariadb-repl-0' to 'mariadb-repl-1'helm upgrade --install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator --set logLevel=debug --set extraArgs={--log-maxscale}Failed to create directory '/var/lib/maxscale/maxscale.cnf.d': 13, Permission deniedapiVersion: apps/v1
kind: StatefulSet
metadata:
name: maxscale-galera
spec:
securityContext:
fsGroup: 999
runAsGroup: 999
runAsNonRoot: true
runAsUser: 999truePhysicalBackupVolumeSnapshots installed in the cluster.apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
storage:
volumeSnapshot:
volumeSnapshotClassName: csi-hostpath-snapclassapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
storage:
s3:
bucket: physicalbackups
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crtapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
waitForIt: true
schedule:
cron: "*/1 * * * *"
suspend: false
immediate: true
onDemand: "1"
onPrimaryChange: true apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
compression: bzip2apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: ssec-key
stringData:
# 32-byte key encoded in base64 (use: openssl rand -base64 32)
customer-key: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
storage:
s3:
bucket: physicalbackups
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
ssec:
customerKeySecretKeyRef:
name: ssec-key
key: customer-keyapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
maxRetention: 720h # 30 daysapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
target: ReplicaapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
bootstrapFrom:
backupRef:
name: physicalbackup
kind: PhysicalBackupapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
bootstrapFrom:
s3:
bucket: physicalbackups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
backupContentType: PhysicalapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
bootstrapFrom:
volumeSnapshotRef:
name: physicalbackup-20250611163352apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
bootstrapFrom:
targetRecoveryTime: 2025-06-17T08:07:00ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
timeout: 2hapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
logLevel: debugapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
args:
- "--verbose"---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
target: Replica
compression: bzip2
storage:
azureBlob:
containerName: physicalbackup
serviceURL: https://physicalbackup.blob.core.windows.net # Format is: `https://%s.blob.core.windows.net/` where `%s` is the containerName
prefix: mariadb
storageAccountName: exampleStorageAccount
storageAccountKey:
name: azurite-key
key: storageAccountKey
# Optional.
# tls:
# enabled: true
# caSecretKeyRef:
# name: azurite-certs
# key: cert.pemapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
storage:
s3:
bucket: physicalbackups
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crtapiVersion: v1
kind: ServiceAccount
metadata:
name: mariadb-backup
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<<account_id>>:role/my-role-irsaapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
serviceAccountName: mariadb-backup
storage:
s3:
bucket: physicalbackups
prefix: mariadb
endpoint: s3.us-east-1.amazonaws.com
region: us-east-1
tls:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
storage:
s3:
bucket: physicalbackups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
stagingStorage:
persistentVolumeClaim:
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
mariaDbRef:
name: mariadb
bootstrapFrom:
s3:
bucket: physicalbackups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
backupContentType: Physical
stagingStorage:
persistentVolumeClaim:
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteOnceapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
bootstrapFrom:
restoreJob:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 1GiapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
mariaDbRef:
name: mariadb
podAffinity: falsekubectl get physicalbackups
NAME COMPLETE STATUS MARIADB LAST SCHEDULED AGE
physicalbackup True Success mariadb 17s 17skubectl get physicalbackups physicalbackup -o json | jq -r '.status'
{
"conditions": [
{
"lastTransitionTime": "2025-07-14T07:01:14Z",
"message": "Success",
"reason": "JobComplete",
"status": "True",
"type": "Complete"
}
],
"lastScheduleCheckTime": "2025-07-14T07:00:00Z",
"lastScheduleTime": "2025-07-14T07:00:00Z",
"nextScheduleTime": "2025-07-15T07:00:00Z"
}kubectl get events --field-selector involvedObject.name=physicalbackup
LAST SEEN TYPE REASON OBJECT MESSAGE
116s Normal WaitForFirstConsumer persistentvolumeclaim/physicalbackup waiting for first consumer to be created before binding
116s Normal JobScheduled physicalbackup/physicalbackup Job physicalbackup-20250714140837 scheduled
116s Normal ExternalProvisioning persistentvolumeclaim/physicalbackup Waiting for a volume to be created either by the external provisioner 'rancher.io/local-path' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.
116s Normal Provisioning persistentvolumeclaim/physicalbackup External provisioner is provisioning volume for claim "default/physicalbackup"
113s Normal ProvisioningSucceeded persistentvolumeclaim/physicalbackup Successfully provisioned volume pvc-7b7c71f9-ea7e-4950-b612-2d41d7ab35b7mariadb [00] 2025-08-04 09:15:57 Was only able to copy log from 58087 to 59916, not 68968; try increasing
innodb_log_file_size
mariadb mariabackup: Stopping log copying thread.[00] 2025-08-04 09:15:57 Retrying read of log at LSN=59916apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
myCnf: |
[mariadb]
innodb_log_file_size=200M
VolumeSnapshotCurrentPosenterprise.mariadb.com/gtidVolumeSnapshotPodapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replicas: 3
replication:
enabled: truekubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-repl-0 2/2 Running 0 2d19h
mariadb-repl-1 2/2 Running 0 2d19h
mariadb-repl-2 2/2 Running 0 2d19h
mariadb-repl-metrics-56865fff65-t72kc 1/1 Running 0 2d20h
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl True Running mariadb-repl-0 ReplicasFirstPrimaryLast 2d20hkubectl get mariadb mariadb-repl -o jsonpath="{.status.replication}" | jq
{
"replicas": {
"mariadb-repl-1": {
"gtidCurrentPos": "0-10-155",
"gtidIOPos": "0-10-155",
"lastErrorTransitionTime": "2025-10-22T10:51:10Z",
"lastIOErrno": 0,
"lastIOError": "",
"lastSQLErrno": 0,
"lastSQLError": "",
"secondsBehindMaster": 0,
"slaveIORunning": true,
"slaveSQLRunning": true
},
"mariadb-repl-2": {
"gtidCurrentPos": "0-10-155",
"gtidIOPos": "0-10-155",
"lastErrorTransitionTime": "2025-10-22T10:47:29Z",
"lastIOErrno": 0,
"lastIOError": "",
"lastSQLErrno": 0,
"lastSQLError": "",
"secondsBehindMaster": 0,
"slaveIORunning": true,
"slaveSQLRunning": true
}
},
"roles": {
"mariadb-repl-0": "Primary",
"mariadb-repl-1": "Replica",
"mariadb-repl-2": "Replica"
}
}apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replicas: 3
replication:
enabled: true
gtidStrictMode: true
semiSyncEnabled: true
semiSyncAckTimeout: 10s
semiSyncWaitPoint: AfterCommit
syncBinlog: 1
standaloneProbes: falseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replicas: 3
replication:
enabled: true
replica:
replPasswordSecretKeyRef:
name: mariadb
key: password
gtid: CurrentPos
connectionRetrySeconds: 10
maxLagSeconds: 0
syncTimeout: 10sapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replicas: 3
replication:
enabled: true
primary:
podIndex: 1kubectl patch mariadb mariadb-repl \
--type='merge' \
-p '{"spec":{"replication":{"primary":{"podIndex":1}}}}'kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Switching primary to 'mariadb-repl-1' mariadb-repl-0 ReplicasFirstPrimaryLast 3d2hapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replicas: 3
replication:
enabled: true
primary:
autoFailover: true
autoFailoverDelay: 0skubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl True Running mariadb-repl-0 ReplicasFirstPrimaryLast 3d2h
kubectl delete pod mariadb-repl-0
pod "mariadb-repl-0" deleted
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Switching primary to 'mariadb-repl-1' mariadb-repl-0 ReplicasFirstPrimaryLast 3d2h
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl True Running mariadb-repl-1 ReplicasFirstPrimaryLast 3d2hapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup-tpl
spec:
mariaDbRef:
name: mariadb-repl
waitForIt: false
schedule:
suspend: true
target: PreferReplica
storage:
s3:
bucket: scaleout
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
timeout: 1h
podAffinity: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup-tpl
spec:
mariaDbRef:
name: mariadb-repl
waitForIt: false
schedule:
suspend: true
target: PreferReplica
storage:
volumeSnapshot:
volumeSnapshotClassName: csi-hostpath-snapclassapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replication:
enabled: true
replica:
bootstrapFrom:
physicalBackupTemplateRef:
name: physicalbackup-tplapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replicas: 4
replication:
enabled: true
replica:
bootstrapFrom:
physicalBackupTemplateRef:
name: physicalbackup-tplkubectl scale mariadb mariadb-repl --replicas=4kubectl scale mariadb mariadb-repl --replicas=4
mariadb.enterprise.mariadb.com/mariadb-repl scaled
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Scaling out mariadb-repl-1 ReplicasFirstPrimaryLast 3d5h
kubectl get physicalbackups
NAME COMPLETE STATUS MARIADB LAST SCHEDULED AGE
mariadb-repl-pb-scaleout True Success mariadb-repl 14s 14s
physicalbackup-tpl False Suspended mariadb-repl 3d8h
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-repl-0 2/2 Running 0 137m
mariadb-repl-1 2/2 Running 0 3d5h
mariadb-repl-2 2/2 Running 0 3d5h
mariadb-repl-3 2/2 Running 0 40s
mariadb-repl-metrics-56865fff65-t72kc 1/1 Running 0 3d5h
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl True Running mariadb-repl-1 ReplicasFirstPrimaryLast 3d5hapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
replication:
enabled: true
replica:
bootstrapFrom:
physicalBackupTemplateRef:
name: physicalbackup-tpl
recovery:
enabled: true
errorDurationThreshold: 5mPRIMARY=$(kubectl get mariadb mariadb-repl -o jsonpath="{.status.currentPrimary}")
echo "Purging binary logs in primary $PRIMARY"
kubectl exec -it $PRIMARY -c mariadb -- mariadb -u root -p'MariaDB11!' --ssl=false -e "FLUSH LOGS;"
kubectl exec -it $PRIMARY -c mariadb -- mariadb -u root -p'MariaDB11!' --ssl=false -e "PURGE BINARY LOGS BEFORE NOW();"
kubectl exec -it $PRIMARY -c mariadb -- mariadb -u root -p'MariaDB11!' --ssl=false -e "SHOW BINARY LOGS;"REPLICA=$(kubectl get mariadb mariadb-repl -o jsonpath='{.status.replication.replicas}' | jq -r 'keys[]' | head -n1)
echo "Deleting PVC and restarting replica $REPLICA"
kubectl delete pvc storage-$REPLICA --wait=false
kubectl delete pod $REPLICA --wait=false kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Recovering replicas mariadb-repl-1 ReplicasFirstPrimaryLast 3d6h
kubectl get physicalbackups
NAME COMPLETE STATUS MARIADB LAST SCHEDULED AGE
mariadb-repl-pb-recovery True Success mariadb-repl 31s 31s
physicalbackup-tpl False Suspended mariadb-repl 3d9h
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-repl-0 0/2 PodInitializing 0 22s
mariadb-repl-0-pb-init-qn79f 0/1 Completed 0 8s
mariadb-repl-1 2/2 Running 0 3d6h
mariadb-repl-2 2/2 Running 0 3d6h
mariadb-repl-metrics-56865fff65-t72kc 1/1 Running 0 3d6h
mariadb-repl-pb-recovery-2025102020270r98zr 0/1 Completed 0 31s
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl True Running mariadb-repl-1 ReplicasFirstPrimaryLast 3d6hkubectl get mariadb mariadb-repl -o jsonpath="{.status.replication}" | jq
{
"replicas": {
"mariadb-repl-1": {
"gtidCurrentPos": "0-10-155",
"gtidIOPos": "0-10-155",
"lastErrorTransitionTime": "2025-10-22T10:51:10Z",
"lastIOErrno": 0,
"lastIOError": "",
"lastSQLErrno": 0,
"lastSQLError": "",
"secondsBehindMaster": 0,
"slaveIORunning": true,
"slaveSQLRunning": true
},
"mariadb-repl-2": {
"gtidCurrentPos": "0-10-155",
"gtidIOPos": "0-10-155",
"lastErrorTransitionTime": "2025-10-22T10:47:29Z",
"lastIOErrno": 0,
"lastIOError": "",
"lastSQLErrno": 0,
"lastSQLError": "",
"secondsBehindMaster": 0,
"slaveIORunning": true,
"slaveSQLRunning": true
}
},
"roles": {
"mariadb-repl-0": "Primary",
"mariadb-repl-1": "Replica",
"mariadb-repl-2": "Replica"
}
}kubectl get mariadb mariadb-repl -o jsonpath="{.status.conditions}" | jq
[
{
"lastTransitionTime": "2025-10-20T20:28:09Z",
"message": "Running",
"reason": "StatefulSetReady",
"status": "True",
"type": "Ready"
},
{
"lastTransitionTime": "2025-10-17T14:17:43Z",
"message": "Updated",
"reason": "Updated",
"status": "True",
"type": "Updated"
},
{
"lastTransitionTime": "2025-10-17T14:17:58Z",
"message": "Replication configured",
"reason": "ReplicationConfigured",
"status": "True",
"type": "ReplicationConfigured"
},
{
"lastTransitionTime": "2025-10-20T17:14:38Z",
"message": "Switchover complete",
"reason": "SwitchPrimary",
"status": "True",
"type": "PrimarySwitched"
},
{
"lastTransitionTime": "2025-10-20T19:31:29Z",
"message": "Scaled out",
"reason": "ScaledOut",
"status": "True",
"type": "ScaledOut"
},
{
"lastTransitionTime": "2025-10-20T20:27:41Z",
"message": "Replica recovered",
"reason": "ReplicaRecovered",
"status": "True",
"type": "ReplicaRecovered"
}
]kubectl get events --field-selector involvedObject.name=mariadb-repl --sort-by='.lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
17s Normal PrimaryLock mariadb/mariadb-repl Locking primary with read lock
17s Normal PrimaryReadonly mariadb/mariadb-repl Enabling readonly mode in primary
17s Normal ReplicaSync mariadb/mariadb-repl Waiting for replicas to be synced with primary
17s Normal PrimaryNew mariadb/mariadb-repl Configuring new primary at index '0'
7s Normal ReplicaConn mariadb/mariadb-repl Connecting replicas to new primary at '0'
7s Normal PrimaryToReplica mariadb/mariadb-repl Unlocking primary '1' and configuring it to be a replica. New primary at '0'
7s Normal PrimaryLock mariadb/mariadb-repl Unlocking primary
7s Normal PrimarySwitched mariadb/mariadb-repl Primary switched from index '1' to index '0'Error 1236: Got fatal error from master when reading data from binary log.2025-10-27 15:17:11 error : [mariadbmon] 'mariadb-repl-1' is not a valid demotion target for switchover: it does not have a 'gtid_binlog_pos'.error creating Job: Job.batch \"mariadb-repl-operator-test-new-physicalbackup-scale-out-20251208221943\"
is invalid: spec.template.labels:
Invalid value: \"mariadb-repl-operator-test-new-physicalbackup-scale-out-20251208221943\":
must be no more than 63 characterscompression: Algorithm to be used for compressing binary logs. It is disabled by default. See compression.restoreJob: Compute resources and metadata configuration for the restoration job. To reduce RTO, it is recommended to properly tune compute resources.apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup-daily
spec:
mariaDbRef:
name: mariadb-repl
schedule:
cron: "0 0 * * *"
suspend: false
immediate: true
compression: bzip2
maxRetention: 720h
storage:
s3:
bucket: physicalbackups
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crtapiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
physicalBackupRef:
name: physicalbackup-daily
storage:
s3:
bucket: binlogs
prefix: mariadb
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
compression: gzip
archiveTimeout: 1h
archiveInterval: 1m
maxParallel: 4
maxRetention: 720h # 30 days
strictMode: falseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
storage:
size: 1Gi
replicas: 3
replication:
enabled: true
# sidecar agent will archive binary logs to the configured storage.
pointInTimeRecoveryRef:
name: pitrapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
storage:
size: 1Gi
replicas: 3
replication:
enabled: true
# bootstrap the instance from PITR: restore closest physical backup and replay binary logs up to targetRecoveryTime.
bootstrapFrom:
pointInTimeRecoveryRef:
name: pitr
targetRecoveryTime: 2026-02-20T18:00:04ZapiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
schedule:
onPrimaryChange: true apiVersion: enterprise.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
name: physicalbackup
spec:
schedule:
cron: "0 0 * * *"
onDemand: "1"apiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
archiveTimeout: 1h
archiveInterval: 1mkubectl logs -l enterprise.mariadb.com/role=primary -c agent --tail 20
{"level":"info","ts":1772208238.0152433,"logger":"binlog-archival","msg":"Archiving binary logs"}
{"level":"info","ts":1772208238.437027,"logger":"binlog-archival.uploader","msg":"Uploading binary log","binlog":"mariadb-repl-bin.000003","object":"server-10/mariadb-repl-bin.000003.gz","start-time":"2026-02-27T16:03:58Z"}
{"level":"info","ts":1772208238.4371545,"logger":"binlog-archival.uploader","msg":"Compressing binary log","binlog":"mariadb-repl-bin.000003","object":"server-10/mariadb-repl-bin.000003.gz","start-time":"2026-02-27T16:03:58Z"}
{"level":"info","ts":1772208260.8291402,"logger":"binlog-archival.uploader","msg":"Binary log uploaded","binlog":"mariadb-repl-bin.000003","object":"server-10/mariadb-repl-bin.000003.gz","start-time":"2026-02-27T16:03:58Z","total-time":"22.392211226s"}
{"level":"info","ts":1772208260.8621385,"logger":"binlog-archival","msg":"Binary log mariadb-repl-bin.000003 archived"}
{"level":"info","ts":1772208260.8622391,"logger":"binlog-archival","msg":"Binlog archival done"}
{"level":"info","ts":1772208261.2485638,"logger":"binlog-archival","msg":"Purging binary logs","max-retention":"720h0m0s"}
{"level":"info","ts":1772208261.2599053,"logger":"binlog-archival","msg":"Binary logs purged","max-retention":"720h0m0s"}
{"level":"info","ts":1772208268.0053742,"logger":"binlog-archival","msg":"Archiving binary logs"}
{"level":"info","ts":1772208268.0907545,"logger":"binlog-archival.uploader","msg":"Uploading binary log","binlog":"mariadb-repl-bin.000004","object":"server-10/mariadb-repl-bin.000004.gz","start-time":"2026-02-27T16:04:28Z"}
{"level":"info","ts":1772208268.0908031,"logger":"binlog-archival.uploader","msg":"Compressing binary log","binlog":"mariadb-repl-bin.000004","object":"server-10/mariadb-repl-bin.000004.gz","start-time":"2026-02-27T16:04:28Z"}
{"level":"info","ts":1772208279.7613757,"logger":"binlog-archival.uploader","msg":"Binary log uploaded","binlog":"mariadb-repl-bin.000004","object":"server-10/mariadb-repl-bin.000004.gz","start-time":"2026-02-27T16:04:28Z","total-time":"11.670631252s"}
{"level":"info","ts":1772208279.7794006,"logger":"binlog-archival","msg":"Binary log mariadb-repl-bin.000004 archived"}
{"level":"info","ts":1772208279.7794523,"logger":"binlog-archival","msg":"Binlog archival done"}
kubectl get events --field-selector involvedObject.name=mariadb-repl
LAST SEEN TYPE REASON OBJECT MESSAGE
4m3s Normal BinlogArchived MariaDB/mariadb-repl Binary log mariadb-repl-bin.000001 archived
2m36s Normal BinlogArchived MariaDB/mariadb-repl Binary log mariadb-repl-bin.000002 archived
2m11s Normal BinlogArchived MariaDB/mariadb-repl Binary log mariadb-repl-bin.000003 archived
112s Normal BinlogArchived MariaDB/mariadb-repl Binary log mariadb-repl-bin.000004 archived
kubectl get mariadb mariadb-repl -o jsonpath='{.status.pointInTimeRecovery}' | jq
{
"lastArchivedBinaryLog": "mariadb-repl-bin.000004",
"lastArchivedGtid": "0-10-1559",
"lastArchivedPosition": 268506819,
"lastArchivedTime": "2026-02-27T16:04:15Z",
"serverId": 10,
"storageReadyForArchival": true
}apiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
compression: gzipapiVersion: v1
kind: Secret
type: Opaque
metadata:
name: ssec-key
stringData:
# 32-byte key encoded in base64 (use: openssl rand -base64 32)
customer-key: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=apiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
physicalBackupRef:
name: physicalbackup-daily
storage:
s3:
bucket: binlogs
endpoint: minio.minio.svc.cluster.local:9000
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crt
ssec:
customerKeySecretKeyRef:
name: ssec-key
key: customer-keyapiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
maxParallel: 4apiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
maxRetention: 720h # 30 daysapiVersion: v1
binlogs:
server-10:
...
- binlogFilename: mariadb-repl-bin.000003
binlogVersion: 4
firstGtid: 0-10-527
firstTime: "2026-02-27T16:03:22Z"
lastGtid: 0-10-1041
lastTime: "2026-02-27T16:03:50Z"
logPosition: 268493636
previousGtids:
- 0-10-526
rotateEvent: true
serverId: 10
serverVersion: 11.8.5-2-MariaDB-enterprise-log
stopEvent: false
- binlogFilename: mariadb-repl-bin.000004
binlogVersion: 4
firstGtid: 0-10-1042
firstTime: "2026-02-27T16:03:50Z"
lastGtid: 0-10-1559
lastTime: "2026-02-27T16:04:15Z"
logPosition: 268506819
previousGtids:
- 0-10-1041
rotateEvent: true
serverId: 10
serverVersion: 11.8.5-2-MariaDB-enterprise-log
stopEvent: falsekubectl get pitr
NAME PHYSICAL BACKUP LAST RECOVERABLE TIME STRICT MODE AGE
pitr physicalbackup-daily 2026-02-27T20:10:42Z true 43hkubectl get pitr
NAME PHYSICAL BACKUP LAST RECOVERABLE TIME STRICT MODE AGE
pitr physicalbackup-daily 2026-02-27T20:10:42Z true 43hapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
storage:
size: 1Gi
replicas: 3
replication:
enabled: true
# bootstrap the instance from PITR: restore closest physical backup and replay binary logs up to targetRecoveryTime.
bootstrapFrom:
pointInTimeRecoveryRef:
name: pitr
targetRecoveryTime: 2026-02-20T18:00:04Z
restoreJob:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 1Gi
logLevel: debugkubectl apply -f mariadb_replication_pitr_s3.yaml
mariadb.enterprise.mariadb.com/mariadb-repl created
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Initializing mariadb-repl-0 ReplicasFirstPrimaryLast 40s
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-repl-0 2/2 Running 0 36s
mariadb-repl-0-pb-init-gp4gl 0/1 Completed 0 45s
mariadb-repl-1 1/2 Running 0 15s
mariadb-repl-1-pb-init-z44d7 0/1 Completed 0 27s
mariadb-repl-2-pb-init-qmkcv 0/1 Completed 0 8s
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Replaying binlogs mariadb-repl-0 ReplicasFirstPrimaryLast 93s
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-repl-0 2/2 Running 0 84s
mariadb-repl-1 2/2 Running 0 58s
mariadb-repl-2 2/2 Running 0 38s
mariadb-repl-pitr-pj6fr 0/1 Init:0/1 0 8s
kubectl logs mariadb-repl-pitr-pj6fr -c mariadb-enterprise-operator
{"level":"info","ts":1772294432.9904623,"msg":"Starting point-in-time recovery"}
{"level":"info","ts":1772294432.9907954,"msg":"Getting binlog index from object storage"}
{"level":"info","ts":1772294432.9951825,"msg":"Building binlog timeline"}
{"level":"info","ts":1772294432.9952044,"logger":"binlog-timeline","msg":"Building binlog timeline","num-binlogs":0,"start-gtid":"0-10-4","target-time":"2026-02-27T21:10:42+01:00","strict-mode":false,"server":"server-10"}
{"level":"info","ts":1772294432.9952517,"msg":"Got binlog timeline","path":["server-10/mariadb-repl-bin.000002","server-10/mariadb-repl-bin.000003","server-10/mariadb-repl-bin.000004","server-10/mariadb-repl-bin.000005"]}
{"level":"info","ts":1772294432.9952574,"msg":"Pulling binlogs into staging area","staging-path":"/binlogs","compression":"gzip"}
{"level":"info","ts":1772294432.9952772,"logger":"storage","msg":"Pulling binlog","binlog":"server-10/mariadb-repl-bin.000005","start-time":"2026-02-28T16:00:32Z"}
{"level":"info","ts":1772294432.9967375,"logger":"storage","msg":"Decompressing binlog","binlog":"server-10/mariadb-repl-bin.000005","start-time":"2026-02-28T16:00:32Z","compressed-file":"server-10/mariadb-repl-bin.000005.gz","decompressed-file":"/binlogs/server-10/mariadb-repl-bin.000005","compression":"gzip"}
{"level":"info","ts":1772294437.3718772,"msg":"Binlogs pulled into staging area","staging-path":"/binlogs","compression":"gzip"}
{"level":"info","ts":1772294437.3719199,"msg":"Writing target file","file-path":"/binlogs/0-binlog-target.txt"}kubectl get mariadb mariadb-repl -o jsonpath='{.status.conditions}' | jq
[
{
"lastTransitionTime": "2026-03-01T12:15:06Z",
"message": "Initialized",
"reason": "Initialized",
"status": "True",
"type": "Initialized"
},
{
"lastTransitionTime": "2026-03-01T12:15:06Z",
"message": "Restored physical backup",
"reason": "RestorePhysicalBackup",
"status": "True",
"type": "BackupRestored"
},
{
"lastTransitionTime": "2026-03-01T12:15:06Z",
"message": "Replication configured",
"reason": "ReplicationConfigured",
"status": "True",
"type": "ReplicationConfigured"
},
{
"lastTransitionTime": "2026-03-01T12:16:40Z",
"message": "Replayed binlogs",
"reason": "ReplayBinlogs",
"status": "True",
"type": "BinlogsReplayed"
},
]apiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
strictMode: truekubectl get pitr
NAME PHYSICAL BACKUP LAST RECOVERABLE TIME STRICT MODE AGE
pitr physicalbackup-daily 2026-02-27T20:10:42Z true 43hapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
storage:
size: 1Gi
replicas: 3
replication:
enabled: true
bootstrapFrom:
pointInTimeRecoveryRef:
name: pitr
targetRecoveryTime: 2026-02-28T20:10:42Zkubectl get events --field-selector involvedObject.name=mariadb-repl
LAST SEEN TYPE REASON OBJECT MESSAGE
41s Warning MariaDBInitError mariadb/mariadb-repl Unable to init MariaDB: target recovery time 2026-02-28 21:10:42 +0100 CET is after latest recoverable time 2026-02-27 20:10:42 +0000 UTC
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Init error: target recovery time 2026-02-28 21:10:42 +0100 CET is after latest recoverable time 2026-02-27 20:10:42 +0000 UTC mariadb-repl-0 ReplicasFirstPrimaryLast 65skubectl get pitr
NAME PHYSICAL BACKUP LAST RECOVERABLE TIME STRICT MODE AGE
pitr physicalbackup-daily 2026-02-27T20:10:42Z false 43hkubectl get events --field-selector involvedObject.name=mariadb-repl
LAST SEEN TYPE REASON OBJECT MESSAGE
12s Warning BinlogTimelineInvalid mariadb/mariadb-repl Invalid binary log timeline: error getting binlog timeline between GTID 0-10-4 and target time 2026-02-28T21:10:42+01:00: timeline did not reach target time: 2026-02-28T21:10:42+01:00, last recoverable time: 2026-02-27T21:10:42+01:00
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Error replaying binlogs: Invalid binary log timeline: error getting binlog timeline between GTID 0-10-4 and target time 2026-02-28T21:10:42+01:00: timeline did not reach target time: 2026-02-28T21:10:42+01:00, last recoverable time: 2026-02-27T21:10:42+01:00 mariadb-repl-0 ReplicasFirstPrimaryLast 3m28sapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-repl
spec:
bootstrapFrom:
stagingStorage:
persistentVolumeClaim:
storageClassName: my-storage-class
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteOncekubectl get mariadb mariadb-repl -o jsonpath='{.status.pointInTimeRecovery}' | jq
{
"lastArchivedBinaryLog": "mariadb-repl-bin.000001",
"lastArchivedPosition": 358,
"lastArchivedTime": "2026-03-02T11:14:00Z",
"serverId": 10,
"storageReadyForArchival": true
}kubectl get mariadb mariadb-repl -o jsonpath="{.status.conditions}" | jq
[
{
"lastTransitionTime": "2026-03-02T11:33:58Z",
"message": "Archived binlogs",
"reason": "ArchiveBinlogs",
"status": "True",
"type": "BinlogsArchived"
},
{
"lastTransitionTime": "2026-03-01T12:16:40Z",
"message": "Replayed binlogs",
"reason": "ReplayBinlogs",
"status": "True",
"type": "BinlogsReplayed"
},
]kubectl get events --field-selector involvedObject.name=mariadb-repl --sort-by='.lastTimestamp'
24m Warning BinlogArchivalError mariadb/mariadb-repl Error archiving binary logs: 1 error occurred:...
23m Normal BinlogArchived mariadb/mariadb-repl Binary log mariadb-repl-bin.000001 archived
41s Warning MariaDBInitError mariadb/mariadb-repl Unable to init MariaDB: target recovery time 2026-02-28 21:10:42 +0100 CET is after latest recoverable time 2026-02-27 20:10:42 +0000 UTC
12s Warning BinlogTimelineInvalid mariadb/mariadb-repl Invalid binary log timeline: error getting binlog timeline between GTID 0-10-4 and target time 2026-02-28T21:10:42+01:00: timeline did not reach target time: 2026-02-28T21:10:42+01:00, last recoverable time: 2026-02-27T21:10:42+01:00kubectl get mariadb mariadb-repl -o jsonpath="{.status}" | jq
{
"conditions": [
{
"lastTransitionTime": "2026-03-02T11:14:58Z",
"message": "Error archiving binlogs: 1 error occurred:\n\t* binary log storage is not ready for archival. Archival must start from a clean state\n\n",
"reason": "ArchiveBinlogsError",
"status": "False",
"type": "Ready"
},
{
"lastTransitionTime": "2026-03-02T11:14:58Z",
"message": "Error archiving binlogs: 1 error occurred:\n\t* binary log storage is not ready for archival. Archival must start from a clean state\n\n",
"reason": "ArchiveBinlogsError",
"status": "False",
"type": "BinlogsArchived"
}
],
}apiVersion: enterprise.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
name: pitr
spec:
physicalBackupRef:
name: physicalbackup-daily
storage:
s3:
bucket: binlogs
prefix: mariadb-v2 # previously it was "mariadb"
endpoint: minio.minio.svc.cluster.local:9000
region: us-east-1
accessKeyIdSecretKeyRef:
name: minio
key: access-key-id
secretAccessKeySecretKeyRef:
name: minio
key: secret-access-key
tls:
enabled: true
caSecretKeyRef:
name: minio-ca
key: ca.crtkubectl get pitr
NAME PHYSICAL BACKUP LAST RECOVERABLE TIME STRICT MODE AGE
pitr physicalbackup-daily 2026-02-27T20:10:42Z true 43h
kubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Init error: target recovery time 2026-02-28 21:10:42 +0100 CET is after latest recoverable time 2026-02-27 20:10:42 +0000 UTC mariadb-repl-0 ReplicasFirstPrimaryLast 65sapiVersion: v1
binlogs:
server-10:
...
- binlogFilename: mariadb-repl-bin.000003
binlogVersion: 4
firstGtid: 0-10-527
firstTime: "2026-02-27T16:03:22Z"
lastGtid: 0-10-1041
lastTime: "2026-02-27T16:03:50Z"
logPosition: 268493636
previousGtids:
- 0-10-526
rotateEvent: true
serverId: 10
serverVersion: 11.8.5-2-MariaDB-enterprise-log
stopEvent: false
- binlogFilename: mariadb-repl-bin.000004
binlogVersion: 4
firstGtid: 0-10-1042
firstTime: "2026-02-27T16:03:50Z"
lastGtid: 0-10-1559
lastTime: "2026-02-27T16:04:15Z"
logPosition: 268506819
previousGtids:
- 0-10-1041
rotateEvent: true
serverId: 10
serverVersion: 11.8.5-2-MariaDB-enterprise-log
stopEvent: falsekubectl get mariadb
NAME READY STATUS PRIMARY UPDATES AGE
mariadb-repl False Error replaying binlogs: Invalid binary log timeline: error getting binlog timeline between GTID 0-10-4 and target time 2026-02-28T21:10:42+01:00: timeline did not reach target time: 2026-02-28T21:10:42+01:00, last recoverable time: 2026-02-27T16:04:15Z mariadb-repl-0 ReplicasFirstPrimaryLast 3m28sGuide to securing database traffic with TLS/SSL certificates, covering internal communication between nodes and external client connections.
MariaDB configurationMaxScale configurationMariaDB certificate specificationMaxScale certificate specificationUsersConnectionsSecret<mariadb-name>-client-certdefaultSecretmariadb-galera-clientmariadb-galera-caapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tls:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tls:
enabled: true
required: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tls:
enabled: falseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
mariaDbRef:
name: mariadb-galera
tls:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
mariaDbRef:
name: mariadb-galera
tls:
enabled: falseapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
tls:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale
spec:
...
tls:
enabled: trueapiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: root-ca
namespace: default
spec:
duration: 52596h # 6 years
commonName: root-ca
usages:
- digital signature
- key encipherment
- cert sign
issuerRef:
name: selfsigned
kind: ClusterIssuer
isCA: true
privateKey:
encoding: PKCS1
algorithm: ECDSA
size: 256
secretTemplate:
labels:
enterprise.mariadb.com/watch: ""
secretName: root-ca
revisionHistoryLimit: 10
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: root-ca
spec:
ca:
secretName: root-caapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tls:
enabled: true
serverCertIssuerRef:
name: root-ca
kind: ClusterIssuer
clientCertIssuerRef:
name: root-ca
kind: ClusterIssuerapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
tls:
enabled: true
adminCertIssuerRef:
name: root-ca
kind: ClusterIssuer
listenerCertIssuerRef:
name: root-ca
kind: ClusterIssuerapiVersion: v1
kind: Secret
type: Opaque
metadata:
name: mariadb-galera-server-ca
labels:
enterprise.mariadb.com/watch: ""
data:
ca.crt:
-----BEGIN CERTIFICATE-----
<public-key>
-----END CERTIFICATE-----
ca.key:
-----BEGIN EC PRIVATE KEY-----
<private-key>
-----END EC PRIVATE KEY-----apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: mariadb-galera-server-tls
labels:
enterprise.mariadb.com/watch: ""
data:
tls.crt:
-----BEGIN CERTIFICATE-----
<public-key>
-----END CERTIFICATE-----
tls.key:
-----BEGIN EC PRIVATE KEY-----
<private-key>
-----END EC PRIVATE KEY-----apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tls:
enabled: true
serverCASecretRef:
name: mariadb-server-ca
serverCertSecretRef:
name: mariadb-galera-server-tls
clientCASecretRef:
name: mariadb-client-ca
clientCertSecretRef:
name: mariadb-galera-client-tlsapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
tls:
enabled: true
adminCASecretRef:
name: maxscale-admin-ca
adminCertSecretRef:
name: maxscale-galera-admin-tls
listenerCASecretRef:
name: maxscale-listener-ca
listenerCertSecretRef:
name: maxscale-galera-listener-tls
serverCASecretRef:
name: mariadb-galera-ca-bundle
serverCertSecretRef:
name: mariadb-galera-client-tlsapiVersion: v1
kind: Secret
type: Opaque
metadata:
name: mariadb-ca
labels:
enterprise.mariadb.com/watch: ""
data:
ca.crt:
-----BEGIN CERTIFICATE-----
<public-key>
-----END CERTIFICATE-----
ca.key:
-----BEGIN EC PRIVATE KEY-----
<private-key>
-----END EC PRIVATE KEY-----apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
...
tls:
enabled: true
serverCASecretRef:
name: mariadb-server-ca
clientCASecretRef:
name: mariadb-client-caapiVersion: v1
kind: Secret
type: Opaque
metadata:
name: custom-trust
labels:
enterprise.mariadb.com/watch: ""
data:
ca.crt:
-----BEGIN CERTIFICATE-----
<my-org-root-ca>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<root-ca>
-----END CERTIFICATE-----apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
tls:
enabled: true
adminCASecretRef:
name: custom-trust
adminCertIssuerRef:
name: my-org-intermediate-ca
kind: ClusterIssuer
listenerCASecretRef:
name: custom-trust
listenerCertIssuerRef:
name: intermediate-ca
kind: ClusterIssuerapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
versions:
- TLSv1.3
- TLSv1.2
- TLSv1.1
- TLSv1.0apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
...
tls:
adminVersions:
- TLSv13
- TLSv12
- TLSv11
- TLSv10
serverVersions:
- TLSv13
- TLSv12
- TLSv11
- TLSv10apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
enabled: true
required: true
serverCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 720h # 1 month
clientCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 720h # 1 monthapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
tls:
enabled: true
adminCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 1h # 1 month
listenerCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 720h # 1 monthapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
enabled: true
required: true
serverCertIssuerRef:
name: root-ca
kind: ClusterIssuer
serverCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 720h # 1 month
clientCertIssuerRef:
name: root-ca
kind: ClusterIssuer
clientCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 720h # 1 monthapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
tls:
enabled: true
adminCertIssuerRef:
name: root-ca
kind: ClusterIssuer
adminCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 1h # 1 month
listenerCertIssuerRef:
name: root-ca
kind: ClusterIssuer
listenerCertConfig:
caLifetime: 8766h # 1 year
certLifetime: 720h # 1 monthapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
enabled: true
required: true
serverCertConfig:
privateKeyAlgorithm: RSA
privateKeySize: 2048
clientCertConfig:
privateKeyAlgorithm: RSA
privateKeySize: 2048apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
tls:
enabled: true
adminCertConfig:
privateKeyAlgorithm: RSA
privateKeySize: 2048
listenerCertConfig:
privateKeyAlgorithm: RSA
privateKeySize: 2048apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
enabled: true
required: true
serverCertIssuerRef:
name: root-ca
kind: ClusterIssuer
serverCertConfig:
privateKeyAlgorithm: ECDSA
privateKeySize: 256
clientCertIssuerRef:
name: root-ca
kind: ClusterIssuer
clientCertConfig:
privateKeyAlgorithm: ECDSA
privateKeySize: 256apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
tls:
enabled: true
adminCertIssuerRef:
name: root-ca
kind: ClusterIssuer
adminCertConfig:
privateKeyAlgorithm: ECDSA
privateKeySize: 256
listenerCertIssuerRef:
name: root-ca
kind: ClusterIssuer
listenerCertConfig:
privateKeyAlgorithm: ECDSA
privateKeySize: 256kubectl get mariadb mariadb-galera -o jsonpath="{.status.tls}" | jq
{
"caBundle": [
{
"issuer": "CN=mariadb-galera-ca",
"notAfter": "2028-01-20T14:26:50Z",
"notBefore": "2025-01-20T13:26:50Z",
"subject": "CN=mariadb-galera-ca"
}
],
"clientCert": {
"issuer": "CN=mariadb-galera-ca",
"notAfter": "2025-04-20T14:26:50Z",
"notBefore": "2025-01-20T13:26:50Z",
"subject": "CN=mariadb-galera-client"
},
"serverCert": {
"issuer": "CN=mariadb-galera-ca",
"notAfter": "2025-04-20T14:26:50Z",
"notBefore": "2025-01-20T13:26:50Z",
"subject": "CN=mariadb-galera.default.svc.cluster.local"
}
}kubectl get maxscale maxscale-galera -o jsonpath="{.status.tls}" | jq
{
"adminCert": {
"issuer": "CN=maxscale-galera-ca",
"notAfter": "2025-04-20T14:33:09Z",
"notBefore": "2025-01-20T13:33:09Z",
"subject": "CN=maxscale-galera.default.svc.cluster.local"
},
"caBundle": [
{
"issuer": "CN=maxscale-galera-ca",
"notAfter": "2028-01-20T14:33:09Z",
"notBefore": "2025-01-20T13:33:09Z",
"subject": "CN=maxscale-galera-ca"
},
{
"issuer": "CN=mariadb-galera-ca",
"notAfter": "2028-01-20T14:28:46Z",
"notBefore": "2025-01-20T13:28:46Z",
"subject": "CN=mariadb-galera-ca"
}
],
"listenerCert": {
"issuer": "CN=maxscale-galera-ca",
"notAfter": "2025-04-20T14:33:09Z",
"notBefore": "2025-01-20T13:33:09Z",
"subject": "CN=maxscale-galera.default.svc.cluster.local"
},
"serverCert": {
"issuer": "CN=mariadb-galera-ca",
"notAfter": "2025-04-20T14:28:46Z",
"notBefore": "2025-01-20T13:28:46Z",
"subject": "CN=mariadb-galera-client"
}
}apiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user
spec:
...
require:
x509: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: user
spec:
...
require:
issuer: "/CN=mariadb-galera-ca"
subject: "/CN=mariadb-galera-client"apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
enabled: true
galeraServerSSLMode: SERVER_X509apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
tls:
enabled: true
galeraSSTEnabled: true
galeraClientSSLMode: VERIFY_IDENTITYapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb-galera
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
storage:
size: 1Gi
replicas: 3
galera:
enabled: true
tls:
enabled: true
required: true
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale-galera
spec:
replicas: 2
mariaDbRef:
name: mariadb-galera
tls:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: User
metadata:
name: app
namespace: app
spec:
mariaDbRef:
name: mariadb-galera
namespace: default
require:
issuer: "/CN=mariadb-galera-ca"
subject: "/CN=mariadb-galera-client"
host: "%"
---
apiVersion: enterprise.mariadb.com/v1alpha1
kind: Grant
metadata:
name: grant-app
namespace: app
spec:
mariaDbRef:
name: mariadb-galera
namespace: default
privileges:
- "ALL PRIVILEGES"
database: "*"
table: "*"
username: app
host: "%"apiVersion: batch/v1
kind: CronJob
metadata:
name: mariadb-client
namespace: app
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: mariadb-client
image: mariadb:11.4.4
command:
- bash
args:
- -c
- >
mariadb -u app -h mariadb-galera-primary.default.svc.cluster.local
--ssl-ca=/etc/pki/ca.crt --ssl-cert=/etc/pki/tls.crt
--ssl-key=/etc/pki/tls.key --ssl-verify-server-cert
-e "SELECT 'MariaDB connection successful!' AS Status;" -t
volumeMounts:
- name: pki
mountPath: /etc/pki
readOnly: true
volumes:
- name: pki
projected:
sources:
- secret:
name: mariadb-bundle
items:
- key: ca.crt
path: ca.crt
- secret:
name: mariadb-galera-client-cert
items:
- key: tls.crt
path: tls.crt
- key: tls.key
path: tls.key
restartPolicy: Never+---------------------------------+
| Status |
+---------------------------------+
| MariaDB connection successful! |
+---------------------------------+apiVersion: batch/v1
kind: CronJob
metadata:
name: maxscale-client
namespace: app
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: maxscale-client
image: mariadb:11.4.4
command:
- bash
args:
- -c
- >
mariadb -u app -h maxscale-galera.default.svc.cluster.local
--ssl-ca=/etc/pki/ca.crt --ssl-cert=/etc/pki/tls.crt
--ssl-key=/etc/pki/tls.key --ssl-verify-server-cert
-e "SELECT 'MaxScale connection successful!' AS Status;" -t
volumeMounts:
- name: pki
mountPath: /etc/pki
readOnly: true
volumes:
- name: pki
projected:
sources:
- secret:
name: mariadb-bundle
items:
- key: ca.crt
path: ca.crt
- secret:
name: mariadb-galera-client-cert
items:
- key: tls.crt
path: tls.crt
- key: tls.key
path: tls.key
restartPolicy: Never+---------------------------------+
| Status |
+---------------------------------+
| MaxScale connection successful! |
+---------------------------------+apiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb-galera
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
tlsClientCertSecretRef:
name: mariadb-galera-client-cert
database: mariadb
healthCheck:
interval: 30sapiVersion: enterprise.mariadb.com/v1alpha1
kind: Connection
metadata:
name: connection-maxscale
spec:
maxScaleRef:
name: maxscale-galera
username: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
tlsClientCertSecretRef:
name: mariadb-galera-client-cert
database: mariadb
healthCheck:
interval: 30skubectl get connections
NAME READY STATUS SECRET AGE
connection True Healthy connection 2m8s
connection-maxscale True Healthy connection-maxscale 97sOfficial Helm install MariaDB Enterprise Operator: mariadb-enterprise-operator-crds chart, values.yaml imagePullSecrets, --version, helm upgrade/uninstall.
cert-controller: Provisions TLS certificates for the webhook. You can see it as a minimal cert-manager that is intended to work only with the webhook. It is optional and can be replaced by cert-manager.helm repo add mariadb-enterprise-operator https://operator.mariadb.com
helm install mariadb-enterprise-operator-crds mariadb-enterprise-operator/mariadb-enterprise-operator-crdsimagePullSecrets:
- name: mariadb-enterprise
webhook:
imagePullSecrets:
- name: mariadb-enterprise
certController:
imagePullSecrets:
- name: mariadb-enterprisehelm repo add mariadb-enterprise-operator https://operator.mariadb.com
helm install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator \
-f values.yamlhelm repo add mariadb-enterprise-operator https://operator.mariadb.com
helm install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator \
-f values.yaml \
--set metrics.enabled=true --set webhook.cert.certManager.enabled=truehelm install --version "25.10.*" mariadb-enterprise-operator-crds mariadb-enterprise-operator/mariadb-enterprise-operator-crds
helm install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operator \
-f values.yaml \
--version "25.10.*"helm repo add mariadb-enterprise-operator https://operator.mariadb.com
helm install mariadb-enterprise-operator mariadb-enterprise-operator/mariadb-enterprise-operatorhelm repo add mariadb-enterprise-operator https://operator.mariadb.com
helm install mariadb-enterprise-operator \
-n databases --create-namespace \
-f values.yaml \
--set currentNamespaceOnly=true \
mariadb-enterprise-operator/mariadb-enterprise-operatorhelm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator-crds \
--version <new-version> \
mariadb-enterprise-operator/mariadb-enterprise-operator-crdshelm repo update mariadb-enterprise-operator
helm upgrade --install mariadb-enterprise-operator \
--version <new-version> \
mariadb-enterprise-operator/mariadb-enterprise-operatorha:
enabled: true
replicas: 3
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- mariadb-enterprise-operator
- key: app.kubernetes.io/instance
operator: In
values:
- mariadb-enterprise-operator
topologyKey: kubernetes.io/hostname
pdb:
enabled: true
maxUnavailable: 1helm uninstall mariadb-enterprise-operatorhelm uninstall mariadb-enterprise-operator-crdsInformation on how to enable and collect performance metrics from managed database instances for monitoring with tools like Prometheus and Grafana.
apiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
metrics:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale
spec:
...
metrics:
enabled: trueapiVersion: enterprise.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
...
metrics:
enabled: true
exporter:
image: mariadb/mariadb-prometheus-exporter-ubi:v0.0.2
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 300m
memory: 512Mi
port: 9104
serviceMonitor:
prometheusRelease: kube-prometheus-stack
jobLabel: mariadb-monitoring
interval: 10s
scrapeTimeout: 10s
username: monitoring
passwordSecretKeyRef:
name: mariadb
key: passwordapiVersion: enterprise.mariadb.com/v1alpha1
kind: MaxScale
metadata:
name: maxscale
spec:
...
auth:
metricsUsername: metrics
metricsPasswordSecretKeyRef:
key: password
name: maxscale-galera-metrics
metrics:
enabled: true
exporter:
image: mariadb/maxscale-prometheus-exporter-ubi:v0.0.2
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 300m
memory: 512Mi
port: 9105
serviceMonitor:
prometheusRelease: kube-prometheus-stack
jobLabel: mariadb-monitoring
interval: 10s
scrapeTimeout: 10sTechnical documentation of the Custom Resource Definitions (CRDs) and API fields used to configure the MariaDB Enterprise Kubernetes Operator.