<p>I want to deploy MySQL-router in Kubernetes working as a service.</p>
<p>My plan..</p>
<ul>
<li>Deploy MySQL-router inside k8 and expose MySQL-router as a service using <code>LoadBalancer</code> (MetalLB)</li>
<li>Applications running inside k8 sees <code>mysql-router</code> service as its database.</li>
<li>MySQL-router sends application data to outside InnoDB cluster.</li>
</ul>
<p>I tried to deploy using:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-router
  namespace: mysql-router
spec:
  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: &quot;192.168.123.130&quot;
        - name: MYSQL_PORT
          value: &quot;3306&quot;
        - name: MYSQL_USER
          value: &quot;root&quot;
        - name: MYSQL_PASSWORD
          value: &quot;root@123&quot;
        imagePullPolicy: Always
        ports:
        - containerPort: 6446
</code></pre>
<p><code>192.168.123.130</code> is MySQL cluster Master IP.</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: mysql-router-service
  namespace: mysql-router
  labels:
    app: mysql-router
spec:
  selector:
    app: mysql-router
  ports:
  - protocol: TCP
    port: 6446
  type: LoadBalancer
  loadBalancerIP: 192.168.123.123
</code></pre>
<p>When I check <code>mysql-router</code> container logs, I see something like this:</p>
<pre><code>Waiting for mysql server 192.168.123.130 (0/12)
Waiting for mysql server 192.168.123.130 (1/12)
Waiting for mysql server 192.168.123.130 (2/12)
....
</code></pre>
<p>After setting my external MySQL cluster info in deployment, I get following errors:</p>
<blockquote>
<p>Successfully contacted mysql server at 192.168.123.130. Checking for cluster state.
Can not connect to database. Exiting.</p>
</blockquote>
<p>I can not deploy <code>mysql-router</code> without specifying <code>MYSQL_HOST</code>. What am I missing here?</p>
<p>My ideal deployment</p>
<p><a href="https://i.stack.imgur.com/R817O.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/R817O.png" alt="Deployment" /></a></p>

<p>Of course you have to provide the MySQL Host. You could doing this with <code>k8s DNS</code> which setup with in the services.</p>
<p>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.</p>
<h1>Examples</h1>
<p>For examples below i use <code>dynamic volume provisioning</code> for data using <code>openebs-hostpath</code> And using <code>StatefulSet</code> for the MySQL Server.</p>
<h2>Deployment</h2>
<h3>MySQL Router :</h3>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-router
  namespace: mysql-router
spec:
  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: &quot;mariadb-galera.galera-cluster&quot;
        - name: MYSQL_PORT
          value: &quot;3306&quot;
        - name: MYSQL_USER
          value: &quot;root&quot;
        - name: MYSQL_PASSWORD
          value: &quot;root@123&quot;
        imagePullPolicy: Always
        ports:
        - containerPort: 3306
</code></pre>
<h3>MySQL Server</h3>
<pre><code>apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: galera-cluster
  name: mariadb-galera
spec:
  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=&quot;${MY_POD_NAME#&quot;mariadb-galera-&quot;}&quot;
          if [[ &quot;$NODE_ID&quot; -eq &quot;0&quot; ]]; 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: &quot;false&quot;
        - 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: &quot;no&quot;
        - name: MARIADB_ENABLE_TLS
          value: &quot;no&quot;
        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
</code></pre>
<h2>Services</h2>
<h3>MySQL Router Service</h3>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: mysql-router-service
  namespace: mysql-router
  labels:
    app: mysql-router
spec:
  selector:
    app: mysql-router
  ports:
  - protocol: TCP
    port: 3306
  type: LoadBalancer
  loadBalancerIP: 192.168.123.123
</code></pre>
<h3>MySQL Service</h3>
<pre><code>apiVersion: v1
kind: Service
metadata:
  namespace: galera-cluster
  name: mariadb-galera
  labels:
    app: mariadb-galera
spec:
  type: ClusterIP
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mariadb-galera
---
apiVersion: v1
kind: Service
metadata:
  namespace: galera-cluster
  name: mariadb-galera-headless
  labels:
    app: mariadb-galera
spec:
  type: ClusterIP
  ports:
  - name: galera
    port: 4567
  - name: ist
    port: 4568
  - name: sst
    port: 4444
  selector:
    app: mariadb-galera
</code></pre>
