New to KubeDB? Please start here.

Using Custom Configuration File

KubeDB supports providing custom configuration for MySQL. This tutorial will show you how to use KubeDB to run a MySQL database with custom configuration.

Before You Begin

  • At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using minikube.

  • Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps here.

  • To keep things isolated, this tutorial uses a separate namespace called demo throughout this tutorial.

  $ kubectl create ns demo
  namespace/demo created
  
  $ kubectl get ns demo
  NAME    STATUS  AGE
  demo    Active  5s

Note: Yaml files used in this tutorial are stored in docs/examples/mysql folder in GitHub repository kubedb/cli.

Overview

MySQL allows to configure database via configuration file. The default configuration for MySQL can be found in /etc/mysql/my.cnf file. When MySQL starts, it will look for custom configuration file in /etc/mysql/conf.d directory. If configuration file exist, MySQL instance will use combined startup setting from both /etc/mysql/my.cnf and *.cnf files in /etc/mysql/conf.d directory. This custom configuration will overwrite the existing default one. To know more about configuring MySQL see here.

At first, you have to create a config file with .cnf extension with your desired configuration. Then you have to put this file into a volume. You have to specify this volume in spec.configSource section while creating MySQL crd. KubeDB will mount this volume into /etc/mysql/conf.d directory of the database pod.

In this tutorial, we will configure max_connections and read_buffer_size via a custom config file. We will use configMap as volume source.

Custom Configuration

At first, let’s create my-config.cnf file setting max_connections and read_buffer_size parameters.

cat <<EOF > my-config.cnf
[mysqld]
max_connections = 200
read_buffer_size = 1048576
EOF

$ cat my-config.cnf
[mysqld]
max_connections = 200
read_buffer_size = 1048576

Here, read_buffer_size is set to 1MB in bytes.

Now, create a configMap with this configuration file.

 $ kubectl create configmap -n demo my-custom-config --from-file=./my-config.cnf
configmap/my-custom-config created

Verify the config map has the configuration file.

$ kubectl get configmap -n demo my-custom-config -o yaml
apiVersion: v1
data:
  my-config.cnf: |
    [mysqld]
    max_connections = 200
    read_buffer_size = 1048576
kind: ConfigMap
metadata:
  name: my-custom-config
  namespace: demo
  ...

Now, create MySQL crd specifying spec.configSource field.

$ kubectl apply -f https://raw.githubusercontent.com/kubedb/cli/0.9.0-rc.1/docs/examples/mysql/configuration/mysql-custom.yaml
mysql.kubedb.com/custom-mysql created

Below is the YAML for the MySQL crd we just created.

apiVersion: kubedb.com/v1alpha1
kind: MySQL
metadata:
  name: custom-mysql
  namespace: demo
spec:
  version: "8.0-v1"
  configSource:
    configMap:
      name: my-custom-config
  storage:
    storageClassName: "standard"
    accessModes:
    - ReadWriteOnce
    resources:
      requests:
        storage: 50Mi

Now, wait a few minutes. KubeDB operator will create necessary PVC, statefulset, services, secret etc. If everything goes well, we will see that a pod with the name custom-mysql-0 has been created.

Check that the statefulset’s pod is running

$ kubectl get pod -n demo
NAME             READY     STATUS    RESTARTS   AGE
custom-mysql-0   1/1       Running   0          44s

Check the pod’s log to see if the database is ready

$ kubectl logs -f -n demo custom-mysql-0
Initializing database
.....
Database initialized
Initializing certificates
...
Certificates initialized
MySQL init process in progress...
....
MySQL init process done. Ready for start up.
....
2018-07-10T06:12:46.957611Z 0 [Note] /usr/sbin/mysqld: ready for connections. Version: '8.0.3-rc-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
....

Once we see [Note] /usr/sbin/mysqld: ready for connections. in the log, the database is ready.

Now, we will check if the database has started with the custom configuration we have provided.

First, deploy phpMyAdmin to connect with the MySQL database we have just created.

 $ kubectl create -f https://raw.githubusercontent.com/kubedb/cli/0.9.0-rc.1/docs/examples/mysql/quickstart/demo-1.yaml
deployment.extensions/myadmin created
service/myadmin created

Then, open your browser and go to the following URL: http://{cluster-ip}:{myadmin-svc-nodeport}. For minikube you can get this URL by running the following command:

$ minikube service myadmin -n demo --url
http://192.168.99.100:30039

Now, let’s connect to the database from the phpMyAdmin dashboard using the database pod IP and MySQL user password.

$ kubectl get pods custom-mysql-0 -n demo -o yaml | grep IP
  hostIP: 10.0.2.15
  podIP: 172.17.0.6

$ kubectl get secrets -n demo custom-mysql-auth -o jsonpath='{.data.\user}' | base64 -d
root

$ kubectl get secrets -n demo custom-mysql-auth -o jsonpath='{.data.\password}' | base64 -d
MLO5_fPVKcqPiEu9

Once, you have connected to the database with phpMyAdmin go to Variables tab and search for max_connections and read_buffer_size. Here are some screenshot showing those configured variables. max_connections

read_buffer_size

Cleaning up

To cleanup the Kubernetes resources created by this tutorial, run:

kubectl patch -n demo my/custom-mysql -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge"
kubectl delete -n demo my/custom-mysql

kubectl patch -n demo drmn/custom-mysql -p '{"spec":{"wipeOut":true}}' --type="merge"
kubectl delete -n demo drmn/custom-mysql

kubectl delete -n demo configmap my-custom-config
kubectl delete deployment -n demo myadmin
kubectl delete service -n demo myadmin

kubectl delete ns demo

If you would like to uninstall KubeDB operator, please follow the steps here.

Next Steps

Subscribe to our free technical newsletter!

Join thousands of subscribers and stay up-to-date on AppsCode.