Mysql Operator En.a4
Mysql Operator En.a4
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.0 Commercial License Information User Manual or MySQL Operator for Kubernetes 8.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.0 Community License Information User Manual or MySQL Operator for Kubernetes 8.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, 2023, Oracle and/or its affiliates.
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.
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 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" or "commercial computer software
documentation" 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.
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.
Oracle, Java, and MySQL 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
v
Access to Oracle Support for Accessibility
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.
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
1
MySQL Operator for Kubernetes Architecture
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:
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
Chapter 2 Installing MySQL Operator for Kubernetes
Table of Contents
2.1 Install using Helm Charts ........................................................................................................ 3
2.2 Install using Manifest Files ...................................................................................................... 3
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
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.
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.yam
3
Install using Manifest Files
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.yam
Verify that the operator is running by checking the deployment that's 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.
4
Chapter 3 MySQL InnoDB Cluster
Table of Contents
3.1 Deploy using Helm ................................................................................................................. 5
3.2 Deploy using kubectl ............................................................................................................... 6
3.3 Manifest Changes for InnoDBCluster ....................................................................................... 7
3.4 MySQL InnoDB Cluster Service Explanation ............................................................................ 9
3.5 MySQL Accounts Created by InnoDBCluster Deployment ....................................................... 10
Examples and documentation assumes the current default namespace is used, which defaults to
'default' although it can be modified, for example:
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
5
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: 8.0.33
serviceAccountName: mycluster-sa
USER-SUPPLIED VALUES:
credentials:
root:
host: '%'
password: sakila
user: root
routerInstances: 1
serverInstances: 3
tls:
useSelfSigned: true
6
Manifest Changes for InnoDBCluster
--from-literal=rootPassword="sakila"
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 -- mysql
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.
7
Router and Server Versions and Instances
name: mycluster
spec:
secretName: mypwds
tlsUseSelfSigned: true
Below are explanations of each change made to initial the InnoDBCluster configuration.
For additional configuration information, see the official Storage: Persistent Volumes documentation.
The datadirVolumeClaimTemplate object is set to x-kubernetes-preserve-unknown-
fields: true.
8
The initDB Object
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"]'.
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
9
MySQL Accounts Created by InnoDBCluster Deployment
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:
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}'
10
MySQL Accounts Created by InnoDBCluster Deployment
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.
11
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.
12
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.
kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-operator/trunk/deploy/deploy-crds.yaml
kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-operator/trunk/deploy/deploy-operator.ya
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.
A common upgrade method is to patch the MySQL server version. For example, this updates the
MySQL Server version to 8.0.34 for a MySQL InnoDB Cluster named mycluster:
kubectl patch ic mycluster -p '{"spec": { "version": "8.0.34" } }' --type=merge
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.
13
14
Chapter 5 Connecting to MySQL InnoDB Cluster
Table of Contents
5.1 Connect with MySQL Shell .................................................................................................... 15
5.2 Connect with Port Forwarding ................................................................................................ 16
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:
$> kubectl run --rm -it myshell --image=container-registry.oracle.com/mysql/community-operator -- mysql
If you don't see a command prompt, try pressing enter.
MySQL JS >
Now connect to the InnoDB Cluster from within MySQL Shell's interface:
MySQL JS> \connect root@mycluster
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.
15
Connect with Port Forwarding
...
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.
For a list of all ports used by MySQL services, see MySQL Port Reference. The ports used here are
from MySQL Router.
16
Chapter 6 Private Registries
Table of Contents
6.1 Install MySQL Operator for Kubernetes from Private Registry using Helm ................................ 17
6.2 Install InnoDB Cluster from Private Registry using Helm ......................................................... 18
6.3 Copy Image to Private Registry using Docker ......................................................................... 18
6.4 Copy Image to Private Registry using Skopeo ........................................................................ 19
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:
To confirm the installation, check the status with commands such as helm list -n $NAMESPACE
and kubectl -n $NAMESPACE get pods.
17
Install InnoDB Cluster from Private Registry using Helm
Note
1. Choose the desired MySQL Operator for Kubernetes version. For example, latest is defined in
helm/mysql-operator/Chart.yaml. For example, 8.0.33-2.0.9.
5. Execute docker load -i mysql-operator.yaml to load the image into the local Docker
cache on that host.
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
18
Copy Image to Private Registry using Skopeo
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
docker push $REGISTRY/$REPOSITORY/mysql-operator:$OPERATOR_VERSION && \
docker rmi container-registry.oracle.com/mysql/community-operator:$OPERATOR_VERSION $REGISTRY
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.
19
20
Chapter 7 MySQL Operator Cookbook
Table of Contents
7.1 Handling MySQL Backups ..................................................................................................... 21
7.2 Bootstrap a MySQL InnoDB Cluster from a Dump using Helm ................................................. 24
7.3 Viewing Logs ........................................................................................................................ 25
• 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.
21
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
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:
storage: 2Gi
The example "mycluster" InnoDB Cluster definition uses a secret named "mypwds" for its root user, for
example:
22
Using OciObjectStorage
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.
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:
23
Cloning
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.
• 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.
24
Viewing Logs
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:
Table 7.1 Containers associated with an InnoDBCluster Pod
Container Name Description
sidecar Initialization, including initial setup of data (initDB)
and ongoing maintenance tasks for a specific
instance, such as TLS certification updates
mysql The MySQL Server itself
initconf It prepares MySQL configuration files for a specific
host. For example, to view its ConfigMap: kubectl
get cm {cluster_name}-initconf -o json
initmysql Initializes the MySQL Server, including its data
directory.
25
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
26
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.cluste
2022-04-21T19:14:38 - [INFO] [initmysql] Configuration done
27
Viewing Logs
data:
00-basic.cnf: |
# Basic configuration.
# Do not edit.
[mysqld]
plugin_load_add=auth_socket.so
loose_auth_socket=FORCE_PLUS_PERMANENT
skip_log_error
log_error_verbosity=3
01-group_replication.cnf: |
# GR and replication related options
# Do not edit.
[mysqld]
log_bin=mycluster
enforce_gtid_consistency=ON
gtid_mode=ON
relay_log_info_repository=TABLE
skip_slave_start=1
02-ssl.cnf: |
# SSL configurations
# Do not edit.
[mysqld]
# ssl-ca=/etc/mysql-ssl/ca.pem
# ssl-crl=/etc/mysql-ssl/crl.pem
# ssl-cert=/etc/mysql-ssl/tls.crt
# ssl-key=/etc/mysql-ssl/tls.key
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: |
# Server identity related options (not shared across instances).
# Do not edit.
[mysqld]
server_id=@@SERVER_ID@@
report_host=@@HOSTNAME@@
datadir=/var/lib/mysql
loose_mysqlx_socket=/var/run/mysqld/mysqlx.sock
socket=/var/run/mysqld/mysql.sock
local-infile=1
[mysql]
socket=/var/run/mysqld/mysql.sock
[mysqladmin]
socket=/var/run/mysqld/mysql.sock
!includedir /etc/my.cnf.d
28
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 true
type 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 false
periodically executed
backups
baseServerId integer Base value for MySQL false
server_id for instances
in the cluster
• Default: 1000
• Minimum: 0
• Maximum:
4294967195
object
datadirVolumeClaimTemplate Template for a false
PersistentVolumeClaim,
to be used as datadir
edition string MySQL Server false
Edition (community or
enterprise)
29
InnoDBCluster.spec
• Default: 1
• Minimum: 1
• Maximum: 9
keyring object Keyring specification false
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
router object MySQL Router false
specification
serviceAccountName string false
tlsCASecretName string Name of a generic type false
Secret containing CA
(ca.pem) and optional
CRL (crl.pem) for SSL
tlsSecretName string Name of a TLS type false
Secret containing Server
certificate and private
key for SSL
tlsUseSelfSigned boolean Enables use of self- false
signed TLS certificates,
reducing or disabling
TLS based security
verifications
• Default: false
30
InnoDBCluster.spec.backupProfiles[index]
InnoDBCluster.spec.backupProfiles[index]
Parent
Table 8.3 Spec table for InnoDBCluster.spec.backupProfiles[index]
Name Type Description Required
name string Embedded backup true
profile, referenced as
backupProfileName
elsewhere
dumpInstance object false
podAnnotations object false
podLabels object false
snapshot object false
InnoDBCluster.spec.backupProfiles[index].dumpInstance
Parent
Table 8.4 Spec table for InnoDBCluster.spec.backupProfiles[index].dumpInstance
Name Type Description Required
dumpOptions object A dictionary of key-value false
pairs passed directly
to MySQL Shell's
DumpInstance()
storage object false
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage
Parent
Table 8.5 Spec table for InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage
Name Type Description Required
azure object false
ociObjectStorage object false
object
persistentVolumeClaim Specification of the PVC false
to be used. Used 'as
is' in pod executing the
backup.
s3 object false
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.azure
Parent
Table 8.6 Spec table for InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.azure
Name Type Description Required
config string Name of a Secret with true
Azure BLOB Storage
31
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.ociObjectStorage
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.ociObjectStorage
Parent
InnoDBCluster.spec.backupProfiles[index].dumpInstance.storage.s3
Parent
• Default:
InnoDBCluster.spec.backupProfiles[index].snapshot
Parent
32
InnoDBCluster.spec.backupProfiles[index].snapshot.storage
InnoDBCluster.spec.backupProfiles[index].snapshot.storage
Parent
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.azure
Parent
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.ociObjectStorage
Parent
33
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.s3
InnoDBCluster.spec.backupProfiles[index].snapshot.storage.s3
Parent
Table 8.13 Spec table for InnoDBCluster.spec.backupProfiles[index].snapshot.storage.s3
Name Type Description Required
bucketName string Name of the S3 bucket true
where the dump is
stored
config string Name of a Secret with true
S3 configuration and
credentials
endpoint string Override endpoint URL false
prefix string Path in the bucket false
where the dump files are
stored
profile string Profile being used in false
configuration files
• Default:
InnoDBCluster.spec.backupSchedules[index]
Parent
Table 8.14 Spec table for InnoDBCluster.spec.backupSchedules[index]
Name Type Description Required
name string Name of the backup true
schedule
schedule string The schedule of the true
job, syntax as a cron
expression
backupProfile object backupProfile false
specification if
backupProfileName is
not specified
backupProfileName string Name of the false
backupProfile to be
used
deleteBackupData boolean Whether to delete the false
backup data in case the
MySQLBackup object
created by the job is
deleted
• Default: false
enabled boolean Whether the schedule is false
enabled or not
• Default: true
InnoDBCluster.spec.backupSchedules[index].backupProfile
Parent
34
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance
Parent
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storag
Parent
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storag
Parent
35
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.ociObjectStorage
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.o
Parent
InnoDBCluster.spec.backupSchedules[index].backupProfile.dumpInstance.storage.s
Parent
• Default:
InnoDBCluster.spec.imagePullSecrets[index]
Parent
36
InnoDBCluster.spec.initDB
InnoDBCluster.spec.initDB
Parent
InnoDBCluster.spec.initDB.clone
Parent
• Default: root
InnoDBCluster.spec.initDB.clone.secretKeyRef
Parent
InnoDBCluster.spec.initDB.dump
Parent
37
InnoDBCluster.spec.initDB.dump.storage
InnoDBCluster.spec.initDB.dump.storage
Parent
InnoDBCluster.spec.initDB.dump.storage.azure
Parent
InnoDBCluster.spec.initDB.dump.storage.ociObjectStorage
Parent
38
InnoDBCluster.spec.initDB.dump.storage.s3
InnoDBCluster.spec.initDB.dump.storage.s3
Parent
• Default:
InnoDBCluster.spec.keyring
Parent
InnoDBCluster.spec.keyring.encryptedFile
Parent
39
InnoDBCluster.spec.keyring.file
• Default: false
InnoDBCluster.spec.keyring.file
Parent
• Default: false
InnoDBCluster.spec.keyring.oci
Parent
40
InnoDBCluster.spec.keyring.oci.endpoints
InnoDBCluster.spec.keyring.oci.endpoints
Parent
InnoDBCluster.spec.metrics
Parent
• Default: false
41
InnoDBCluster.spec.router
• Default: false
monitorSpec object Custom configuration false
for the ServiceMonitor
object
• Default: map[]
options []string Options passed to false
the 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
container an can be
used from webConfig
webConfig string Name of a ConfigMap false
with a web.config file, if
this option is provided a
command line option --
web.config.file is added
InnoDBCluster.spec.router
Parent
• Default: 1
• Minimum: 0
podAnnotations object false
podLabels object false
podSpec object false
tlsSecretName string Name of a TLS type false
Secret containing
MySQL Router
certificate and private
key used for SSL
42
MySQLBackup
MySQLBackup
Table 8.37 Spec table for MySQLBackup
Name Type Description Required
apiVersion string mysql.oracle.com/v2 true
kind string MySQLBackup true
metadata object Refer to the Kubernetes true
API documentation
spec object false
status object false
MySQLBackup.spec
Parent
MySQLBackup.spec.backupProfile
Parent
MySQLBackup.spec.backupProfile.dumpInstance
Parent
43
MySQLBackup.spec.backupProfile.dumpInstance.storage
MySQLBackup.spec.backupProfile.dumpInstance.storage
Parent
MySQLBackup.spec.backupProfile.dumpInstance.storage.azure
Parent
MySQLBackup.spec.backupProfile.dumpInstance.storage.ociObjectStorage
Parent
44
MySQLBackup.spec.backupProfile.dumpInstance.storage.s3
MySQLBackup.spec.backupProfile.dumpInstance.storage.s3
Parent
• Default:
MySQLBackup.status
Parent
Resource Types
• ClusterKopfPeering
• KopfPeering
45
ClusterKopfPeering
ClusterKopfPeering
Table 8.46 Spec table for ClusterKopfPeering
KopfPeering
Table 8.47 Spec table for KopfPeering
46