Skip to content

Install Percona Server for MySQL on Minikube

Minikube lets you run a Kubernetes cluster locally without a cloud provider. It works on Linux, Windows, and macOS using a hypervisor like VirtualBox, KVM/QEMU, VMware Fusion, Hyper-V, or Docker. This makes it perfect for testing the Operator before deploying it in a cloud or in production

Prerequisites

Before you begin, you need to install Minikube on your system. The installation includes three components:

  1. kubectl - the Kubernetes command-line tool
  2. A hypervisor - if you don’t already have one installed
  3. Minikube - the Minikube package itself

After installing Minikube, start it with increased resources to ensure the Operator runs smoothly:

minikube start --memory=4096 --cpus=3

This command downloads the necessary virtualized images, then initializes and starts your local Kubernetes cluster. The --memory=4096 and --cpus=3 parameters allocate more resources to the virtual machine, which helps the Operator run reliably.

Optional: Kubernetes Dashboard

You can optionally start the Kubernetes dashboard to visualize your cluster. Run:

minikube dashboard

This opens the dashboard in your default web browser, giving you a visual view of your cluster’s state.

Install the Operator

  1. Clone the repository and navigate into it:

    git clone -b v1.0.0 https://github.com/percona/percona-server-mysql-operator
    cd percona-server-mysql-operator
    
  2. Deploy the Operator to your Minikube cluster

    kubectl apply--server-side -f deploy/bundle.yaml
    
    Expected output
    customresourcedefinition.apiextensions.k8s.io/perconaservermysqlbackups.ps.percona.com created
    customresourcedefinition.apiextensions.k8s.io/perconaservermysqlrestores.ps.percona.com created
    customresourcedefinition.apiextensions.k8s.io/perconaservermysqls.ps.percona.com created
    serviceaccount/percona-server-mysql-operator created
    role.rbac.authorization.k8s.io/percona-server-mysql-operator-leaderelection created
    role.rbac.authorization.k8s.io/percona-server-mysql-operator created
    rolebinding.rbac.authorization.k8s.io/percona-server-mysql-operator-leaderelection created
    rolebinding.rbac.authorization.k8s.io/percona-server-mysql-operator created
    configmap/percona-server-mysql-operator-config created
    deployment.apps/percona-server-mysql-operator created
    

Configure and deploy your MySQL cluster

Since Minikube runs on a single node, the default configuration doesn’t fit. Use the minimal configuration adjusted for Minikube environment.

kubectl apply -f deploy/cr-minimal.yaml
Expected output
perconaservermysql.ps.percona.com/ps-cluster1 created

This creates a group-replication cluster with one Percona Server for MySQL instances and one HAProxy instance. For more configuration options, see the deploy/cr.yaml file and the Custom Resource Options reference.

Check the cluster status

The cluster creation process takes a few minutes. Monitor the status with:

kubectl get ps

Wait until the STATE column shows ready. This indicates your cluster is fully operational.

Expected output
NAME           REPLICATION         ENDPOINT                   STATE   MYSQL   ORCHESTRATOR   HAPROXY   ROUTER   AGE
ps-cluster1   group-replication    ps-cluster1-haproxy.default   ready   1                     1                  5m50s

Verify the cluster operation

It typically takes about ten minutes for the cluster to start. Once kubectl get ps shows the cluster status as ready, you can connect to it and start using your MySQL database.

To connect to Percona Server for MySQL you will need the password for the root user. Passwords are stored in the Secrets object, which was generated during the previous steps.

Here’s how to get it:

  1. List the Secrets objects.

    $ kubectl get secrets
    
    It will show you the list of Secrets objects (by default the Secrets object you are interested in has ps-cluster1-secrets name).

  2. Use the following command to get the password of the root user. Substitute ps-cluster1 with your value, if needed:

    $ kubectl get secret ps-cluster1-secrets -o yaml
    

    The command returns the YAML file with generated Secrets, including the root password, which should look as follows:

    ...
    data:
      ...
      root: <base64-encoded-password>
    
  3. The actual password is base64-encoded. Use the following command to bring it back to a human-readable form:

    $ echo '<base64-encoded-password>' | base64 --decode
    
  4. Run a container with mysql tool and connect its console output to your terminal. The following command will do this, naming the new Pod percona-client:

    $ kubectl run -i --rm --tty percona-client --image=percona/percona-server:8.4 --restart=Never -- bash -il
    

    It may require some time to execute the command and deploy the correspondent Pod.

  5. Now run mysql tool in the percona-client command shell using the password obtained from the Secret instead of the <root password> placeholder. The command will look different depending on whether the cluster uses load balancing with HAProxy (the default behavior) or uses MySQL Router (can be used with Group Replication clusters):

    mysql -h ps-cluster1-haproxy -uroot -p<root password>
    
    mysql -h ps-cluster1-router -uroot -p<root password>
    
    Expected output
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 1665
    Server version: 8.4.6-6.1 Percona Server (GPL), Release 6, Revision dbba4396
    
    Copyright (c) 2009-2025 Percona LLC and/or its affiliates
    Copyright (c) 2000, 2025, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    

    The following example uses the MySQL prompt to check the max_connections variable:

    SHOW VARIABLES LIKE "max_connections";
    
    Expected output
    +-----------------+-------+
    | Variable_name   | Value |
    +-----------------+-------+
    | max_connections | 158   |
    +-----------------+-------+
    1 row in set (0.02 sec)
    
    mysql> 
    

Last update: 2025-11-17