Mysql Operator en
Mysql Operator en
Abstract
MySQL Operator for Kubernetes manages MySQL InnoDB Cluster setups inside a Kubernetes Cluster. MySQL
Operator for Kubernetes manages the full lifecycle with setup and maintenance including automating upgrades and
backups.
For notes detailing the changes in each release, see the MySQL Operator Release Notes.
For help with using MySQL, please visit the MySQL Forums, where you can discuss your issues with other MySQL
users.
iii
iv
Preface and Legal Notices
MySQL Operator for Kubernetes manages MySQL InnoDB Cluster setups inside a Kubernetes Cluster.
MySQL Operator for Kubernetes manages the full lifecycle with set up and maintenance including
automating upgrades and backups. This is the MySQL Operator for Kubernetes manual.
Licensing information. This product may include third-party software, used under license. If you are
using a Commercial release of MySQL Operator for Kubernetes, see the MySQL Operator for Kubernetes
8.4 Commercial License Information User Manual or MySQL Operator for Kubernetes 9.1 Commercial
License Information User Manual for licensing information, including licensing information relating to third-
party software that may be included in this Commercial release. If you are using a Community release
of MySQL Operator for Kubernetes, see the MySQL Operator for Kubernetes 8.4 Community License
Information User Manual or MySQL Operator for Kubernetes 9.1 Community License Information User
Manual for licensing information, including licensing information relating to third-party software that may be
included in this Community release.
Legal Notices
Copyright © 2009, 2025, Oracle and/or its affiliates.
License Restrictions
This software and related documentation are provided under a license agreement containing restrictions
on use and disclosure and are protected by intellectual property laws. Except as expressly permitted
in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast,
modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any
means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for
interoperability, is prohibited.
Warranty Disclaimer
The information contained herein is subject to change without notice and is not warranted to be error-free.
If you find any errors, please report them to us in writing.
If this is software, software documentation, data (as defined in the Federal Acquisition Regulation), or
related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S.
Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated
software, any programs embedded, installed, or activated on delivered hardware, and modifications
of such programs) and Oracle computer documentation or other Oracle data delivered to or accessed
by U.S. Government end users are "commercial computer software," "commercial computer software
documentation," or "limited rights data" pursuant to the applicable Federal Acquisition Regulation and
agency-specific supplemental regulations. As such, the use, reproduction, duplication, release, display,
disclosure, modification, preparation of derivative works, and/or adaptation of i) Oracle programs (including
any operating system, integrated software, any programs embedded, installed, or activated on delivered
hardware, and modifications of such programs), ii) Oracle computer documentation and/or iii) other Oracle
data, is subject to the rights and limitations specified in the license contained in the applicable contract.
The terms governing the U.S. Government's use of Oracle cloud services are defined by the applicable
contract for such services. No other rights are granted to the U.S. Government.
v
Access to Oracle Support for Accessibility
This software or hardware is developed for general use in a variety of information management
applications. It is not developed or intended for use in any inherently dangerous applications, including
applications that may create a risk of personal injury. If you use this software or hardware in dangerous
applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other
measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages
caused by use of this software or hardware in dangerous applications.
Trademark Notice
Oracle, Java, MySQL, and NetSuite are registered trademarks of Oracle and/or its affiliates. Other names
may be trademarks of their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks
are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD,
Epyc, and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a
registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content,
products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and
expressly disclaim all warranties of any kind with respect to third-party content, products, and services
unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and its
affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of
third-party content, products, or services, except as set forth in an applicable agreement between you and
Oracle.
This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the
following terms:
You may create a printed copy of this documentation solely for your own personal use. Conversion to other
formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish
or distribute this documentation in any form or on any media, except if you distribute the documentation in
a manner similar to how Oracle disseminates it (that is, electronically for download on a Web site with the
software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated
together with the software on the same medium. Any other use, such as any dissemination of printed
copies or use of this documentation, in whole or in part, in another publication, requires the prior written
consent from an authorized representative of Oracle. Oracle and/or its affiliates reserve any and all rights
to this documentation not expressly granted above.
vi
Chapter 1 Introduction
MySQL and Kubernetes share terminology. For example, a Node might be a Kubernetes Node or a
MySQL Node, a Cluster might be a MySQL InnoDB Cluster or Kubernetes Cluster, and a ReplicaSet is a
feature in both MySQL and Kubernetes. This documentation prefers the long names but these overloaded
terms may still lead to confusion; context is important.
Kubernetes
The Kubernetes system uses Controllers to manage the life-cycle of containerized workloads by running
them as Pods in the Kubernetes system. Controllers are general-purpose tools that provide capabilities
for a broad range of services, but complex services require additional components and this includes
operators. An Operator is software running inside the Kubernetes cluster, and the operator interacts
with the Kubernetes API to observe resources and services to assist Kubernetes with the life-cycle
management.
The MySQL Operator is deployed in the 'mysql-operator' Kubernetes namespace by default; and watches
all InnoDB Clusters and related resources in the Kubernetes cluster. To perform these tasks, the operator
subscribes to the Kubernetes API server to update events and connects to the managed MySQL Server
instance as needed. On top of the Kubernetes controllers, the operator configures the MySQL servers,
replication using MySQL Group Replication, and MySQL Router.
This manages the Pods and assigns the corresponding storage Volume. Each Pod managed by this
StatefulSet runs multiple containers. Several provide a sequence of initialisation steps for preparing the
MySQL Server configuration and data directory, and then two containers remain active for operational
mode. One of those containers (named 'mysql') runs the MySQL Server itself, and the other (named
'sidecar') is a Kubernetes sidecar responsible for local management of the node in coordination with the
operator itself.
MySQL Routers are stateless services routing the application to the current Primary or a Replica,
depending on the application's choice. The operator can scale the number of routers up or down as
required by the Cluster's workload.
• One service is the name of the InnoDB Cluster. It serves as primary entry point for an application
and sends incoming connections to the MySQL Router. They provide stable name in the form
'{clustername}.svc.cluster.local' and expose specific ports.
1
MySQL InnoDB Cluster
See also Section 3.4, “MySQL InnoDB Cluster Service Explanation” and Chapter 5, Connecting to
MySQL InnoDB Cluster.
• A second service named '{clustername}-instances' provides stable names to the individual servers.
Typically these should not be directly used; instead use the main service to reliably reach the current
primary or secondary as needed. However, for maintenance or monitoring purposes, direct access to an
instance might be needed. Each pod instance has MySQL Shell installed.
MySQL Operator for Kubernetes creates and manages additional resources that should not be manually
modified, including:
• A Kubernetes ConfigMap named '{clustername}-initconf' that contains configuration information for the
MySQL Servers.
To modify the generated my.cnf configuration file, see Section 3.3, “Manifest Changes for
InnoDBCluster”.
• A sequence of Kubernetes Secrets with credentials for different parts of the system; names include
'{clustername}.backup', '{clustername.privsecrets}', and '{clustername.router}'.
For a list of MySQL accounts (and associated Secrets) created by the operator, see Section 3.5,
“MySQL Accounts Created by InnoDBCluster Deployment”.
2
MySQL Operator for Kubernetes Architecture
3
4
Chapter 2 Installing MySQL Operator for Kubernetes
Table of Contents
2.1 Install using Helm Charts .............................................................................................................. 5
2.2 Install using Manifest Files ............................................................................................................ 5
Two different installation methods are documented here; using either helm or manually applying manifests
using kubectl. This documentation assumes that kubectl is available on a system configured with the
desired Kubernetes context; and all examples use a Unix-like command line.
MySQL Operator for Kubernetes functions with Kubernetes 1.21 and newer.
Note
MySQL Operator for Kubernetes requires these three container images to function:
MySQL Operator for Kubernetes, MySQL Router, and MySQL Server.
Install MySQL Operator for Kubernetes, this simple example defines the release name as my-mysql-
operator using a new namespace named mysql-operator:
$> helm install my-mysql-operator mysql-operator/mysql-operator \
--namespace mysql-operator --create-namespace
The operator deployment is customizable through other options that override built-in defaults. For example,
useful when using a local (air-gapped) private container registry to use with the operator.
To use MySQL Operator for Kubernetes to create MySQL InnoDB Clusters, see Chapter 3, MySQL
InnoDB Cluster.
MySQL Operator for Kubernetes can be installed using raw manifest files with kubectl.
Note
Using trunk in the URL references the latest MySQL Operator for Kubernetes
release because Github is updated at release time. Alternatively, replace trunk in
the URL with a specific tagged released version.
5
Install using Manifest Files
First install the Custom Resource Definition (CRD) used by MySQL Operator for Kubernetes:
$> kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-operator/trunk/deploy/deploy-crds.yaml
Next deploy MySQL Operator for Kubernetes, which also includes RBAC definitions as noted in the output:
$> kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-operator/trunk/deploy/deploy-operator.yaml
Verify that the operator is running by checking the deployment that is managing the operator inside the
mysql-operator namespace, a configurable namespace defined by deploy-operator.yaml:
$> kubectl get deployment mysql-operator --namespace mysql-operator
After MySQL Operator for Kubernetes is ready, the output should look similar to this:
To use MySQL Operator for Kubernetes to create MySQL InnoDB Clusters, see Chapter 3, MySQL
InnoDB Cluster.
6
Chapter 3 MySQL InnoDB Cluster
Table of Contents
3.1 Deploy using Helm ....................................................................................................................... 7
3.2 Deploy using kubectl .................................................................................................................... 8
3.3 Manifest Changes for InnoDBCluster ............................................................................................. 9
3.4 MySQL InnoDB Cluster Service Explanation ................................................................................ 11
3.5 MySQL Accounts Created by InnoDBCluster Deployment ............................................................. 13
Examples and documentation assumes the current default namespace is used, which defaults to 'default'
although it can be modified, for example:
$> kubectl create namespace newdefaultnamespace
$> kubectl config set-context --current --namespace=newdefaultnamespace
Examples typically use 'innodbcluster' as the resource name but may use plural and short names as
defined in deploy-crds.yaml:
names:
kind: InnoDBCluster
listKind: InnoDBClusterList
singular: innodbcluster
plural: innodbclusters
shortNames:
- ic
- ics
Public Registry
The most common Helm repository is the public https://artifacthub.io/, which is used by these examples.
Example credentials.yaml:
credentials:
root:
user: root
password: sakila
host: "%"
---
# Source: mysql-innodbcluster/templates/service_account_cluster.yaml
7
Deploy using kubectl
apiVersion: v1
kind: ServiceAccount
metadata:
name: mycluster-sa
namespace: default
---
# Source: mysql-innodbcluster/templates/cluster_secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mycluster-cluster-secret
namespace: default
stringData:
rootUser: "root"
rootHost: "%"
rootPassword: "sakila"
---
# Source: mysql-innodbcluster/templates/deployment_cluster.yaml
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: mycluster
namespace: default
spec:
instances: 3
tlsUseSelfSigned: true
router:
instances: 1
secretName: mycluster-cluster-secret
imagePullPolicy : IfNotPresent
baseServerId: 1000
version: 9.1.0
serviceAccountName: mycluster-sa
USER-SUPPLIED VALUES:
credentials:
root:
host: '%'
password: sakila
user: root
routerInstances: 1
serverInstances: 3
tls:
useSelfSigned: true
8
Manifest Changes for InnoDBCluster
Use that newly created user to configure a new MySQL InnoDB Cluster. This example's InnoDBCluster
definition creates three MySQL server instances and one MySQL Router instance:
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: mycluster
spec:
secretName: mypwds
tlsUseSelfSigned: true
instances: 3
router:
instances: 1
Assuming a file named mycluster.yaml contains this definition, install this simple cluster:
$> kubectl apply -f mycluster.yaml
Optionally observe the process by watching the innodbcluster type for the default namespace:
$> kubectl get innodbcluster --watch
To demonstrate, this example connects with MySQL Shell to show the host name:
$> kubectl run --rm -it myshell --image=container-registry.oracle.com/mysql/community-operator -- mysqlsh r
If you don't see a command prompt, try pressing enter.
******
+-------------+
| @@hostname |
+-------------+
| mycluster-0 |
+-------------+
This shows a successful connection that was routed to the mycluster-0 pod in the MySQL InnoDB Cluster.
For additional information about connecting, see Chapter 5, Connecting to MySQL InnoDB Cluster.
9
Router and Server Versions and Instances
Below are explanations of each change made to initial the InnoDBCluster configuration.
10
The initDB Object
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 40Gi
For additional configuration information, see the official Storage: Persistent Volumes documentation. The
datadirVolumeClaimTemplate object is set to x-kubernetes-preserve-unknown-fields:
true.
Note
MySQL Operator for Kubernetes currently does not support storage resizing.
For a related MySQLBackup example that uses a PersistentVolumeClaim, see Section 7.1, “Handling
MySQL Backups”.
This simple initDB clone example clones a remote MySQL instance from a cluster. The donor MySQL
server's credentials are stored in a Secret on the target server with a 'rootPassword' key for the 'rootUser'.
initDB:
clone:
donorUrl: mycluster-0.mycluster-instances.another.svc.cluster.local:3306
rootUser: root
secretKeyRef:
name: mypwds
MySQL Server restarts after populating with the clone operation, and a "1" is seen in the restart column of
the associated pods. Cloning utilizes MySQL Server's The Clone Plugin and behaves accordingly.
For a dump example (instead of clone), see Section 7.2, “Bootstrap a MySQL InnoDB Cluster from a Dump
using Helm”.
This is added to the generated my.cnf; the default my.cnf template is visible in the initconf container's
ConfigMap. An example to see this template: kubectl get cm ${CLUSTER_NAME}-initconf -o json | jq -r
'.data["my.cnf.in"]'.
11
MySQL InnoDB Cluster Service Explanation
Name: mycluster
Namespace: default
Labels: mysql.oracle.com/cluster=mycluster
tier=mysql
Annotations: <none>
Selector: component=mysqlrouter,mysql.oracle.com/cluster=mycluster,tier=mysql
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.106.33.215
IPs: 10.106.33.215
Port: mysql 3306/TCP
TargetPort: 6446/TCP
Endpoints: 172.17.0.12:6446
Port: mysqlx 33060/TCP
TargetPort: 6448/TCP
Endpoints: 172.17.0.12:6448
Port: mysql-alternate 6446/TCP
TargetPort: 6446/TCP
Endpoints: 172.17.0.12:6446
Port: mysqlx-alternate 6448/TCP
TargetPort: 6448/TCP
Endpoints: 172.17.0.12:6448
Port: mysql-ro 6447/TCP
TargetPort: 6447/TCP
Endpoints: 172.17.0.12:6447
Port: mysqlx-ro 6449/TCP
TargetPort: 6449/TCP
Endpoints: 172.17.0.12:6449
Port: router-rest 8443/TCP
TargetPort: 8443/TCP
Endpoints: 172.17.0.12:8443
Session Affinity: None
Events: <none>
The long host name used to connect to an InnoDB Cluster from within a Kubernetes cluster is
{innodbclustername}.{namespace}.svc.cluster.local, which routes to the current primary/
replica using MySQL Router, depending on the port. Acceptable host name forms:
{innodbclustername}.{namespace}.svc.cluster.local
{innodbclustername}.{namespace}.svc
{innodbclustername}.{namespace}
{innodbclustername}
Using these names goes to the Kubernetes LoadBalancer (part of Kubernetes Service), which redirects to
MySQL Router. MySQL Router then talks to the individual server based on the role, such as PRIMARY or
SECONDARY.
For example, assuming 'mycluster' as the InnoDB Cluster name in the 'default' namespace:
12
MySQL Accounts Created by InnoDBCluster Deployment
mycluster.default.svc.cluster.local
Using only {innodbclustername} as the host name assumes the session's context is either the default
namespace or set accordingly. Alternatively you may use the clusterIP instead of a host name; here's an
example that retrieves it:
$> kubectl get service/mycluster -o jsonpath='{.spec.clusterIP}'
Typically the only account a system administrator uses is the 'root' user, whereas other MySQL users are
considered internal to the MySQL InnoDB Cluster installation.
13
MySQL Accounts Created by InnoDBCluster Deployment
Related: Deploying MySQL Operator for Kubernetes creates a Kubernetes service account with a name
defaulting to mysql-operator-sa in the bundled deploy-operator.yaml and Helm deployment
template.
For a list of all ports used by MySQL services, see MySQL Port Reference.
14
Chapter 4 Upgrading MySQL Operator
Upgrading MySQL Operator
Apply MySQL Operator's latest released CRDs to create a new MySQL Operator deployment that replaces
the old. The old operator is terminated after the new operator is started and ready, which should not cause
downtime.
Note
This only updates MySQL Operator and not the associated MySQL InnoDB Cluster.
Using trunk in the URL references the latest MySQL Operator for Kubernetes release because Github is
updated at release time. Alternatively, replace trunk in the URL with a specific tagged released version.
We recommend using MySQL Shell's checkForServerUpgrade() utility to confirm that a MySQL InnoDB
Cluster is ready for upgrade. This example creates a temporary 8.4.0 pod (which includes MySQL Shell
8.4.0) to check if the InnoDB Cluster named mycluster is compatible to upgrade to MySQL 8.4.0:
...
Errors: 0
Warnings: 0
Notices: 0
A common upgrade method is to patch the MySQL server version. For example, this updates the MySQL
Server version to 8.4.0 for a MySQL InnoDB Cluster named mycluster:
15
Upgrading MySQL InnoDB Cluster
Updating a MySQL InnoDB Cluster initiates a rolling restart of the MySQL servers; the upgrade replaces
MySQL servers in order, by highest value in the name to lowest. This can cause multiple failovers of the
primary, depending on the current and assigned primaries.
• MySQL Router to the specified spec.version unless spec.router.version is also explicitly set in
the patch
• The MySQL sidecar container for each server to the installed MySQL Operator version
The MySQL InnoDB Cluster remains available during the upgrade process but the associated restarts may
interrupt existing connections.
16
Chapter 5 Connecting to MySQL InnoDB Cluster
Table of Contents
5.1 Connect with MySQL Shell ......................................................................................................... 17
5.2 Connect with Port Forwarding ..................................................................................................... 18
These examples assume the InnoDB Cluster is named 'mycluster' and using the 'default' namespace.
Create the new container with MySQL Shell; this example uses the MySQL Operator for Kubernetes
image but other images work too, such as container-registry.oracle.com/mysql/community-
server:8.0.
This example creates a new container named "myshell" using a MySQL Operator image, and immediately
executes MySQL Shell:
MySQL JS >
Now connect to the InnoDB Cluster from within MySQL Shell's interface:
The root@mycluster shorthand works as it assumes port 3306 (MySQL Router redirects to 6446) and
the default namespace.
The "******" represents entering the MySQL user's password to MySQL Shell as MySQL Shell prompts for
a password by default. The root@mycluster represents user root on host mycluster, and assumes the
default namespace. Setting "-sql initiates MySQL Shell into SQL mode.
17
Troubleshooting a Specific Container
...
To test, open a second terminal using the MySQL command line or MySQL Shell with the InnoDB Cluster
user's credentials:
$> mysql -h127.0.0.1 -uroot -p
Not seeing a port-forward to 127.0.0.1:3306 in this example means a local MySQL installation is likely
installed and active on the system.
18
Connect with Port Forwarding
router-rest: 8443
For a list of all ports used by MySQL services, see MySQL Port Reference. The ports used here are from
MySQL Router.
19
20
Chapter 6 Private Registries
Table of Contents
6.1 Install MySQL Operator for Kubernetes from Private Registry using Helm ...................................... 21
6.2 Install InnoDB Cluster from Private Registry using Helm ............................................................... 22
6.3 Copy Image to Private Registry using Docker .............................................................................. 22
6.4 Copy Image to Private Registry using Skopeo ............................................................................. 23
Authenticated private registries need to create a namespace for MySQL Operator for Kubernetes, and also
add a Kubernetes docker-registry secret in the namespace; then execute helm install with arguments
that look similar to:
21
Install InnoDB Cluster from Private Registry using Helm
To confirm the installation, check the status with commands such as helm list -n $NAMESPACE and
kubectl -n $NAMESPACE get pods.
Note
MySQL Operator for Kubernetes requires these three container images to function:
MySQL Operator for Kubernetes, MySQL Router, and MySQL Server.
1. Choose the desired MySQL Operator for Kubernetes version. For example, latest is defined in helm/
mysql-operator/Chart.yaml. For example, 9.1.0-2.2.2.
5. Execute docker load -i mysql-operator.yaml to load the image into the local Docker cache
on that host.
22
Copy Image to Private Registry using Skopeo
8. If you won't need the image from the importing host cache, then you can delete it with docker rmi
mysql/mysql-operator:VERSION registry:port/repo/mysql-server:VERSION. This
removes it from the host but the registry itself won't be affected. Adjust VERSION accordingly.
Alternatively, you can use the following commands to pull and push in one command. Execute it on
a host with Oracle Container Registry (OCR) access. If applicable, this host also needs access to the
secure (bastion) host that can access the private registry. Modify the variable values to fit your needs. The
command does not consume local space for a tarball but will stream the container image over SSH.
export BASTION_USER='k8s'
export BASTION_HOST='k8'
export REGISTRY="..." # for example 192.168.20.199:5000
export REPOSITORY="..." # for example mysql
export OPERATOR_VERSION=$(grep appVersion helm/mysql-operator/Chart.yaml | cut -d '"' -f2)
docker pull container-registry.oracle.com/mysql/community-operator:$OPERATOR_VERSION
docker save container-registry.oracle.com/mysql/community-operator:$OPERATOR_VERSION | \
ssh $BASTION_USER@$BASTION_HOST \
"docker load && \
docker tag container-registry.oracle.com/mysql/community-operator:$OPERATOR_VERSION $REGISTRY/$RE
docker push $REGISTRY/$REPOSITORY/mysql-operator:$OPERATOR_VERSION && \
docker rmi container-registry.oracle.com/mysql/community-operator:$OPERATOR_VERSION $REGISTRY/$RE
docker rmi container-registry.oracle.com/mysql/community-operator:$OPERATOR_VERSION
For authenticated private registries, append --dest-creds user:pass to the skopeo command. Also
append --dest-tls-verify=false if it does not use TLS.
23
24
Chapter 7 MySQL Operator Cookbook
Table of Contents
7.1 Handling MySQL Backups .......................................................................................................... 25
7.2 Bootstrap a MySQL InnoDB Cluster from a Dump using Helm ...................................................... 28
7.3 Viewing Logs .............................................................................................................................. 29
• Backup profile: describes the general backup structure that includes storage, schedule, and MySQL
Shell dump related options. Defining profiles is optional, and profiles are separated by name.
• Backup request: requesting a backup initiates a new object that creates a new pod to perform the
backup.
• Backup schedule: defined as a cron expression for regular backups, or with no schedule when
performing one-off backups.
See also Chapter 8, MySQL Operator Custom Resource Properties for a list of all MySQLBackup resource
options.
• The optional dumpOptions value is a dictionary of key-value pairs passed directly to MySQL Shell's
DumpInstance() function. See Instance Dump Utility, Schema Dump Utility, and Table Dump Utility for a
list of relevant options.
MySQL Operator for Kubernetes adds definitions by default, such as defining threads based on what
the system claims as its CPU count; but these values can be overridden.
• The storage configuration specification offers two options as of MySQL Operator for Kubernetes
8.0.29: persistentVolumeClaim or ociObjectStorage (OCI refers to Oracle Cloud Infrastructure).
Note
• The backupSchedules schedule utilizes the Kubernetes CronJob controller for regular backups.
25
A PersistentVolumeClaim Scheduled Backup Example
Note
This example defines a single backupProfile and schedule but could define multiple
profiles and schedules depending need. For example, a volatile table may have
hourly backups in addition to the full nightly backup.
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: mycluster
spec:
instances: 3
router:
instances: 1
secretName: mypwds
tlsUseSelfSigned: true
backupProfiles:
- name: myfancyprofile # Embedded backup profile
dumpInstance: # MySQL Shell Dump
dumpOptions:
excludeTables:
- world.country # Example to exclude one table
storage:
persistentVolumeClaim:
claimName: myexample-pvc # store to this pre-existing PVC
backupSchedules:
- name: mygreatschedule
schedule: "0 0 * * *" # Daily, at midnight
backupProfileName: myfancyprofile # reference the desired backupProfiles's name
enabled: true # backup schedules can be temporarily disabled
This example requires a PersistentVolumeClaim definition named "myexample-pvc"; see the official
Kubernetes Persistent Volumes documentation for PersistentVolumeClaim specifics. A simple
example:
apiVersion: v1
kind: PersistentVolume
metadata:
name: myexample-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myexample-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
26
Using OciObjectStorage
storage: 2Gi
The example "mycluster" InnoDB Cluster definition uses a secret named "mypwds" for its root user, for
example:
$> kubectl create secret generic mypwds \
--from-literal=rootUser=root \
--from-literal=rootHost=% \
--from-literal=rootPassword="sakila"
After creating the example InnoDB Cluster, you may want to execute a one-off backup using an existing
profile, such as:
apiVersion: mysql.oracle.com/v2
kind: MySQLBackup
metadata:
name: a-cool-one-off-backup
spec:
clusterName: mycluster
backupProfileName: myfancyprofile
Using OciObjectStorage
Using the same example but for Oracle Cloud Infrastructure (OCI) instead of a PVC, modify
dumpInstance.storage from PrivateVolumeClaim to an ociObjectStorage object similar to:
dumpInstance:
storage:
ociObjectStorage:
prefix: someprefix # a prefix (directory) used for ObjectStorage
bucketName: bucket # the ObjectStorage bucket
credentials: backup-apikey # a secret with credentials ...
The backup-apikey secret used in this OCI example looks similar to:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: backup-apikey
stringData:
fingerprint: 06:e9:e1:c6:e5:df:81:f3:......
passphrase: ....
privatekey: |
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwmQ1JGOGUBNwyJuq4msGpBfK24toKrWaqAkbZ1Z/XLOFLvEE
....
region: us-ashburn-1..
tenancy: ocid1.tenancy...
user: ocid1.user.....
An example method to create the Secret; values are found in the configuration file downloaded from OCI,
which is used with the OCI command-line tool.
27
Cloning
Using profiles (backupProfileName) is optional, so instead it may look like the following with the same
settings. This example restores to a new InnoDB Cluster from ociObjectStorage:
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: newcluster
spec:
instances: 3
router:
instances: 1
secretName: newpwds
tlsUseSelfSigned: true
baseServerId: 2000
initDB:
dump:
name: some-name
storage:
ociObjectStorage:
prefix: someprefix
bucketName: bucket
credentials: restore-apikey
The secret (restore-apikey) could be the same as the backup example (backup-apikey) but may be
a different user with different permissions, such as no write permissions to the OS.
Cloning
Data can be initialized using a backup or by cloning an existing and running MySQL instance using iniDB
and its donorURL option:
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: copycluster
spec:
instances: 1
secretName: pwds
tlsUseSelfSigned: true
initDB:
clone:
donorUrl: [email protected]:3306
secretKeyRef:
name: donorpwds
The donorpwds secret contains a single field named rootPassword, so for example you could reuse the
main secretName used when creating the original cluster (named mypwds in the example). This utilizes
MySQL's cloning plugin, so standard limitations apply (such as requiring the same MySQL versions).
Cloning can theoretically also be used for creating backups.
28
Viewing Logs
• The OCI OS Object Prefix (plays the role of a directory). The following Helm variables must be set:
• initDB.dump.name: a name for the dump that follows the Kubernetes rules for naming an identifier,
such as dump-20210916-140352.
For the credentials secret, the following information is needed: OCI OS User Name, Fingerprint,
Tenancy Name, Region Name, Passphrase, and the Private Key of the user.
The OCI command-line tool provides this information in $HOME/config under the [DEFAULT] section.
Once obtained, execute:
export NAMESPACE="mynamespace"
export OCI_CREDENTIALS_SECRET_NAME="oci-credentials"
export OCI_USER="..." # like ocid1.user.oc1....
export OCI_FINGERPRINT="..." # like 90:01:..:..:....
export OCI_TENANCY="..." # like ocid1.tenancy.oc1...
export OCI_REGION="..." # like us-ashburn-1
export OCI_PASSPHRASE="..." # set to empty string if no passphrase
export OCI_PATH_TO_PRIVATE_KEY="..." # like $HOME/.oci/oci_api_key.pem
With the OCI secret created, now create the cluster that'll be initialized from the dump in OCI OS:
export NAMESPACE="mynamespace"
export OCI_DUMP_PREFIX="..." # like dump-20210916-140352
export OCI_BUCKET_NAME="..." # like idbcluster_backup
export OCI_CREDENTIALS_SECRET_NAME="oci-credentials"
kubectl create namespace $NAMESPACE
helm install mycluster mysql-operator/mysql-innodbcluster \
--namespace $NAMESPACE \
--set credentials.root.user='root' \
--set credentials.root.password='sakila' \
--set credentials.root.host='%' \
--set serverInstances=3 \
--set routerInstances=1 \
--set initDB.dump.name="initdb-dump" \
--set initDB.dump.ociObjectStorage.prefix="$OCI_DUMP_PREFIX" \
--set initDB.dump.ociObjectStorage.bucketName="$OCI_BUCKET_NAME" \
--set initDB.dump.ociObjectStorage.credentials="$OCI_CREDENTIALS_SECRET_NAME"
Log locations include each InnoDBCluster Pod, which are divided into a set of containers. There are two
operative containers (mysql, and sidecar) and three initializer containers (initconf, initmysql, and
fixdatadir) as described below here:
29
Viewing Logs
There's also the dynamic MySQL Operator for Kubernetes and MySQL Router pods.
Examples that assume a basic setup as per samples/sample-cluster.yaml which looks like:
$> kubectl get pods
30
Viewing Logs
...
## MySQL Classic protocol
- Read/Write Connections: localhost:6446
- Read/Only Connections: localhost:6447
...
31
Viewing Logs
/mnt/initconf:
total 0
lrwxrwxrwx 1 root mysql 19 Apr 21 19:14 00-basic.cnf -> ..data/00-basic.cnf
lrwxrwxrwx 1 root mysql 31 Apr 21 19:14 01-group_replication.cnf -> ..data/01-group_replication.cnf
lrwxrwxrwx 1 root mysql 17 Apr 21 19:14 02-ssl.cnf -> ..data/02-ssl.cnf
lrwxrwxrwx 1 root mysql 19 Apr 21 19:14 99-extra.cnf -> ..data/99-extra.cnf
lrwxrwxrwx 1 root mysql 27 Apr 21 19:14 initdb-localroot.sql -> ..data/initdb-localroot.sql
lrwxrwxrwx 1 root mysql 23 Apr 21 19:14 livenessprobe.sh -> ..data/livenessprobe.sh
lrwxrwxrwx 1 root mysql 16 Apr 21 19:14 my.cnf.in -> ..data/my.cnf.in
lrwxrwxrwx 1 root mysql 24 Apr 21 19:14 readinessprobe.sh -> ..data/readinessprobe.sh
/mnt/mycnfdata:
total 0
2022-04-21T19:14:38 - [INFO] [initmysql] Setting up configurations for mycluster-0 server_id=1000
report_host=mycluster-0.mycluster-instances.default.svc.cluster.local
2022-04-21T19:14:38 - [INFO] [initmysql] Configuration done
loose_group_replication_recovery_use_ssl=1
# loose_group_replication_recovery_ssl_verify_server_cert=1
# loose_group_replication_recovery_ssl_ca=/etc/mysql-ssl/ca.pem
## loose_group_replication_recovery_ssl_crl=/etc/mysql-ssl/crl.pem
# loose_group_replication_recovery_ssl_cert=/etc/mysql-ssl/tls.crt
# loose_group_replication_recovery_ssl_key=/etc/mysql-ssl/tls.key
99-extra.cnf: |
# Additional user configurations taken from spec.mycnf in InnoDBCluster.
# Do not edit directly.
[mysqld]
innodb_buffer_pool_size=200M
innodb_log_file_size=2G
my.cnf.in: |
32
Viewing Logs
[mysql]
socket=/var/run/mysqld/mysql.sock
[mysqladmin]
socket=/var/run/mysqld/mysql.sock
!includedir /etc/my.cnf.d
33
34
Chapter 8 MySQL Operator Custom Resource Properties
Resource Types
• InnoDBCluster
• MySQLBackup
InnoDBCluster
Table 8.1 Spec table for InnoDBCluster
Name Type Description Required
apiVersion string mysql.oracle.com/v2 true
kind string InnoDBCluster true
metadata object Refer to the Kubernetes true
API documentation
spec object true
status object false
InnoDBCluster.spec
Parent
Table 8.2 Spec table for InnoDBCluster.spec
Name Type Description Required
secretName string Name of a generic type true
Secret containing root/
default account password
backupProfiles []object Backup profile false
specifications for the
cluster, which can be
referenced from backup
schedules and one-off
backup jobs
backupSchedules []object Schedules for periodically false
executed backups
baseServerId integer Base value for MySQL false
server_id for instances in
the cluster
• Default: 1000
• Minimum: 0
• Maximum: 4294967195
datadirPermissions object false
object
datadirVolumeClaimTemplate Template for a false
PersistentVolumeClaim,
to be used as datadir
35
InnoDBCluster.spec
• Default: 1
• Minimum: 1
• Maximum: 9
keyring object Keyring specification false
logs object Functionality added in false
MySQL Operator for
Kubernetes 8.2.0-2.1.1.
metrics object Configuration of a false
Prometheus-style metrics
provider; functionality
added in MySQL
Operator for Kubernetes
8.1.0-2.1.0.
mycnf string Custom configuration false
additions for my.cnf
podAnnotations object false
podLabels object false
podSpec object false
readReplicas []object false
router object MySQL Router false
specification
service object Configuration of the false
Service used by
applications connecting
to the InnoDB Cluster
serviceAccountName string false
serviceFqdnTemplate string Template for a FQDN false
resolving to the cluster's
36
InnoDBCluster.spec.backupProfiles[index]
• Default: false
version string MySQL Server version false
InnoDBCluster.spec.backupProfiles[index]
Parent
InnoDBCluster.spec.backupProfiles[index].dumpInstance
Parent
37
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage
Parent
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.azure
Parent
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.ociObjectStorage
Parent
38
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.s3
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.s3
Parent
• Default:
InnoDBCluster.spec.backupProfiles[index].snapshot
Parent
InnoDBCluster.spec.backupProfiles[index].snapshot.storage
Parent
39
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.azure
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.azure
Parent
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.ociObjectStorage
Parent
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.s3
Parent
40
InnoDBCluster.spec.backupSchedules[index]
InnoDBCluster.spec.backupSchedules[index]
Parent
• Default: false
enabled boolean Whether the schedule is false
enabled or not
• Default: true
timeZone string Timezone for the backup false
schedule, example:
'America/New_York' --
functionality added in
MySQL Operator for
Kubernetes 8.3.0-2.1.2.
InnoDBCluster.spec.backupSchedules[index].backupProfile
Parent
41
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance
Parent
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage
Parent
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.azu
Parent
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.oci
Parent
42
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.s3
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.s
Parent
• Default:
InnoDBCluster.spec.datadirPermissions
Functionality added in MySQL Operator for Kubernetes 9.1.0-2.2.2.
Parent
43
InnoDBCluster.spec.imagePullSecrets[index]
• Default: true
InnoDBCluster.spec.imagePullSecrets[index]
Parent
InnoDBCluster.spec.initDB
Parent
InnoDBCluster.spec.initDB.clone
Parent
• Default: root
InnoDBCluster.spec.initDB.clone.secretKeyRef
Parent
44
InnoDBCluster.spec.initDB.dump
InnoDBCluster.spec.initDB.dump
Parent
InnoDBCluster.spec.initDB.dump.storage
Parent
InnoDBCluster.spec.initDB.dump.storage.azure
Parent
45
InnoDBCluster.spec.initDB.dump.storage.ociObjectStorage
InnoDBCluster.spec.initDB.dump.storage.ociObjectStorage
Parent
InnoDBCluster.spec.initDB.dump.storage.s3
Parent
• Default:
InnoDBCluster.spec.keyring
Parent
46
InnoDBCluster.spec.keyring.encryptedFile
InnoDBCluster.spec.keyring.encryptedFile
Parent
• Default:
mysql_keyring
readOnly boolean Whether to open the false
keyring file in read-only
mode
• Default: false
InnoDBCluster.spec.keyring.file
Parent
47
InnoDBCluster.spec.keyring.oci
• Default:
mysql_keyring
readOnly boolean Whether to open the false
keyring file in read-only
mode
• Default: false
InnoDBCluster.spec.keyring.oci
Parent
InnoDBCluster.spec.keyring.oci.endpoints
Parent
48
InnoDBCluster.spec.logs
InnoDBCluster.spec.logs
Functionality added in MySQL Operator for Kubernetes 8.2.0-2.1.1.
Parent
InnoDBCluster.spec.logs.collector
Parent
• Default: logcollector
env []object false
fluentd object Properties of the fluentd false
log collector
image string Name of an image, false
including registry and
repository, to be used for
the log collector sidecar.
49
InnoDBCluster.spec.logs.collector.fluentd
InnoDBCluster.spec.logs.collector.fluentd
Parent
InnoDBCluster.spec.logs.collector.fluentd.errorLog
Parent
• Default:
InnoDBCluster.spec.logs.collector.fluentd.generalLog
Parent
50
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation
Parent
• Default: false
labels []object false
podFields []object false
resourceFields []object false
staticFields []object false
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.annotations[index]
Parent
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.labels[index]
Parent
51
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.podFields[index]
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.podFields[index]
Parent
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.resourceFields[index]
Parent
52
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.staticFields[index]
InnoDBCluster.spec.logs.collector.fluentd.recordAugmentation.staticFields[index]
Parent
InnoDBCluster.spec.logs.collector.fluentd.sinks[index]
Parent
InnoDBCluster.spec.logs.collector.fluentd.slowQueryLog
Parent
• Default:
53
InnoDBCluster.spec.logs.error
InnoDBCluster.spec.logs.error
Parent
• Default: false
verbosity integer Log error verbosity. For false
details, see the MySQL
Server --log-error-
verbosity documentation.
• Default: 3
• Minimum: 1
• Maximum: 3
InnoDBCluster.spec.logs.general
Parent
• Default: false
enabled boolean Whether general logging false
should be enabled
• Default: false
InnoDBCluster.spec.logs.slowQuery
Parent
54
InnoDBCluster.spec.metrics
• Default: false
enabled boolean Whether slow query false
logging should be
enabled
• Default: false
longQueryTime number Long query time false
threshold
• Default: 10
• Minimum: 0
InnoDBCluster.spec.metrics
Parent
• Default: false
image string Name of an image to true
be used for the metrics
sidecar, if provided
metrics will be enabled
monitor boolean Create a ServiceMonitor false
for Prometheus Operator
• Default: false
monitorSpec object Custom configuration for false
the ServiceMonitor object
• Default: map[]
options []string Options passed to the false
metrics provider as
command line arguments
tlsSecret string Name of a Secret with false
TLS certificate, key
and CA, which will be
mounted at /tls into the
55
InnoDBCluster.spec.readReplicas[index]
InnoDBCluster.spec.readReplicas[index]
Functionality added in MySQL Operator for Kubernetes 8.2.0-2.1.1.
Parent
Table 8.53 Spec table for InnoDBCluster.spec.readReplicas[index]
Name Type Description Required
baseServerId integer Base value for MySQL true
server_id for instances
of the readReplica, if
0 it will be assigned
automatically
• Default: 0
• Minimum: 0
• Maximum: 4294967195
name string true
object
datadirVolumeClaimTemplate Template for a false
PersistentVolumeClaim,
to be used as datadir
instances integer Number of MySQL false
instances for the set of
read replica
• Default: 1
• Minimum: 1
• Maximum: 999
mycnf string Custom configuration false
additions for my.cnf
podAnnotations object false
podLabels object false
podSpec object false
version string MySQL Server version false
InnoDBCluster.spec.router
Parent
56
InnoDBCluster.spec.router.routingOptions
• Default: 1
• Minimum: 0
options []string Command line options false
passed to MySQL
Router while running;
functionality added in
MySQL Operator for
Kubernetes 8.2.0-2.1.1.
podAnnotations object false
podLabels object false
podSpec object false
routingOptions object Set routing options for false
the cluster
tlsSecretName string Name of a TLS type false
Secret containing MySQL
Router certificate and
private key used for SSL
version string Override MySQL Router false
version
InnoDBCluster.spec.router.routingOptions
Parent
57
InnoDBCluster.spec.service
InnoDBCluster.spec.service
Parent
Description: Configuration of the Service used by applications connecting to the InnoDB Cluster
• Enum: mysql-rw,
mysql-ro, mysql-rw-
split
• Default: mysql-rw
labels object Custom labels for the false
Service
type enum • Enum: ClusterIP, false
NodePort,
LoadBalancer
• Default: ClusterIP
MySQLBackup
Table 8.57 Spec table for MySQLBackup
58
MySQLBackup.spec
MySQLBackup.spec
Parent
MySQLBackup.spec.backupProfile
Parent
MySQLBackup.spec.backupProfile.dumpInstance
Parent
MySQLBackup.spec.backupProfile.dumpInstance.storage
Parent
59
MySQLBackup.spec.backupProfile.dumpInstance.storage.azure
MySQLBackup.spec.backupProfile.dumpInstance.storage.azure
Parent
MySQLBackup.spec.backupProfile.dumpInstance.storage.ociObjectStorage
Parent
MySQLBackup.spec.backupProfile.dumpInstance.storage.s3
Parent
60
MySQLBackup.status
• Default:
MySQLBackup.status
Parent
Resource Types
• ClusterKopfPeering
• KopfPeering
ClusterKopfPeering
Table 8.66 Spec table for ClusterKopfPeering
61
KopfPeering
KopfPeering
Table 8.67 Spec table for KopfPeering
62