Tutorial

This hands-on tutorial aims to help you learn how to deploy Charmed MySQL Router on LXD or Kubernetes and become familiar with its available operations.

If you are not sure which path to take, we recommend following this tutorial on LXD by following the “VM” tabs.

Prerequisites

While this tutorial intends to guide you as you deploy Charmed MySQL and MySQL Router for the first time, it will be most beneficial if:

  • You have some experience using a Linux-based CLI

  • You are familiar with MySQL concepts such as replication and users.

  • Your computer fulfils the minimum system requirements


Set up the environment

First, we will set up a cloud environment using Multipass with LXD, MicroK8s and Juju. This is the quickest and easiest way to get your machine ready for using Charmed MySQL.

Create a Multipass VM

Multipass is a quick and easy way to launch virtual machines running Ubuntu. It uses the cloud-init standard to install and configure all the necessary parts automatically.

Install Multipass from the snap store:

user@my-pc:~$
sudo snap install multipass

Spin up a new VM using multipass launch with the charm-dev cloud-init configuration:

user@my-pc:~$
multipass launch --cpus 4 --memory 8G --disk 50G --name my-vm charm-dev

This may take several minutes if it’s the first time you launch this VM.

As soon as the new VM has started, access it:

user@my-pc:~$
multipass shell my-vm
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-63-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro
...

Tip

All necessary components have been pre-installed inside VM already, like LXD, MicroK8s and Juju. The files /var/log/cloud-init.log and /var/log/cloud-init-output.log contain all low-level installation details.

Set up Juju

Since my-vm already has Juju, LXD and MicroK8s installed, we can go ahead and bootstrap a cloud. In this tutorial, we will use a local LXD controller.

We will call our new controller “overlord”, but you can give it any name you’d like:

ubuntu@my-vm:~$
juju bootstrap localhost overlord
ubuntu@my-vm:~$
juju bootstrap microk8s overlord

The controller can work with different Juju models. Set up a specific model for Charmed MySQL named tutorial:

ubuntu@my-vm:~$
juju add-model tutorial

You can now view the model you created by running the command juju status.

ubuntu@my-vm:~$
juju status
Model     Controller  Cloud/Region         Version  SLA          Timestamp
tutorial  overlord    localhost/localhost  3.5.2    unsupported  15:31:14+02:00

Model "admin/tutorial" is empty.
ubuntu@my-vm:~$
juju status
Model     Controller  Cloud/Region         Version  SLA          Timestamp
tutorial  overlord    microk8s/localhost   3.5.2    unsupported  15:31:14+02:00

Model "admin/tutorial" is empty.

Deploy Charmed MySQL and MySQL Router

To deploy the two charms, run the following commands:

ubuntu@my-vm:~$
juju deploy mysql --channel 8.0/stable
ubuntu@my-vm:~$
juju deploy mysql-router --channel dpe/candidate
ubuntu@my-vm:~$
juju deploy mysql-k8s --channel 8.0/stable --trust
ubuntu@my-vm:~$
juju deploy mysql-router-k8s --channel 8.0/stable --trust

Juju will now fetch the charms from Charmhub and deploy them to LXD or a MicroK8s cloud. This process can take several minutes depending on how provisioned (RAM, CPU, etc) your machine is.

You can track the progress by running:

ubuntu@my-vm:~$
juju status --watch 1s

Tip

You can open a separate terminal window, enter the same Multipass VM, and keep juju status --watch 1s permanently running in it.

When the application is ready, juju status will show MySQL Router in a blocked state because it is missing an integration with MySQL.

To integrate them, run

user@my-vm:~$
juju integrate mysql mysql-router
user@my-vm:~$
juju integrate mysql-k8s mysql-router-k8s

Now, juju status will report new type of blocked state: Missing relation: database as it waits for a client to consume DB service.

In this tutorial, we will connect to the data integrator charm. This is a bare-bones charm that allows for central management of database users. It automatically provides credentials and endpoints that are needed to connect with a charmed database application.

Deploy data-integrator, associate it to a new database called test-database, and relate it to MySQL Router:

user@my-vm:~$
juju deploy data-integrator --config database-name=test-database
user@my-vm:~$
juju integrate data-integrator mysql-router
user@my-vm:~$
juju deploy data-integrator --config database-name=test-database
user@my-vm:~$
juju integrate data-integrator mysql-router-k8s

In a few seconds, its status will no longer be blocked.

Access the database

Connecting to the database requires that you know the values for host, username and password. To retrieve the necessary fields, run data-integrator action get-credentials:

user@my-vm:~$
juju run data-integrator/leader get-credentials

This should return the username and password

The host value is the IP address that can be found with juju status (the application hosting the MySQL Router application):

To access the MySQL database via MySQL Router, choose read-write (port 6446) or read-only (port 6447) endpoints:

user@my-vm:~$
mysql -h 10.152.183.52 -P6446 -urelation-4-6 -pNu7wK85QU7dpVX66X56lozji test-database

Inside the MySQL shell, list the databases available on the host with show databases:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| test-database      |
+--------------------+
3 rows in set (0.00 sec)

You can now interact with MySQL directly using any MySQL Queries. For example entering SELECT VERSION(), CURRENT_DATE; should output something like:

mysql> SELECT VERSION(), CURRENT_DATE;
+------------------------+--------------+
| VERSION()              | CURRENT_DATE |
+------------------------+--------------+
| 8.4.7-0ubuntu0.26.04.1 | 2026-01-22   |
+------------------------+--------------+
1 row in set (0.00 sec)

Feel free to test out any other MySQL queries. When you’re ready to leave the MySQL shell you can just type exit. Now you will be in your original shell where you first started the tutorial; here you can interact with Juju and LXD.

Remove or reset the user

Removing the integration automatically removes the user that was created when the integration was created.

To remove the integration, run the following command:

ubuntu@my-vm:~$
juju remove-relation data-integrator mysql
ubuntu@my-vm:~$
juju remove-relation data-integrator mysql-k8s

If you try to connect to the same MySQL you just used in Access the integrated database, you’ll get an “Access denied” error. This is expected, since the user no longer exists after removing the integration. However, note that data remains on the server at this stage.

To create a user again, re-integrate the applications:

ubuntu@my-vm:~$
juju integrate data-integrator mysql-router
ubuntu@my-vm:~$
juju integrate data-integrator mysql-router-k8s

Re-integrating generates a new user and password. You can obtain these credentials as before, with the get-credentials action, and connect to the database with this new credentials.

From here you will see all of your data is still present in the database.

Scale MySQL Router units

To add two more units to your MySQL Router deployment, run

ubuntu@my-vm:~$
juju add-unit mysql-router -n 2
ubuntu@my-vm:~$
juju scale-application mysql-router-k8s 3

You can now watch the scaling process in live using: juju status --watch 1s.

It usually takes several minutes for new cluster members to be added. You’ll know that all three nodes are in sync when juju status reports:

  • Workload is active.

  • Agent is idle.

You can scale Charmed MySQL in the same way:

ubuntu@my-vm:~$
juju add-unit mysql -n 2
ubuntu@my-vm:~$
juju scale-application mysql-k8s 3

Make sure all units are active using juju status.

Note

The maximum number of Charmed MySQL units in a single Juju application is 9. This is a limitation of MySQL replication.

Read more about all limitations in the official MySQL documentation.

Remove units

Removing a unit from the application scales the replicas down.

On VM, specify the unit to remove (in this example, mysql-router/2):

ubuntu@my-vm:~$
juju remove-unit mysql-router/2

On K8s, specify the desired number of units:

ubuntu@my-vm:~$
juju scale-application mysql-router-k8s 2

Enable encryption with TLS

Transport Layer Security (TLS) is a protocol used to encrypt data exchanged between two applications. Essentially, it secures data transmitted over a network.

Typically, enabling TLS internally within a highly available database or between a highly available database and client/server applications requires a high level of expertise. This has all been encoded into Charmed MySQL so that configuring TLS requires minimal effort on your end.

TLS is enabled by integrating Charmed MySQL with the Self-signed certificates charm. This charm centralises TLS certificate management consistently and handles operations like providing, requesting, and renewing TLS certificates.

Caution

Self-signed certificates are not recommended for a production environment.

Check this guide for an overview of the TLS certificates charms available.

Before enabling TLS on Charmed MySQL, we must deploy the self-signed-certificates charm:

ubuntu@my-vm:~$
juju deploy self-signed-certificates --channel 1/stable --config ca-common-name="Tutorial CA"

Wait until self-signed-certificates is up and active, using juju status --watch 1s to monitor its progress.

To enable TLS on Charmed MySQL Router, integrate the two applications:

ubuntu@my-vm:~$
juju integrate mysql-router self-signed-certificates
ubuntu@my-vm:~$
juju integrate mysql-router-k8s self-signed-certificates

Use openssl to connect to MySQL Router and check the TLS certificate in use:

ubuntu@my-vm:~$
juju ssh mysql-router/0 "openssl s_client -showcerts -starttls mysql -unix /var/snap/charmed-mysql/common/run/mysqlrouter/mysql.sock < /dev/null  | openssl x509 -text | grep Issuer"
...
    Issuer: C = US, CN = Tutorial CA
...
ubuntu@my-vm:~$
juju ssh mysql-router-k8s/0 "openssl s_client -showcerts -starttls mysql -connect 127.0.0.1:6446  < /dev/null  | openssl x509 -text | grep Issuer"
...
    Issuer: C = US, CN = Tutorial CA
...

Congratulations! MySQL Router is now using a TLS certificate generated by the external application self-signed-certificates.

To remove the external TLS and return to the locally generated one, remove the relation:

ubuntu@my-vm:~$
juju remove-relation mysql-router self-signed-certificates
ubuntu@my-vm:~$
juju remove-relation mysql-router-k8s self-signed-certificates

Now, if you check the certificates again with openssl you’ll see an output similar to:

Issuer: CN = MySQL_Router_Auto_Generated_CA_Certificate

The Charmed MySQL Router application reverted to the placeholder certificate that was created locally during the installation.

Clean up your environment

To exit the Multipass VM, press Ctrl + D or type exit.

If you’d like to keep your MySQL environment for later, simply stop your VM with:

user@my-pc:~$
multipass stop my-vm

If you’re done with testing and would like to free up resources on your machine, you can remove the VM entirely.

Caution

When you remove VM as shown below, you will lose all the data in MySQL and any other applications inside Multipass VM!

For more information, see the docs for multipass delete.

Delete your VM and its data by running:

user@my-pc:~$
multipass delete --purge my-vm