Déployer un cluster à haute disponibilité MySQL dans Kubernetes

Introduction à MySql

MySQL est un système de gestion de base de données relationnelle développé par la société suédoise MySQL AB et est un produit d'Oracle. MySQL est l'un des systèmes de gestion de bases de données relationnelles les plus populaires. En termes d'applications Web, MySQL est l'un des meilleurs logiciels d'application RDBMS (Relational Database Management System). MySQL est un système de gestion de base de données relationnelle. Les bases de données relationnelles stockent les données dans différentes tables au lieu de placer toutes les données dans un grand entrepôt, ce qui augmente la vitesse et la flexibilité. Le langage SQL utilisé par MySQL est le langage standardisé le plus couramment utilisé pour accéder aux bases de données. Le logiciel MySQL adopte une politique d'autorisation double, divisée en version communautaire et version commerciale. En raison de sa petite taille, de sa vitesse rapide, de son faible coût total de possession, en particulier des caractéristiques de l'open source, le développement de sites Web de petite et moyenne taille choisit généralement MySQL comme base de données du site Web.

La solution haute disponibilité de MySQL

La solution de haute disponibilité MySQL présentée ci-dessous utilise la réplication maître-esclave + séparation lecture-écriture, qui est composée d'un seul maître et de plusieurs esclaves. Parmi eux, le client écrit dans la base de données via le maître et lit via l'esclave. Une fois que le maître a un problème, vous pouvez basculer l'application du côté esclave. Cette solution est une solution hautement disponible officiellement fournie par MySQL. La synchronisation des données entre les nœuds utilise la technologie de réplication MySQL. La réplication MySQL réplique les données d'un serveur de base de données MySQL (maître) vers un ou plusieurs serveurs de base de données MySQL (esclave). Par défaut, la réplication est asynchrone; l'esclave n'a pas besoin de toujours recevoir les mises à jour de l'hôte. En fonction de la configuration, vous pouvez copier toutes les bases de données de la base de données, des bases de données sélectionnées ou des tables spécifiques.

Installation et déploiement

1. Créez un ConfigMap

Créez un ConfigMap nommé mysql via le fichier YAML

chat mysql-configmap.yaml
apiVersion : v1 genre : métadonnées ConfigMap : nom : libellés mysql : app : données mysql : maître . cnf : | # Appliquez cette configuration uniquement sur le maître. [ mysqld ] log - bin     log_bin_trust_function_creators = 1     lower_case_table_names = 1 esclave . cnf : | # N'appliquez cette configuration qu'aux esclaves. [ 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


图片


Je suppose que tu aimes

Origine blog.51cto.com/15127502/2655080
conseillé
Classement