Exposing cluster¶
The Operator provides entry points for accessing the database by client applications in several scenarios. In either way the cluster is exposed with regular Kubernetes Service objects , configured by the Operator.
This document describes the usage of Custom Resource manifest options to expose the clusters deployed with the Operator. The expose options vary for different replication types: Asynchronous and Group Replication .
Asynchronous Replication¶
Exposing cluster with HAProxy¶
Percona Operator for MySQL provides load balancing and proxy service with HAProxy (enabled by default).
You can control whether to use it or not by enabling or disabling it via the
haproxy.enabled
option in the deploy/cr.yaml
configuration file.
The following example turns on the asynchronous replication and enables HAProxy:
mysql:
clusterType: async
...
haproxy:
enabled: true
size: 3
image: perconalab/percona-xtradb-cluster-operator:0.10.0-haproxy
The resulting HAProxy setup will contain the cluster1-haproxy
service
listening on ports 3306 (MySQL primary), 3307 (MySQL replicas), and 3309 (the proxy protocol
useful for operations such as asynchronous calls).
Note
The Operator currently supports using HAProxy not only with asynchronous replication clusters, but also with group replication clusters.
When the cluster is configured in this way, you can find the endpoint (the
public IP address of the load balancer in our example) by getting the Service
object with the kubectl get service
command:
$ kubectl get service cluster1-haproxy
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster1-haproxy ClusterIP 10.76.2.102 <none> 3306/TCP,3307/TCP,3309/TCP 2m32s
Exposing cluster without HAProxy¶
With Asynchronous replication
the cluster can be also exposed through a Kubernetes Service called
<CLUSTER_NAME>-mysql-primary
: for example, cluster1-mysql-primary
.
This Service is created by default and is always present. You can change the type of the Service object by setting mysql.primaryServiceType variable in the Custom Resource.
The following example exposes the Primary node of the asynchronous cluster with the LoadBalancer object:
mysql:
clusterType: async
...
primaryServiceType: LoadBalancer
When the cluster is configured in this way, you can find the endpoint (the
public IP address of the load balancer in our example) by getting the Service
object with the kubectl get service
command:
$ kubectl get service cluster1-mysql-primary
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster1-mysql-primary LoadBalancer 10.40.37.98 35.192.172.85 3306:32146/TCP,33062:31062/TCP,33060:32026/TCP,6033:30521/TCP 3m31s
As you could notice, this command also shows mapped ports the application can
use to communicate with MySQL primary instance (e.g. 3306
for the classic
MySQL protocol, or 33060
for MySQL X Protocol
useful for operations such as asynchronous calls).
Group Replication¶
Group replication clusters can be configured to use either HAProxy or MySQL Router . Group replication cluster can be exposed with HAProxy similarly to the asynchronous cluster.
If group replication cluster is configured with MySQL Router, it can be
exposed through a Kubernetes Service called <CLUSTER_NAME>-router
: for example,
cluster1-router
. Network design in this case looks like this:
MySQL Router can be configured via the router section. In particular, the router.expose.type option sets the type of the correspondent Kubernetes Service object. The following example exposes MySQL Router through a LoadBalancer object:
mysql:
clusterType: group-replication
...
router:
expose:
type: LoadBalancer
When the cluster is configured in this way, you can find the endpoint (the
public IP address of the load balancer in our example) by getting the Service
object with the kubectl get service
command:
$ kubectl get service cluster1-router
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-cluster-router LoadBalancer 10.20.22.90 35.223.42.238 6446:30852/TCP,6447:31694/TCP,6448:31515/TCP,6449:31686/TCP 18h
As you could notice, this command also shows mapped ports the application can use to communicate with MySQL Router:
3306
- read/write, default MySQL clients connection,33062
- read/write, port for MySQL administrative connections,6446
- read/write, routing traffic to a Primary node,6447
- read-only, load balancing the traffic across Replicas.
Additionally, ports 6448
and 6449
are available in the same way to
connect via MySQL X Protocol
useful for operations such as asynchronous calls.
Alternatively, you can find the endpoint to connect to by kubectl get ps
command:
$ kubectl get ps
NAME REPLICATION ENDPOINT STATE AGE
cluster1 group-replication 35.239.63.143 ready 10m
Service per Pod¶
Still, sometimes it is required to expose all MySQL instances, where each of them gets its own IP address (e.g. in case of load balancing implemented on the application level).
This is possible by setting the following options in spec.mysql section.
- mysql.expose.enabled enables or disables exposure of MySQL instances,
- mysql.expose.type defines the Kubernetes Service object type.
The following example creates a dedicated LoadBalancer Service for each node of the MySQL cluster:
mysql:
expose:
enabled: true
type: LoadBalancer
When the cluster instances are exposed in this way, you can find the
corresponding Services with the kubectl get services
command:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
cluster1-mysql-0 LoadBalancer 10.40.44.110 104.198.16.21 3306:31009/TCP,33062:31319/TCP,33060:30737/TCP,6033:30660/TCP 75s
cluster1-mysql-1 LoadBalancer 10.40.42.5 34.70.170.187 3306:30601/TCP,33062:30273/TCP,33060:30910/TCP,6033:30847/TCP 75s
cluster1-mysql-2 LoadBalancer 10.40.42.158 35.193.50.44 3306:32042/TCP,33062:31576/TCP,33060:31656/TCP,6033:31448/TCP 75s
As you could notice, this command also shows mapped ports the application can
use to communicate with MySQL instances (e.g. 3306
for the classic MySQL
protocol, or 33060
for MySQL X Protocol
useful for operations such as asynchronous calls).