Implementar el clúster de alta disponibilidad de MySQL en Kubernetes

Introducción a MySql

MySQL es un sistema de gestión de bases de datos relacionales desarrollado por la empresa sueca MySQL AB y es un producto de Oracle. MySQL es uno de los sistemas de administración de bases de datos relacionales más populares En términos de aplicaciones web, MySQL es uno de los mejores software de aplicación RDBMS (Sistema de administración de bases de datos relacionales). MySQL es un sistema de administración de bases de datos relacionales. Las bases de datos relacionales almacenan datos en diferentes tablas en lugar de colocar todos los datos en un gran almacén, lo que aumenta la velocidad y la flexibilidad. El lenguaje SQL utilizado por MySQL es el lenguaje estandarizado más utilizado para acceder a las bases de datos. El software MySQL adopta una política de autorización dual, dividida en versión comunitaria y versión comercial. Debido a su pequeño tamaño, alta velocidad, bajo costo total de propiedad, especialmente las características del código abierto, el desarrollo de sitios web pequeños y medianos generalmente elige MySQL como la base de datos del sitio web.

Solución de alta disponibilidad de MySQL

La solución de alta disponibilidad de MySQL que se presenta a continuación utiliza la replicación maestro-esclavo + separación de lectura y escritura, que se compone de un solo maestro y varios esclavos. Entre ellos, el cliente escribe en la base de datos a través del maestro y lee a través del esclavo. Después de que el maestro tenga un problema, puede cambiar la aplicación al lado esclavo. Esta solución es una solución de alta disponibilidad proporcionada oficialmente por MySQL La sincronización de datos entre nodos utiliza la tecnología MySQL Replication. La replicación de MySQL replica los datos de un servidor de base de datos MySQL (maestro) a uno o más servidores de base de datos MySQL (esclavo). De forma predeterminada, la replicación es asíncrona; el esclavo no necesita recibir siempre actualizaciones del host. Dependiendo de la configuración, puede copiar todas las bases de datos en la base de datos, bases de datos seleccionadas o tablas específicas.

Instalación y despliegue

1. Cree un ConfigMap

Cree un ConfigMap llamado mysql a través del archivo YAML

gato mysql-configmap.yaml
apiVersion : v1 tipo : ConfigMap metadatos : nombre : etiquetas mysql : aplicación : datos mysql : maestro . cnf : | # Aplique esta configuración solo en el maestro. [ mysqld ] log - bin     log_bin_trust_function_creators = 1     lower_case_table_names = 1 esclavo . cnf : | # Aplicar esta configuración solo en esclavos. [ mysqld ] super


 

 

   


 

   

   

   



 

   

   

   
-read-only
   log_bin_trust_function_creators
=1

kubectl apply -f mysql-configmap.yaml -n kube-public

2. 创建Services

通过yaml文件创建两个service,分别是mysql和mysql-read:

cat mysql-service.yaml


apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None
  selector:
    app: mysql
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql

kubectl apply -f mysql-service.yaml -n kube-public

3.创建StatefulSet

通过yaml文件创建名为mysql的StatefulSet:

cat  mysql-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 3
  volumeClaimTemplates:
  - metadata:
      name: data
      annotations:
        volume.beta.kubernetes.io/storage-class: "nfs"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
          if [[ $ordinal -eq 0 ]]; then
            cp /mnt/config-map/master.cnf /mnt/conf.d/
          else
            cp /mnt/config-map/slave.cnf /mnt/conf.d/
          fi
        volumeMounts:
        - name: conf
          mountPath: /mnt/conf.d
        - name: config-map
          mountPath: /mnt/config-map
      - name: clone-mysql
        image: gcr.io/google-samples/xtrabackup:1.0
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ -d /var/lib/mysql/mysql ]] && exit 0
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          [[ $ordinal -eq 0 ]] && exit 0
          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
          xtrabackup --prepare --target-dir=/var/lib/mysql
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "1"
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
          initialDelaySeconds: 5
          periodSeconds: 2
          timeoutSeconds: 1
      - name: xtrabackup
        image: gcr.io/google-samples/xtrabackup:1.0
        ports:
        - name: xtrabackup
          containerPort: 3307
        command:
        - bash
        - "-c"
        - |
          set -ex
          cd /var/lib/mysql
          if [[ -f xtrabackup_slave_info ]]; then
            mv xtrabackup_slave_info change_master_to.sql.in
            rm -f xtrabackup_binlog_info
          elif [[ -f xtrabackup_binlog_info ]]; then
            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
            rm xtrabackup_binlog_info
            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
          fi
          if [[ -f change_master_to.sql.in ]]; then
            echo "Waiting for mysqld to be ready (accepting connections)"
            until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
            echo "Initializing replication from clone position"
            mv change_master_to.sql.in change_master_to.sql.orig
            mysql -h 127.0.0.1 <<EOF
          $(<change_master_to.sql.orig),
            MASTER_HOST='mysql-0.mysql',
            MASTER_USER='root',
            MASTER_PASSWORD='',
            MASTER_CONNECT_RETRY=10;
          START SLAVE;
          EOF
          fi
          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: mysql

kubectl apply -f mysql-statefulset.yaml -n kube-public

通过执行如下的命令可以查看启动过程:

$ kubectl get pods -lapp=mysql --watch --namespace=kube-public

在启动后,应该能够看到如下的信息:


注:上面配置说明

volumeClaimTemplates:

 - metadata:

     name: data

     annotations:

       volume.beta.kubernetes.io/storage-class: "nfs"

   spec:

     accessModes: [ "ReadWriteOnce" ]

     resources:

       requests:

         storage: 10Gi

上面这段表示动态申请pvc,存储类是由nfs创建的,前提是创建nfs的存储类,创建方法如下:

cat  class.yaml

kind: StorageClass

apiVersion: storage.k8s.io/v1

metadata:

 name: nfs

provisioner: example.com/nfs

kubectl apply -f class.yaml


动态pvc创建可参考:

kubernetes集群中部署EFK日志管理系统

MySQL部署环境验证

1)通过运行一个临时的容器(使用mysql:5.7镜像),使用MySQL 客户端发送测试请求给MySQL master节点(主机名为mysql-0.mysql;跨命名空间的话,主机名请使用mysql-0.mysql.kube-public)

kubectl run mysql-client --image=mysql:5.7 -it --rm --restart=Never -- mysql -h mysql-0.mysql.kube-public

CREATE DATABASE demo;
CREATE TABLE demo.messages (message VARCHAR(250));
INSERT INTO demo.messages VALUES ('hello');

在master节点上创建demo数据库,并创建一个只有message字段的demo.messages的表,并为message字段插入hello值。

图片

2)使用主机名为mysql-read来发送测试请求给服务器:



kubectl run mysql-client --image=mysql:5.7 -i -t --rm --restart=Never -- mysql -h mysql-read.kube-public


图片


Supongo que te gusta

Origin blog.51cto.com/15127502/2655080
Recomendado
Clasificación