Table of Contents
When you create a vCluster, it needs a backing store. By default, it will be created with SQLite, but there are other options, such as etcd, MySQL, and PostgreSQL. Let's take a look at one of the new features that launched with vCluster Platform 4.1 - External Database Connector.
You can read more about the updates for vCluster Platform v4.1 in our changelog.
Intro
In this blog post we will walk through how to get the External Database Connector working with MySQL running in a vCluster. Why would you want to use anything other than the lightweight default?
- You are already running a relational database at scale
- You want to offload database HA clustering
- Backup / Recovery using a Cloud Provider
Previously, you would need to specify the database you were going to use for each vCluster, which required a connection string similar to:
"mysql://username:password@hostname:5432/vcluster-1"
This required manual configuration and was per vCluster. With the updates, you can now create a configuration using a secret and then reference it at the time of creation in the vCluster configuration, you can even use a template!
Requirements
In this demo, we are running everything on-prem. The username and password used for the MySQL database are not suggested for production.
This demo assumes that you have installed the following:
- Kubernetes Cluster
- vCluster CLI (Install Docs)
- vCluster Platform (Installation Docs)
- LoadBalancer Service (or NodePort if you modify the example)
If you already have a Database, you can skip much of the demo setup and start with the External Database Connector Secret section. To teach some of the other concepts of the vCluster Platform, we are going to use Templates and Apps.
Once you have vCluster Platform running (you could also use vcluster.cloud and then connect a cluster), move on to the next section where we will template out and create a vCluster that will host our MySQL Database.
MySQL Database App
We will start by creating an App in the UI. Head to Templates > Apps > Add app template. We will create this with kubectl. You could also use Helm if you have a Helm chart for MySQL.
This is a basic configuration for MySQL. Some of the configuration options we selected for this application are:
- Persistent Volume using the default Storage Class
- 20Gi storage request, which is probably too much for a demo
- Load Balancer for the service; other examples use NodePort
- Plain text MySQL credentials for demo purposes (using root:password)
For this demo we are just updating the Definition section and the Name so that we can find it when we configure the app within the vCluster template. Go ahead and fill in the definition with the application YAML below in the vCluster Platform UI and save.
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: LoadBalancer
ports:
- port: 3306
selector:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:latest
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
MySQL vCluster Template
Now that we have an App defined we can create a template and add the App to the template. To do this you will navigate to Templates > Virtual Clusters > Add Virtual Cluster Template.
Name your template something like vCluster MySQL. The definition section can either be left with the default options, or you can add the option to sync the ingress class fromHost with this YAML:
sync:
toHost:
ingresses:
enabled: true
fromHost:
ingressClasses:
enabled: true
controlPlane:
coredns:
enabled: true
embedded: true
The main section we want to focus on is the App section. This is where we will add the MySQL App that we created to the template. In the drop-down, you should see the App you just created; in my demo environment, I named it MySQL. Add the app and save the template.
Create the MySQL vCluster
Now that we have a template, we can create the MySQL virtual cluster and verify that we can connect to the database. In the Virtual Cluster section under your project, select “Create virtual cluster”, then select the template we just created. In my demo, it is named vCluster MySQL.
Once the vCluster has launched we can connect to it and verify connectivity to MySQL. Reference the name of the vCluster in the UI. You can also find it with `vcluster list`
$ vcluster list
NAME | NAMESPACE | STATUS | VERSION | CONNECTED | AGE
-----------------+-------------------------------+---------+----------------+-----------+-------------
vcluster-42r7g | loft-default-v-vcluster-42r7g | Running | 0.21.1 | | 20h7m57s
vcluster-fgkb2 | loft-default-v-vcluster-fgkb2 | Running | 0.21.1 | | 142h36m49s
vcluster-t2kjh | loft-default-v-vcluster-t2kjh | Running | 0.21.1 | | 118h56m16s
vcluster-w8zwn | loft-default-v-vcluster-w8zwn | Running | 0.21.1 | | 20h16m32s
In our example, the vCluster we want to connect to is w8zwn
- so we can head to the command line and connect to the cluster using:
vcluster connect vcluster-w8zwn
This will port forward and connect you directly to the vCluster, so you’ll need to open another terminal to interact with it.
The main reason we are connecting to the cluster is to pull the LoadBalancer IP and familiarize ourselves with using vcluster connect
. You can also find this information on the host cluster however you may have a ton of resources to look through. I’ll give you the commands to find it on both:
vCluster
$ kubectl get svc | grep -i mysql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql LoadBalancer 10.43.177.29 192.168.86.16 3306:32037/TCP 20h
Host Cluster
$ kubectl get svc --all-namespaces | grep -i w8zwn | grep -i loadbalancer
loft-default-v-vcluster-w8zwn mysql-x-default-x-vcluster-w8zwn LoadBalancer 10.43.177.29 192.168.86.16 3306:32037/TCP 20h
Now we know the IP address associated with our MySQL Database, let’s connect to it!
On a Mac:
mysqlsh --uri root@192.168.86.16:3306
Once connected, you can use show databases;
to see what has been populated. This information will update once we create a new vCluster using the External Database Connector, but first, we need to create the secret so that we can connect.
External Database Connector Secret
Now that we know the Database information we can create a secret with the relevant connection information. The secret will need to live in the vcluster-platform namespace, or whichever namespace was used for the vCluster Platform installation. In this demo the namespace is just vclsuter-platform
so we can use that for the example secret.
We will need to name it something relevant (save this information for the next step), select the namespace where vCluster Platform is installed, update the endpoint with the LoadBalancer IP address we created, update the password with “password” (super secure), update the port with 3306 since we left it default, and update the user as “root” which is the default.
apiVersion: v1
kind: Secret
metadata:
name: mysql-ext-db # this is a normal metadata name. A descriptive name is recommended. This will be used in a tenet vCluster's config to reference the connector secret
namespace: vcluster-platform # this is the namespace that vCluster Platform is installed in. "vcluster-platform" and "loft" are common values.
labels:
loft.sh/connector-type: "shared-database"
stringData:
endpoint: "192.168.86.16" # this could be a service endoint or an external hostname endpoint
password: "password"
port: "3306" # 3306 is a common port for database servers
user: "root"
Save the above configuration in a mysql-ext-db.yaml file and then create it on the host cluster. You might need to verify your context before creating this if you connected to the vCluster previously. If you have kubectx
installed, you can run the following:
$ kubectx
default
vcluster_vcluster-pqlxz_loft-default-v-vcluster-pqlxz_default
vcluster_vcluster-tk2c2_loft-default-v-vcluster-tk2c2_default
vcluster_vcluster-w8zwn_loft-default-v-vcluster-w8zwn_default
In my demo the “default” context is the host cluster. I’ll run this to switch contexts:
kubectx default
Then, create the secret:
kubectl create -f mysql-ext-db.yaml
$ kubectl get secret -n vcluster-platform | grep -i mysql
mysql-ext-db Opaque 4 20h
Now, we can actually create a virtual cluster using the MySQL Database as the backingStore.
vCluster Using the External Database
Head back to the UI and create a new template: Templates > Virtual Clusters > Add Virtual Cluster Template. Name this template “vCluster with ext-db” and this time we are going to update the Definition. We need to update the control plane to use a new backingStore. The backingStore is going to reference the secret we just created.
sync:
toHost:
ingresses:
enabled: true
controlPlane:
coredns:
enabled: true
embedded: true
backingStore:
database:
external:
connector: "mysql-ext-db"
Update the definition then save the template. Now it’s time to create the virtual cluster. Head back to Virtual Clusters > Create virtual cluster. Use the template we just created. Wait for the virtual cluster to come up. Once it’s up we can verify that a new database has been created for the virtual cluster in MySQL.
mysqlsh --uri root@192.168.86.16:3306
show databases;
(removed other default MySQL DBs to show the desired DB)
+----------------------------------+
| Database |
+----------------------------------+
| 19ae9b4871dbde0e5146e4d6ae31c8e8 |
+----------------------------------+
5 rows in set (0.0075 sec)
The new database has been created: 19ae9b4871dbde0e5146e4d6ae31c8e8
.
If you want to explore further, you can use 19ae9b4871dbde0e5146e4d6ae31c8e8;
and then show tables;
+--------------------------------------------+
| Tables_in_19ae9b4871dbde0e5146e4d6ae31c8e8 |
+--------------------------------------------+
| kine |
+--------------------------------------------+
1 row in set (0.0181 sec)
Success! We created a new vCluster that uses our MySQL database for the dataStore.
Conclusion
In this post we showed some of the useful features of the vCluster Platform. If you already are managing a database, backing it up with the ability to restore, or just want to store your vCluster information somewhere specific, then this will make it easier to set up and scale out.
As always, your feedback is valuable and something we are interested in. Join our slack to ask questions. If you run into issues head to GitHub and open an issue.