Situatie
Kubernetes support for stateful applications has considerably matured over the past few years. Now it’s viable to locate your database inside your cluster, allowing it to benefit from the same scalability as your other workloads.
MySQL is one of the most popular relational database engines and it’s now augmented by an official Kubernetes operator. The Oracle-led open-source project provides a simple way to create managed MySQL clusters within Kubernetes.
Solutie
Oracle’s MySQL operator is a component that runs inside your cluster to automate database initialization. You don’t need the operator to use MySQL in Kubernetes – you could deploy the official container image yourself by using a StatefulSet. This approach is cumbersome though, requiring you to author and maintain long manifest files to create a reliable environment.
The operator provides a set of custom resources that you can use to create your databases. Adding an InnoDBCluster
object to your Kubernetes cluster prompts the operator to set up StatefulSets, storage, and networking for you. It also automates upgrades and backups, greatly reducing the burden on administrators.
Installing the MySQL Operator
The included Helm chart is the simplest way to install the operator in your cluster. Manifest files are available as an alternative if you don’t have Helm in your environment.
First add the operator to your Helm repository list:
$ helm repo add mysql-operator https://mysql.github.io/mysql-operator/
Next update Helm’s repository database so it discovers the available charts:
$ helm repo update
Now use the following command to install the operator into a new namespace called mysql-operator
:
$ helm install mysql-operator mysql-operator/mysql-operator \ --namespace mysql-operator \ --create-namespace NAME: mysql-operator LAST DEPLOYED: Sat Oct 29 15:00:26 2022 NAMESPACE: mysql-operator STATUS: deployed REVISION: 1 TEST SUITE: None
It might take a few seconds for the process to complete.
Creating a Root User Credentials Secret
Each database cluster you create must be accompanied by a Kubernetes secret that contains the credentials for the MySQL root user. The operator will create the root-privileged account with the username and password provided in the secret.
Copy the following YAML manifest and change the value of the rootPassword
field to something secure. Alter the username and user host settings too if applicable to your situation. Remember that the account named here will have total control over MySQL; you should set up separate users for your applications later on, using the regular MySQL shell.
apiVersion: v1 kind: Secret metadata: name: mysql-root-user stringData: rootHost: "%" rootUser: "root" rootPassword: "P@$$w0rd"
Save the file as secret.yaml
. Now use Kubectl to add the secret to your cluster:
$ kubectl apply -f secret.yaml secret/mysql-root-user created
Creating a Basic Cluster
Next create a new YAML file called mysql.yaml
and copy the following content:
apiVersion: mysql.oracle.com/v2 kind: InnoDBCluster metadata: name: mysql-cluster spec: secretName: mysql-root-user instances: 3 tlsUseSelfSigned: true router: instances: 1
This defines an object using the InnoDBCluster
custom resource offered by the MySQL operator. Applying the manifest to your cluster will create a new MySQL database with replication automatically configured. Review and change the following properties in the manifest before you continue:
spec.secretName
– This must match themetadata.name
of the secret you created earlier. The referenced secret will be read to set up the MySQL root user account.spec.instances
– This defines how many MySQL replicas (Pods) to run. Up to 10 replicas are currently supported.spec.tlsUseSelfSigned
– The field is set totrue
in this example to use the included self-signed TLS certificate. You can optionally supply your own certificate via a Kubernetes secret by setting thespec.tlsSecretName
/spec.tlsCASecretName
fields.spec.router.instances
– The MySQL Router component is responsible for directing service traffic between the available MySQL replicas. This field defines how many instances of the router to run. Multiple instances will improve performance and resiliency in high-traffic situations.
Use Kubectl to apply the manifest and create your database cluster:
$ kubectl apply -f mysql.yaml innodbcluster.mysql.oracle.com/mysql-cluster created
The MySQL initialization process can take a couple of minutes to complete. The operator uses several init containers to set up user accounts and configure MySQL’s data directory. Wait a few moments before running kubectl get pods
to check what’s running:
$ kubectl get pods NAME READY STATUS RESTARTS AGE mysql-cluster-0 2/2 Running 0 2m mysql-cluster-1 2/2 Running 0 2m mysql-cluster-2 2/2 Running 0 2m mysql-cluster-router-6b68f9b5cb-wbqm5 1/1 Running 0 2m
The three MySQL replicas and single router instance are all in the Running
state. The database is now ready to use.
Connecting to Your Cluster
The MySQL operator creates a Kubernetes service that routes traffic from your application Pods to your database. The service gets assigned a hostname with the following format:
<cluster-name>.<namespace-name>.svc.cluster.local
The correct hostname for the example cluster shown above is mysql-cluster.default.svc.cluster.local
. Configure your applications to connect to MySQL at this address using port 3306 and the user credentials you defined in your secret.
Accessing Your Database Externally
You can access MySQL from outside your cluster using Kubectl’s port forwarding capabilities. Run the following command to open a new port forwarding session:
$ kubectl port-forward service/mysql-cluster 3306
Replace mysql-cluster
with the name of the InnoDBCluster
you want to connect to. Now you can use your local tools to interact with your database:
$ mysql -h127.0.0.1 -u root -p
Pressing Ctrl+C in the terminal window running the kubectl port-forward
command will close the connection.
Customizing MySQL Server Settings
You can supply any MySQL config file options that your application requires by setting the spec.mycnf
field in your InnoDBCluster
object’s manifest:
apiVersion: mysql.oracle.com/v2 kind: InnoDBCluster spec: # ... mycnf: | [mysqld] max_connections=500 innodb_ft_min_token_size=5
The operator will use the value of this field to write the my.cnf
file in the filesystem of your database Pods.
Setting the Storage Capacity
The operator automatically creates a Persistent Volume (PV) and Persistent Volume Claim (PVC) to store your database’s data. It defaults to providing 2Gi of storage.
This can be changed using the datadirVolumeClaimTemplate
manifest field which allows you to override properties of the PVC resource produced by the operator. Set the resources.requests.storage
property to the capacity you require.
apiVersion: mysql.oracle.com/v2 kind: InnoDBCluster spec: # ... datadirVolumeClaimTemplate: resources: requests: storage: 10Gi
You should set this high enough that there’s plenty of room for your data to grow in the future. The operator doesn’t support in-place volume resizes so you’ll see an error if you try to increase the capacity in the future. Switching to a bigger volume would necessitate manual migration steps.
Pinning the MySQL Version
You can pin to a specific MySQL release with the spec.version
and spec.router.version
fields. This will prevent unintentional automatic upgrades. Select the same version for your MySQL Pods and router instances to guarantee compatibility.
apiVersion: mysql.oracle.com/v2 kind: InnoDBCluster spec: # ... version: 8.0.31 router: instances: 1 version: 8.0.31
Oracle’s MySQL Operator provides a convenient mechanism for running MySQL databases within a Kubernetes cluster. You can provision new replicated databases by creating InnoDBCluster
objects. This is much simpler than manually creating StatefulSets and services that expose regular MySQL containers.
Using the operator doesn’t impede your ability to control MySQL or your Kubernetes environment. You can customize your Pods by supplying your own manifest properties in the spec.podSpec
field and use your own MySQL config file with the steps shown above. The operator also offers integrated backup support, letting you copy your database to external storage on a recurring schedule.
Leave A Comment?