MySQL kubernetes 中的路由器即服务

MySQL router in kubernetes as a service

我想在 Kubernetes 中部署 MySQL-路由器作为服务。

我的计划..

我尝试使用以下方式进行部署:

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: "192.168.123.130"
        - name: MYSQL_PORT
          value: "3306"
        - name: MYSQL_USER
          value: "root"
        - name: MYSQL_PASSWORD
          value: "root@123"
        imagePullPolicy: Always
        ports:
        - containerPort: 6446

192.168.123.130 是 MySQL 集群主 IP。

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

当我检查 mysql-router 容器日志时,我看到类似这样的内容:

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)
....

在部署中设置外部 MySQL 集群信息后,出现以下错误:

Successfully contacted mysql server at 192.168.123.130. Checking for cluster state. Can not connect to database. Exiting.

如果不指定 MYSQL_HOST,我无法部署 mysql-router。我在这里错过了什么?

我的理想部署

当然你必须提供 MySQL 主机。您可以使用在服务中设置的 k8s DNS 来执行此操作。

MySQL 路由器是在您的应用程序和任何后端 MySQL 服务器之间提供透明路由的中间件。它可用于各种用例,例如通过有效地将数据库流量路由到适当的后端 MySQL 服务器来提供高可用性和可扩展性。

例子

在下面的示例中,我使用 dynamic volume provisioning 作为数据,使用 openebs-hostpath 并使用 StatefulSet 作为 MySQL 服务器。

部署

MySQL 路由器:

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: "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 服务器

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="${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

服务

MySQL 路由器服务

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

MySQL 服务

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

你需要它从 App1-x 到 Mysql 路由器的 #1 通信和从 MysqlRoutere 到外部 mysql 实例的 #2 VIP/LB。

我们从 Mysql 实例 VIP 的 #2 配置开始。您将需要 service without selector.

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  ports:
  - name: mysql
    port: 3306
    protocol: TCP
    targetPort: 3306
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
  name: mysql-service
subsets:
- addresses:
  - ip: 192.168.123.130
  - ip: 192.168.123.131
  - ip: 192.168.123.132
  ports:
  - name: mysql
    port: 3306
    protocol: TCP

您不需要 LoadBalancer 因为您只会在集群内部进行连接。因此,请改用 ClusterIp

#1 创建Mysql路由器部署。

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: "mysql-service"
        - name: MYSQL_PORT
          value: "3306"
        - name: MYSQL_USER
          value: "root"
        - name: MYSQL_PASSWORD
          value: "root@123"
        imagePullPolicy: Always
        ports:
        - containerPort: 6446

要通过 VIP/ClusterIP 连接到外部 MySQL 实例,请使用 mysql-service 服务,如果部署和服务在同一个命名空间中,请使用 mysql-service 作为主机名或在其中放置一个 CLusterIP 来自 kubectl get service mysql-service

apiVersion: v1
kind: Service
metadata:
  name: mysql-router-service
  namespace: mysql-router
  labels:
    app: mysql-router
spec:
  selector:
    app: mysql-router
  ports:
  - name: mysql
    port: 6446
    protocol: TCP
    targetPort: 6446
  type: ClusterIP

您可以在 kubernetes 集群内连接到同一命名空间中的 mysql-router-service 主机名,在外部命名空间连接到 mysql-router-service.namespace.svc 或在 kubernetes 集群外部使用 NodePortLoadBalancer.