MySQL router in kubernetes as a service MySQL router in kubernetes as a service kubernetes kubernetes

MySQL router in kubernetes as a service


Of course you have to provide the MySQL Host. You could doing this with k8s DNS which setup with in the services.

MySQL Router is middleware that provides transparent routing between your application and any backend MySQL Servers. It can be used for a wide variety of use cases, such as providing high availability and scalability by effectively routing database traffic to appropriate backend MySQL Servers.

Examples

For examples below i use dynamic volume provisioning for data using openebs-hostpath And using StatefulSet for the MySQL Server.

Deployment

MySQL Router :

apiVersion: apps/v1kind: Deploymentmetadata:  name: mysql-router  namespace: mysql-routerspec:  replicas: 1   selector:    matchLabels:      app: mysql-router  template:    metadata:      labels:        app: mysql-router        version: v1    spec:      containers:      - name: mysql-router        image: mysql/mysql-router        env:        - name: MYSQL_HOST          value: "mariadb-galera.galera-cluster"        - name: MYSQL_PORT          value: "3306"        - name: MYSQL_USER          value: "root"        - name: MYSQL_PASSWORD          value: "root@123"        imagePullPolicy: Always        ports:        - containerPort: 3306

MySQL Server

apiVersion: apps/v1kind: StatefulSetmetadata:  namespace: galera-cluster  name: mariadb-galeraspec:  podManagementPolicy: OrderedReady  replicas: 1  selector:    matchLabels:      app: mariadb-galera  serviceName: mariadb-galera  template:    metadata:      labels:        app: mariadb-galera    spec:      restartPolicy: Always      securityContext:        fsGroup: 1001        runAsUser: 1001      containers:      - command:        - bash        - -ec        - |          # Bootstrap from the indicated node          NODE_ID="${MY_POD_NAME#"mariadb-galera-"}"          if [[ "$NODE_ID" -eq "0" ]]; then              export MARIADB_GALERA_CLUSTER_BOOTSTRAP=yes              export MARIADB_GALERA_FORCE_SAFETOBOOTSTRAP=no          fi          exec /opt/bitnami/scripts/mariadb-galera/entrypoint.sh /opt/bitnami/scripts/mariadb-galera/run.sh        env:        - name: MY_POD_NAME          valueFrom:            fieldRef:              apiVersion: v1              fieldPath: metadata.name        - name: BITNAMI_DEBUG          value: "false"        - name: MARIADB_GALERA_CLUSTER_NAME          value: galera        - name: MARIADB_GALERA_CLUSTER_ADDRESS          value: gcomm://mariadb-galera.galera-cluster        - name: MARIADB_ROOT_PASSWORD          value: root@123        - name: MARIADB_DATABASE          value: my_database        - name: MARIADB_GALERA_MARIABACKUP_USER          value: mariabackup        - name: MARIADB_GALERA_MARIABACKUP_PASSWORD          value: root@123        - name: MARIADB_ENABLE_LDAP          value: "no"        - name: MARIADB_ENABLE_TLS          value: "no"        image: docker.io/bitnami/mariadb-galera:10.4.13-debian-10-r23        imagePullPolicy: IfNotPresent        livenessProbe:          exec:            command:            - bash            - -ec            - |              exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD          failureThreshold: 3          initialDelaySeconds: 120          periodSeconds: 10          successThreshold: 1          timeoutSeconds: 1        name: mariadb-galera        ports:        - containerPort: 3306          name: mysql          protocol: TCP        - containerPort: 4567          name: galera          protocol: TCP        - containerPort: 4568          name: ist          protocol: TCP        - containerPort: 4444          name: sst          protocol: TCP        readinessProbe:          exec:            command:            - bash            - -ec            - |              exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD          failureThreshold: 3          initialDelaySeconds: 30          periodSeconds: 10          successThreshold: 1          timeoutSeconds: 1        volumeMounts:        - mountPath: /opt/bitnami/mariadb/.bootstrap          name: previous-boot        - mountPath: /bitnami/mariadb          name: data        - mountPath: /opt/bitnami/mariadb/conf          name: mariadb-galera-config      volumes:      - emptyDir: {}        name: previous-boot      - configMap:          defaultMode: 420          name: my.cnf        name: mariadb-galera-config  volumeClaimTemplates:  - apiVersion: v1    metadata:      name: data    spec:      storageClassName: openebs-hostpath      accessModes:      - ReadWriteOnce      resources:        requests:          storage: 20Gi

Services

MySQL Router Service

apiVersion: v1kind: Servicemetadata:  name: mysql-router-service  namespace: mysql-router  labels:    app: mysql-routerspec:  selector:    app: mysql-router  ports:  - protocol: TCP    port: 3306  type: LoadBalancer  loadBalancerIP: 192.168.123.123

MySQL Service

apiVersion: v1kind: Servicemetadata:  namespace: galera-cluster  name: mariadb-galera  labels:    app: mariadb-galeraspec:  type: ClusterIP  ports:  - name: mysql    port: 3306  selector:    app: mariadb-galera---apiVersion: v1kind: Servicemetadata:  namespace: galera-cluster  name: mariadb-galera-headless  labels:    app: mariadb-galeraspec:  type: ClusterIP  ports:  - name: galera    port: 4567  - name: ist    port: 4568  - name: sst    port: 4444  selector:    app: mariadb-galera


What you need its #1 communication from App1-x to Mysql router and #2 a VIP/LB from MysqlRoutere to external mysql instances.

Well start with #2 configuration of Mysql instances VIP. You will need a service without selector.

apiVersion: v1kind: Servicemetadata:  name: mysql-servicespec:  ports:  - name: mysql    port: 3306    protocol: TCP    targetPort: 3306  sessionAffinity: None  type: ClusterIP---apiVersion: v1kind: Endpointsmetadata:  name: mysql-servicesubsets:- addresses:  - ip: 192.168.123.130  - ip: 192.168.123.131  - ip: 192.168.123.132  ports:  - name: mysql    port: 3306    protocol: TCP

You don't need LoadBalancer cuz you will connect only inside cluster. So, use ClusterIp instead.

#1 Create MysqlRouter deployment.

apiVersion: apps/v1kind: Deploymentmetadata:  name: mysql-router  namespace: mysql-routerspec:  replicas: 1   selector:    matchLabels:      app: mysql-router  template:    metadata:      labels:        app: mysql-router        version: v1    spec:      containers:      - name: mysql-router        image: mysql/mysql-router        env:        - name: MYSQL_HOST          value: "mysql-service"        - name: MYSQL_PORT          value: "3306"        - name: MYSQL_USER          value: "root"        - name: MYSQL_PASSWORD          value: "root@123"        imagePullPolicy: Always        ports:        - containerPort: 6446

To connect to external MySQL instances trough VIP/ClusterIP use mysql-service service and if deployment and service is in same namespace use mysql-service as hostname or put there a CLusterIP from kubectl get service mysql-service

apiVersion: v1kind: Servicemetadata:  name: mysql-router-service  namespace: mysql-router  labels:    app: mysql-routerspec:  selector:    app: mysql-router  ports:  - name: mysql    port: 6446    protocol: TCP    targetPort: 6446  type: ClusterIP

You can connect within kubernetes cluster to mysql-router-service hostname in same namespace and outside namespace to mysql-router-service.namespace.svc or outside kubernetes cluster use NodePort or LoadBalancer.