Zustandsorientierten MySQL-Cluster in GKE bereitstellen


Dieses Dokument richtet sich an Datenbankadministratoren, Cloud-Architekten und Betriebsexperten, die an der Bereitstellung einer hochverfügbaren MySQL-Topologie in Google Kubernetes Engine (GKE) interessiert sind.

In dieser Anleitung erfahren Sie, wie Sie einen MySQL-InnoDB-Cluster und ein MySQL-InnoDB-ClusterSet zusätzlich zur MySQL-Router Middleware in Ihrem GKE-Cluster bereitstellen und wie Sie Upgrades auslösen.

Lernziele

In dieser Anleitung erhalten Sie Informationen zu folgenden Themen:

  • Zustandsorientierten Kubernetes-Dienst erstellen und bereitstellen.
  • MySQL-InnoDB-Cluster für Hochverfügbarkeit bereitstellen.
  • Router-Middleware für das Routing von Datenbankvorgängen bereitstellen.
  • MySQL-InnoDB-ClusterSet zur Notfalltoleranz bereitstellen.
  • Failover eines MySQL-Clusters simulieren.
  • Upgrade der MySQL-Version auslösen.

In den folgenden Abschnitten wird die Architektur der Lösung beschrieben, die Sie in dieser Anleitung erstellen.

MySQL-InnoDB-Cluster

In Ihrem regionalen GKE-Cluster stellen Sie mithilfe eines StatefulSets eine MySQL-Datenbankinstanz mit der erforderlichen Benennung und Konfiguration bereit, um einen MySQL-InnoDB-Cluster zu erstellen. Für Fehlertoleranz und Hochverfügbarkeit stellen Sie drei Datenbankinstanz-Pods bereit. Dadurch wird sichergestellt, dass die meisten Pods in verschiedenen Zonen jederzeit für eine erfolgreiche primäre Auswahl mit einem Konsensprotokoll verfügbar sind. Weiter toleriert Ihr MySQL-InnoDB-Cluster deswegen Ausfälle einzelner Zonen.

Architekturdiagramm, das die Beziehung zwischen Anwendungen, MySQL Router und MySQL-Cluster zeigt
Abbildung 1: Beispielarchitektur für einen einzelnen MySQL-InnoDB-Cluster

Nach der Bereitstellung legen Sie einen Pod als primäre Instanz für Lese- und Schreibvorgänge fest. Die anderen beiden Pods sind sekundäre schreibgeschützte Replikate. Wenn bei der primären Instanz ein Infrastrukturfehler auftritt, können Sie einen dieser beiden Replikat-Pods hochstufen.

In einem separaten Namespace stellen Sie drei MySQL Router-Pods bereit, um ein Verbindungsrouting zur erhöhten Ausfallsicherheit bereitzustellen. Anstatt eine direkte Verbindung zum Datenbankdienst herzustellen, verbinden sich Ihre Anwendungen mit MySQL Router-Pods. Jeder Router-Pod kennt Status und Zweck jedes MySQL-InnoDB-Cluster-Pods und leitet Anwendungsvorgänge an den entsprechenden fehlerfreien Pod weiter. Der Routingstatus wird in den Router-Pods im Cache gespeichert und aus den Clustermetadaten aktualisiert, die auf jedem Knoten des MySQL-InnoDB-Clusters gespeichert sind. Bei einem Instanzausfall passt der Router das Verbindungsrouting für eine Live-Instanz an.

MySQL-InnoDB-ClusterSet

Sie können ein MySQL InnoDB ClusterSet aus einem anfänglichen MySQL-InnoDB-Cluster erstellen. Auf diese Weise können Sie die Notfallwiederherstellung erhöhen, wenn der primäre Cluster nicht mehr verfügbar ist.

Das Diagramm zeigt, wie primäre und Replikat-MySQL-InnoDB-Cluster durch asynchrone Replikation synchron bleiben.
Abbildung 2: Beispiel für eine multiregionale ClusterSet-Architektur mit einem primären Cluster und einem Replikatcluster

Ist die primäre Instanz des MySQL-InnoDB-Clusters nicht mehr verfügbar, können Sie einen Replikatcluster im ClusterSet auf die primäre Instanz hochstufen. Bei der Verwendung der MySQL Router-Middleware muss Ihre Anwendung den Zustand der primären Datenbankinstanz nicht verfolgen. Das Routing wird angepasst, um Verbindungen nach der Wahl an die neue primäre Datenbank zu senden. Es liegt jedoch in Ihrer Verantwortung, darauf zu achten, dass Anwendungen, die eine Verbindung zu Ihrer MySQL-Router-Middleware herstellen, den Best Practices für Ausfallsicherheit folgen. Das bedingt, dass Verbindungen wiederholt werden, wenn ein Fehler während des Cluster-Failovers auftritt.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

Projekt einrichten

  1. Melden Sie sich bei Ihrem Google Cloud-Konto an. Wenn Sie mit Google Cloud noch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Klicken Sie in der Google Cloud Console auf der Projektauswahlseite auf Projekt erstellen, um mit der Erstellung eines neuen Google Cloud-Projekts zu starten.

    Zur Projektauswahl

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  4. GKE API aktivieren.

    Aktivieren Sie die API

  5. Klicken Sie in der Google Cloud Console auf der Projektauswahlseite auf Projekt erstellen, um mit der Erstellung eines neuen Google Cloud-Projekts zu starten.

    Zur Projektauswahl

  6. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  7. GKE API aktivieren.

    Aktivieren Sie die API

Rollen einrichten

  1. Gewähren Sie Ihrem Google-Konto Rollen. Führen Sie den folgenden Befehl für jede der folgenden IAM-Rollen einmal aus: role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin

    $ gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID.
    • Ersetzen Sie EMAIL_ADDRESS durch Ihre E-Mail-Adresse.
    • Ersetzen Sie ROLE durch jede einzelne Rolle.

Umgebung einrichten

In dieser Anleitung verwenden Sie Cloud Shell zum Verwalten von Ressourcen, die in Google Cloud gehostet werden. In Cloud Shell sind Docker und die kubectl- und gcloud-Befehlszeile vorinstalliert.

So richten Sie Ihre Umgebung mit Cloud Shell ein:

  1. Umgebungsvariablen festlegen

    export PROJECT_ID=PROJECT_ID
    export CLUSTER_NAME=gkemulti-west
    export REGION=COMPUTE_REGION
    

    Ersetzen Sie die folgenden Werte:

    • PROJECT_ID: Ihre Google Cloud-Projekt-ID.
    • COMPUTE_REGION: Ihre Compute Engine-Region. In dieser Anleitung ist die Region us-west1. In der Regel sollten Sie eine Region in Ihrer Nähe haben.
  2. Legen Sie die Standardumgebungsvariablen fest.

     gcloud config set project PROJECT_ID
     gcloud config set compute/region COMPUTE_REGION
    
  3. Klonen Sie das Code-Repository.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  4. Wechseln Sie in das Arbeitsverzeichnis.

    cd kubernetes-engine-samples/databases/gke-stateful-mysql/kubernetes
    

GKE-Cluster erstellen

In diesem Abschnitt erstellen Sie einen regionalen GKE-Cluster. Im Gegensatz zu zonalen Clustern wird die Steuerungsebene regionaler Cluster in mehrere Zonen repliziert. Entsprechen wird die Verbindung zur Steuerungsebene bei einem Ausfall in einer einzelnen Zone nicht unterbrochen.

So erstellen Sie einen GKE-Cluster:

Autopilot

  1. Erstellen Sie in Cloud Shell einen GKE AutoAutpilot-Cluster in der Region us-west1.

    gcloud container clusters create-auto $CLUSTER_NAME \
        --region=$REGION
    
  2. Rufen Sie die Anmeldedaten für den GKE-Cluster ab:.

    gcloud container clusters get-credentials $CLUSTER_NAME \
      --region=$REGION
    
  3. Stellen Sie einen Service über drei Zonen hinweg bereit.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: prepare-three-zone-ha
      labels:
        app: prepare-three-zone-ha
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: prepare-three-zone-ha
      template:
        metadata:
          labels:
            app: prepare-three-zone-ha
        spec:
          affinity:
            # Tell Kubernetes to avoid scheduling a replica in a zone where there
            # is already a replica with the label "app: prepare-three-zone-ha"
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - prepare-three-zone-ha
                topologyKey: "topology.kubernetes.io/zone"
          containers:
          - name: prepare-three-zone-ha
            image: busybox:latest
            command:
                - "/bin/sh"
                - "-c"
                - "while true; do sleep 3600; done"
            resources:
              limits:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
              requests:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
    kubectl apply -f prepare-for-ha.yaml
    

    Standardmäßig stellt Autopilot Ressourcen in nur zwei Zonen bereit. Das in prepare-for-ha.yaml definierte Deployment sorgt dafür, dass Autopilot Knoten über drei Zonen Ihres Clusters hinweg bereitstellt. Dazu werden replicas:3, podAntiAffinity, requiredDuringSchedulingIgnoredDuringExecution und topologyKey: "topology.kubernetes.io/zone" festgelegt.

  4. Prüfen Sie den Status der Bereitstellung.

    kubectl get deployment prepare-three-zone-ha --watch
    

    Wenn drei Pods bereit sind, brechen Sie diesen Befehl mit CTRL+C ab. Die Ausgabe sieht in etwa so aus:

    NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
    prepare-three-zone-ha   0/3     3            0           9s
    prepare-three-zone-ha   1/3     3            1           116s
    prepare-three-zone-ha   2/3     3            2           119s
    prepare-three-zone-ha   3/3     3            3           2m16s
    
  5. Führen Sie dieses Skript aus, um zu prüfen, ob Ihre Pods über drei Zonen hinweg bereitgestellt wurden.

    bash ../scripts/inspect_pod_node.sh default
    

    Jede Zeile der Ausgabe entspricht einem Pod. Die zweite Spalte gibt die Cloud-Zone an. Die Ausgabe sieht in etwa so aus:

    gk3-gkemulti-west1-default-pool-eb354e2d-z6mv us-west1-b prepare-three-zone-ha-7885d77d9c-8f7qb
    gk3-gkemulti-west1-nap-25b73chq-739a9d40-4csr us-west1-c prepare-three-zone-ha-7885d77d9c-98fpn
    gk3-gkemulti-west1-default-pool-160c3578-bmm2 us-west1-a prepare-three-zone-ha-7885d77d9c-phmhj
    

Standard

  1. Erstellen Sie in Cloud Shell einen GKE Standard-Cluster in der Region us-west1.

    gcloud container clusters create $CLUSTER_NAME \
      --region=$REGION \
      --machine-type="e2-standard-2" \
      --disk-type="pd-standard" \
      --num-nodes="5"
    
  2. Rufen Sie die Anmeldedaten für den GKE-Cluster ab:.

    gcloud container clusters get-credentials $CLUSTER_NAME \
      --region=$REGION
    

MySQL-StatefulSets bereitstellen

In diesem Abschnitt stellen Sie ein StatefulSet von MySQL bereit. Jedes StatefulSet besteht aus drei MySQL-Replikaten.

So stellen Sie MySQL StatefulSet bereit:

  1. Erstellen Sie einen Namespace für das StatefulSet:

    kubectl create namespace mysql1
    
  2. Erstellen Sie das MySQL-Secret:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-secret
    type: Opaque
    data:
      password: UGFzc3dvcmQkMTIzNDU2 # Password$123456
      admin-password: UGFzc3dvcmQkMTIzNDU2 # Password$123456
    kubectl apply -n mysql1 -f secret.yaml
    

    Das Passwort wird mit jedem Pod bereitgestellt. Weiter wird es in dieser Anleitung von Verwaltungsskripts und Befehlen zur Bereitstellung von MySQL-InnoDB-Clustern und ClusterSets verwendet.

  3. Erstellen Sie die StorageClass.

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: fast-storageclass
    provisioner: pd.csi.storage.gke.io
    volumeBindingMode: WaitForFirstConsumer
    reclaimPolicy: Retain
    allowVolumeExpansion: true
    parameters:
      type: pd-balanced
    kubectl apply -n mysql1 -f storageclass.yaml
    

    Diese Speicherklasse verwendet den nichtflüchtigen Speichertyp pd-balanced, der eine Balance zwischen Leistung und Kosten bietet. Das volumeBindingMode-Feld ist auf WaitForFirstConsumer gesetzt, was bedeutet, dass GKE die Bereitstellung eines PersistentVolume verzögert, bis der Pod erstellt ist. Diese Einstellung sorgt dafür, dass das Laufwerk in der Zone bereitgestellt wird, in der der Pod geplant ist.

  4. StatefulSet der MySQL-Instanz-Pods bereitstellen.

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: dbc1
      labels:
        app: mysql
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: mysql
      serviceName: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          topologySpreadConstraints:
          - maxSkew: 1
            topologyKey: "topology.kubernetes.io/zone"
            whenUnsatisfiable: DoNotSchedule
            labelSelector:
              matchLabels:
                app: mysql
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - mysql
                topologyKey: "kubernetes.io/hostname"
          containers:
          - name: mysql
            image: mysql/mysql-server:8.0.28
            command:
            - /bin/bash
            args:
            - -c
            - >-
              /entrypoint.sh
              --server-id=$((20 +  $(echo $HOSTNAME | grep -o '[^-]*$') + 1))
              --report-host=${HOSTNAME}.mysql.mysql1.svc.cluster.local
              --binlog-checksum=NONE
              --enforce-gtid-consistency=ON
              --gtid-mode=ON
              --default-authentication-plugin=mysql_native_password
            env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            - name: MYSQL_ADMIN_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: admin-password
            - name: MYSQL_ROOT_HOST
              value: '%'
            ports:
            - name: mysql
              containerPort: 3306
            - name: mysqlx
              containerPort: 33060
            - name: xcom
              containerPort: 33061
            resources:
              limits:
                cpu: "500m"
                ephemeral-storage: "1Gi"
                memory: "1Gi"
              requests:
                cpu: "500m"
                ephemeral-storage: "1Gi"
                memory: "1Gi"
            volumeMounts:
            - name: mysql
              mountPath: /var/lib/mysql
              subPath: mysql
            readinessProbe:
              exec:
                command:
                - bash
                - "-c"
                - |
                  mysql -h127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e'SELECT 1'
              initialDelaySeconds: 30
              periodSeconds: 2
              timeoutSeconds: 1
            livenessProbe:
              exec:
                command:
                - bash
                - "-c"
                - |
                  mysqladmin -uroot -p$MYSQL_ROOT_PASSWORD ping
              initialDelaySeconds: 30
              periodSeconds: 10
              timeoutSeconds: 5
      updateStrategy:
        rollingUpdate:
          partition: 0
        type: RollingUpdate
      volumeClaimTemplates:
      - metadata:
          name: mysql
          labels:
            app: mysql
        spec:
          storageClassName: fast-storageclass
          volumeMode: Filesystem
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 10Gi
    kubectl apply -n mysql1 -f c1-mysql.yaml
    

    Mit diesem Befehl wird das StatefulSet bereitgestellt, das aus drei Replikaten besteht. In dieser Anleitung wird der primäre MySQL-Cluster über drei Zonen in us-west1 hinweg bereitgestellt. Die Ausgabe sieht in etwa so aus:

    service/mysql created
    statefulset.apps/dbc1 created
    

    In dieser Anleitung werden die Ressourcenlimits und -anfragen auf minimale Werte festgelegt, um Kosten zu sparen. Achten Sie bei der Planung einer Produktionsarbeitslast darauf, dass diese Werte den Anforderungen Ihrer Organisation entsprechen.

  5. Prüfen Sie, ob das StatefulSet erfolgreich erstellt wurde.

    kubectl get statefulset -n mysql1 --watch
    

    Es kann etwa 10 Minuten dauern, bis das SatefulSet bereit ist.

  6. Wenn alle drei Pods bereit sind, beenden Sie den Befehl mit Ctrl+C. Wenn aufgrund von unzureichender CPU oder Arbeitsspeicher PodUnscheduleable-Fehler auftreten, warten Sie einige Minuten, bis die Größe der Steuerungsebene angepasst wurde, um die große Arbeitslast zu bewältigen.

    Die Ausgabe sieht in etwa so aus:

    NAME   READY   AGE
    dbc1   1/3     39s
    dbc1   2/3     50s
    dbc1   3/3     73s
    
  7. Führen Sie das folgende Skript aus, um die Platzierung Ihrer Pods auf den GKE-Clusterknoten zu prüfen:

    bash ../scripts/inspect_pod_node.sh mysql1 mysql
    

    Die Ausgabe zeigt den Pod-Namen, den GKE-Knotennamen und die Zone, in der der Knoten bereitgestellt wird, und sieht in etwa so aus:

    gke-gkemulti-west-5-default-pool-4bcaca65-jch0 us-west1-b dbc1-0
    gke-gkemulti-west-5-default-pool-1ac6e8b5-ddjx us-west1-c dbc1-1
    gke-gkemulti-west-5-default-pool-1f5baa66-bf8t us-west1-a dbc1-2
    

    Die Spalten in der Ausgabe stellen Hostnamen, Cloudzone und Pod-Namen dar.

    Die topologySpreadConstraints-Richtlinie in der StatefulSet-Spezifikation (c1-mysql.yaml) weist den Planer an, die Pods gleichmäßig in der Fehlerdomain zu platzieren (topology.kubernetes.io/zone).

    Die podAntiAffinity-Richtlinie erzwingt die Einschränkung, dass Pods nicht auf demselben GKE-Clusterknoten platziert werden müssen (kubernetes.io/hostname). Bei MySQL-Instanz-Pods führt diese Richtlinie dazu, dass die Pods gleichmäßig über die drei Zonen der Google Cloud-Region hinweg bereitgestellt werden. Diese Platzierung ermöglicht die hohe Verfügbarkeit des MySQL-InnoDB-Clusters. Dazu wird jede Datenbankinstanz in einer separaten Fehlerdomain platziert.

Primären MySQL-InnoDB-Cluster vorbereiten

So konfigurieren Sie einen MySQL-InnoDB-Cluster:

  1. Legen Sie im Cloud Shell-Terminal die Gruppenreplikationskonfigurationen für die MySQL-Instanzen fest, die Ihrem Cluster hinzugefügt werden sollen.

    bash ../scripts/c1-clustersetup.sh
    
    POD_ORDINAL_START=${1:-0}
    POD_ORDINAL_END=${2:-2}
    for i in $(seq ${POD_ORDINAL_START} ${POD_ORDINAL_END}); do
      echo "Configuring pod mysql1/dbc1-${i}"
      cat <<'  EOF' | kubectl -n mysql1 exec -i dbc1-${i} -- bash -c 'mysql -uroot -proot --password=${MYSQL_ROOT_PASSWORD}'
    INSTALL PLUGIN group_replication SONAME 'group_replication.so';
    RESET PERSIST IF EXISTS group_replication_ip_allowlist;
    RESET PERSIST IF EXISTS binlog_transaction_dependency_tracking;
    SET @@PERSIST.group_replication_ip_allowlist = 'mysql.mysql1.svc.cluster.local';
    SET @@PERSIST.binlog_transaction_dependency_tracking = 'WRITESET';
      EOF
    done

    Das Skript stellt eine Remote-Verbindung zu jeder der drei MySQL-Instanzen her, um folgende Umgebungsvariablen festzulegen und beizubehalten:

    • group_replication_ip_allowlist: Ermöglicht der Instanz im Cluster, sich mit einer beliebigen Instanz in der Gruppe verbinden.
    • binlog_transaction_dependency_tracking='WRITESET': Ermöglicht parallele Transaktionen, die keine Konflikte hervorrufen.

    Verwenden Sie in MySQL-Versionen vor 8.0.22 group_replication_ip_whitelist anstelle von group_replication_ip_allowlist.

  2. Öffnen Sie ein zweites Terminal, damit Sie nicht für jeden Pod eine Shell erstellen müssen.

  3. Stellen Sie eine Verbindung zu MySQL Shell auf dem Pod dbc1-0 her.

    kubectl -n mysql1 exec -it dbc1-0 -- \
        /bin/bash \
        -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'
    
  4. Prüfen Sie die Zulassungsliste der MySQL-Gruppenreplikation zum Herstellen einer Verbindung zu anderen Instanzen.

    \sql SELECT @@group_replication_ip_allowlist;
    

    Die Ausgabe sieht in etwa so aus:

    +----------------------------------+
    | @@group_replication_ip_allowlist |
    +----------------------------------+
    | mysql.mysql1.svc.cluster.local   |
    +----------------------------------+
    
  5. Prüfen Sie, ob server-id pro Instanz einmalig ist.

    \sql SELECT @@server_id;
    

    Die Ausgabe sieht in etwa so aus:

    +-------------+
    | @@server_id |
    +-------------+
    |          21 |
    +-------------+
    
  6. Konfigurieren Sie jede Instanz für die Verwendung des MySQL-InnoDB-Clusters und erstellen Sie auf jeder Instanz ein Administratorkonto.

    \js
    dba.configureInstance('root@dbc1-0.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    dba.configureInstance('root@dbc1-1.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    dba.configureInstance('root@dbc1-2.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    

    Alle Instanzen müssen denselben Nutzernamen und dasselbe Passwort haben, damit der MySQL InnoDB-Cluster ordnungsgemäß funktioniert. Die Ausgabe der einzelnen Befehle sieht in etwa so aus:

    ...
    
    The instance 'dbc1-2.mysql:3306' is valid to be used in an InnoDB cluster.
    
    Cluster admin user 'icadmin'@'%' created.
    The instance 'dbc1-2.mysql.mysql1.svc.cluster.local:3306' is already
    ready to be used in an InnoDB cluster.
    
    Successfully enabled parallel appliers.
    
  7. Prüfen, ob die Instanz für die Verwendung in einem MySQL-InnoDB-Cluster bereit ist

    dba.checkInstanceConfiguration()
    

    Die Ausgabe sieht in etwa so aus:

    ...
    
    The instance 'dbc1-0.mysql.mysql1.svc.cluster.local:3306' is valid to be used in an InnoDB cluster.
    
    {
        "status": "ok"
    }
    

    Optional können Sie eine Verbindung zu den einzelnen MySQL-Instanzen herstellen und diesen Befehl wiederholen. Führen Sie beispielsweise diesen Befehl aus, um den Status der dbc1-1-Instanz zu prüfen:

    kubectl -n mysql1 exec -it dbc1-0 -- \
        /bin/bash \
        -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-1.mysql.mysql1.svc.cluster.local" \
        --js --execute "dba.checkInstanceConfiguration()"'
    

Primären MySQL-InnoDB-Cluster erstellen

Erstellen Sie als Nächstes mit dem Befehl createCluster des MySQL-Administrators den MySQL-InnoDB-Cluster. Beginnen Sie mit der dbc1-0-Instanz, die die primäre Instanz für den Cluster ist, und fügen Sie dem Cluster dann zwei zusätzliche Replikate hinzu.

So initialisieren Sie den MySQL-InnoDB-Cluster:

  1. Erstellen Sie den MySQL-InnoDB-Cluster.

    var cluster=dba.createCluster('mycluster');
    

    Der Befehl createCluster löst folgende Vorgänge aus:

    • Bereitstellung des Metadatenschemas.
    • Prüfen, ob die Konfiguration für die Gruppenreplikation korrekt ist.
    • Registrieren der Seed-Instanz des neuen Clusters.
    • Erstellen der erforderlichen internen Konten, z. B. des Nutzerkontos für die Replikation.
    • Start der Gruppenreplikation.

    Dieser Befehl initialisiert einen MySQL-InnoDB-Cluster mit dem Host dbc1-0 als primärem Element. Die Clusterreferenz wird in der Clustervariablen gespeichert.

    Die Ausgabe sieht dann ungefähr so aus:

    A new InnoDB cluster will be created on instance 'dbc1-0.mysql:3306'.
    
    Validating instance configuration at dbc1-0.mysql:3306...
    
    This instance reports its own address as dbc1-0.mysql.mysql1.svc.cluster.local:3306
    
    Instance configuration is suitable.
    NOTE: Group Replication will communicate with other instances using
    'dbc1-0.mysql:33061'. Use the localAddress
    option to override.
    
    Creating InnoDB cluster 'mycluster' on
    'dbc1-0.mysql.mysql1.svc.cluster.local:3306'...
    
    Adding Seed Instance...
    Cluster successfully created. Use Cluster.addInstance() to add MySQL
    instances.
    At least 3 instances are needed for the cluster to be able to withstand
    up to one server failure.
    
  2. Fügen Sie dem Cluster die zweite Instanz hinzu.

    cluster.addInstance('icadmin@dbc1-1.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    
  3. Fügen Sie dem Cluster die verbleibende Instanz hinzu.

    cluster.addInstance('icadmin@dbc1-2.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    

    Die Ausgabe sieht in etwa so aus:

    ...
    The instance 'dbc1-2.mysql:3306' was successfully added to the cluster.
    
  4. Überprüfen Sie den Clusterstatus.

    cluster.status()
    

    Dieser Befehl zeigt den Status des Clusters an. Die Topologie besteht aus drei Hosts, einer primären und zwei sekundären Instanzen. Optional können Sie cluster.status({extended:1}) aufrufen.

    Die Ausgabe sieht in etwa so aus:

    {
        "clusterName": "mysql1",
        "defaultReplicaSet": {
            "name": "default",
            "primary": "dbc1-0.mysql:3306",
            "ssl": "REQUIRED",
            "status": "OK",
            "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
            "topology": {
                "dbc1-0.mysql:3306": {
                    "address": "dbc1-0.mysql:3306",
                    "memberRole": "PRIMARY",
                    "mode": "R/W",
                    "readReplicas": {},
                    "replicationLag": null,
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.28"
                },
                "dbc1-1.mysql:3306": {
                    "address": "dbc1-1.mysql:3306",
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": null,
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.28"
                },
                "dbc1-2.mysql:3306": {
                    "address": "dbc1-2.mysql:3306",
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": null,
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.28"
                }
            },
            "topologyMode": "Single-Primary"
        },
        "groupInformationSourceMember": "dbc1-0.mysql:3306"
    }
    

    Optional können Sie cluster.status({extended:1}) aufrufen, um zusätzliche Statusdetails zu erhalten.

Beispieldatenbank erstellen

So erstellen Sie eine Beispieldatenbank:

  1. Erstellen Sie eine Datenbank und laden Sie Daten in die Datenbank.

    \sql
    create database loanapplication;
    use loanapplication
    CREATE TABLE loan (loan_id INT unsigned AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL , status VARCHAR(30) );
    
  2. Fügen Sie Beispieldaten in die Datenbank ein. Zum Einfügen von Daten müssen Sie mit der primären Instanz des Clusters verbunden sein.

    INSERT INTO loan (firstname, lastname, status) VALUES ( 'Fred','Flintstone','pending');
    INSERT INTO loan (firstname, lastname, status) VALUES ( 'Betty','Rubble','approved');
    
  3. Prüfen Sie, ob die Tabelle die drei Zeilen enthält, die im vorherigen Schritt eingefügt wurden.

    SELECT * FROM loan;
    

    Die Ausgabe sieht in etwa so aus:

    +---------+-----------+------------+----------+
    | loan_id | firstname | lastname   | status   |
    +---------+-----------+------------+----------+
    |       1 | Fred      | Flintstone | pending  |
    |       2 | Betty     | Rubble     | approved |
    +---------+-----------+------------+----------+
    2 rows in set (0.0010 sec)
    

MySQL-InnoDB-ClusterSet erstellen

Sie können einen MySQL-InnoDB-ClusterSet erstellen, um die Replikation von Ihrem primären Cluster zu Replikatclustern zu verwalten. Verwenden Sie dazu einen dedizierten ClusterSet-Replikationskanal.

Ein MySQL-InnoDB-ClusterSet bietet eine Notfalltoleranz für MySQL-InnoDB-Clusterbereitstellungen. Dazu wird ein primärer MySQL-InnoDB-Cluster mit einem oder mehreren Replikaten seiner selbst an alternativen Standorten verknüpft, z. B. in mehreren Zonen und mehreren Regionen.

Wenn Sie MySQL Shell geschlossen haben, erstellen Sie eine neue Shell. Dazu führen Sie diesen Befehl in einem neuen Cloud Shell-Terminal aus:

  kubectl -n mysql1 exec -it dbc1-0 -- \
      /bin/bash -c 'mysqlsh \
      --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'

So erstellen Sie ein MySQL-InnoDB-ClusterSet:

  1. Rufen Sie im MySQL Shell-Terminal ein Clusterobjekt ab.

    \js
    cluster=dba.getCluster()
    

    Die Ausgabe sieht in etwa so aus:

    <Cluster:mycluster>
    
  2. Initialisieren Sie einen MySQL InnoDB-ClusterSet mit dem vorhandenen MySQL InnoDB-Cluster, der im Clusterobjekt als primäre Instanz gespeichert ist.

    clusterset=cluster.createClusterSet('clusterset')
    

    Die Ausgabe sieht in etwa so aus:

    A new ClusterSet will be created based on the Cluster 'mycluster'.
    
    * Validating Cluster 'mycluster' for ClusterSet compliance.
    
    * Creating InnoDB ClusterSet 'clusterset' on 'mycluster'...
    
    * Updating metadata...
    
    ClusterSet successfully created. Use ClusterSet.createReplicaCluster() to add Replica Clusters to it.
    
    <ClusterSet:clusterset>
    
  3. Prüfen Sie den Status Ihres MySQL-InnoDB-Clustersets.

    clusterset.status()
    

    Die Ausgabe sieht in etwa so aus:

    {
        "clusters": {
            "mycluster": {
                "clusterRole": "PRIMARY",
                "globalStatus": "OK",
                "primary": "dbc1-0.mysql:3306"
            }
        },
        "domainName": "clusterset",
        "globalPrimaryInstance": "dbc1-0.mysql:3306",
        "primaryCluster": "mycluster",
        "status": "HEALTHY",
        "statusText": "All Clusters available."
    }
    

    Optional können Sie clusterset.status({extended:1}) aufrufen, um zusätzliche Statusdetails wie Informationen zum Cluster abzurufen.

  4. Beenden Sie MySQL Shell.

    \q
    

Stellen Sie eine MySQL-Router bereit

Sie können einen MySQL Router bereitstellen, um den Traffic der Clientanwendung an die entsprechenden Cluster weiterzuleiten. Das Routing basiert auf dem Verbindungsport der Anwendung, die einen Datenbankvorgang ausführt:

  • Schreibvorgänge werden an die primäre Clusterinstanz im primären ClusterSet weitergeleitet.
  • Lesevorgänge können an jede Instanz im primären Cluster weitergeleitet werden.

Wenn Sie einen MySQL Router starten, wird er per Bootstrapping auf Basis der MySQL-InnoDB-ClusterSet-Bereitstellung ausgeführt. Die mit dem MySQL-InnoDB-ClusterSet verbundenen MySQL-Router-Instanzen erkennen alle kontrollierten Switchover und Failover-Failover und leiten Traffic an den neuen primären Cluster weiter.

So stellen Sie einen MySQL Router bereit:

  1. Stellen Sie im Cloud Shell-Terminal den MySQL Router bereit.

    kubectl apply -n mysql1 -f c1-router.yaml
    

    Die Ausgabe sieht in etwa so aus:

    configmap/mysql-router-config created
    service/mysql-router created
    deployment.apps/mysql-router created
    
  2. Prüfen Sie, ob die MySQL-Routerbereitstellung bereit ist.

    kubectl -n mysql1 get deployment mysql-router --watch
    

    Wenn alle drei Pods bereit sind, sieht die Ausgabe in etwa so aus:

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    mysql-router   3/3     3            0           3m36s
    

    Wenn in der Konsole der PodUnschedulable-Fehler angezeigt wird, warten Sie ein bis zwei Minuten, während GKE mehr Knoten bereitstellt. Nach der Aktualisierung sollten Sie 3/3 OK sehen.

  3. Starten Sie MySQL Shell auf einem Mitglied des vorhandenen Clusters.

    kubectl -n mysql1 exec -it dbc1-0 -- \
        /bin/bash -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
    

    Dieser Befehl stellt eine Verbindung zum dbc1-0-Pod her und startet dann eine Shell, die mit der MySQL-Instanz dbc1-0 verbunden ist.

  4. Prüfen Sie die Routerkonfiguration.

    clusterset=dba.getClusterSet()
    clusterset.listRouters()
    

    Die Ausgabe sieht in etwa so aus:

    {
      "domainName": "clusterset",
      "routers": {
        "mysql-router-7cd8585fbc-74pkm::": {
            "hostname": "mysql-router-7cd8585fbc-74pkm",
            "lastCheckIn": "2022-09-22 23:26:26",
            "roPort": 6447,
            "roXPort": 6449,
            "rwPort": 6446,
            "rwXPort": 6448,
            "targetCluster": null,
            "version": "8.0.27"
        },
        "mysql-router-7cd8585fbc-824d4::": {
          ...
        },
        "mysql-router-7cd8585fbc-v2qxz::": {
          ...
        }
      }
    }
    
  5. Beenden Sie MySQL Shell.

    \q
    
  6. Führen Sie dieses Skript aus, um die Platzierung der MySQL-Router-Pods zu prüfen.

    bash ../scripts/inspect_pod_node.sh mysql1 | sort
    

    Das Skript zeigt die Knoten- und Cloud Zone-Platzierung aller Pods im Namespace mysql1, wobei die Ausgabe in etwa so aussieht:

    gke-gkemulti-west-5-default-pool-1ac6e8b5-0h9v us-west1-c mysql-router-6654f985f5-df97q
    gke-gkemulti-west-5-default-pool-1ac6e8b5-ddjx us-west1-c dbc1-1
    gke-gkemulti-west-5-default-pool-1f5baa66-bf8t us-west1-a dbc1-2
    gke-gkemulti-west-5-default-pool-1f5baa66-kt03 us-west1-a mysql-router-6654f985f5-qlfj9
    gke-gkemulti-west-5-default-pool-4bcaca65-2l6s us-west1-b mysql-router-6654f985f5-5967d
    gke-gkemulti-west-5-default-pool-4bcaca65-jch0 us-west1-b dbc1-0
    

    Sie sehen, dass die MySQL Router-Pods gleichmäßig über die Zonen verteilt sind. Das heißt, sie sind nicht auf demselben Knoten wie ein MySQL-Pod oder auf demselben Knoten wie ein anderer MySQL-Router-Pod platziert.

GKE- und MySQL-InnoDB-Cluster-Upgrades verwalten

Aktualisierungen für MySQL und Kubernetes werden regelmäßig veröffentlicht. Halten Sie sich an die Best Practices für den Betrieb von Software, um Ihre Softwareumgebung regelmäßig zu aktualisieren. Standardmäßig verwaltet GKE Upgrades für Cluster und Knotenpools. Kubernetes und GKE bieten außerdem zusätzliche Funktionen zur Unterstützung der MySQL-Software-Upgrades.

GKE-Upgrades planen

Sie können proaktive Schritte ausführen und Konfigurationen festlegen, um Risiken zu minimieren und ein reibungsloseres Clusterupgrade bei der Ausführung zustandsorientierter Dienste zu ermöglichen. Dazu gehören:

  • Standardcluster: Folgen Sie den GKE-Best Practices für Cluster-Upgrades. Wählen Sie eine geeignete Upgradestrategie, um sicherzustellen, dass die Upgrades während des Wartungsfensters stattfinden:

    • Wählen Sie Surge-Upgrades aus, wenn eine Kostenoptimierung wichtig ist und Ihre Arbeitslasten ein ordnungsgemäßes Herunterfahren in weniger als 60 Minuten tolerieren können.
    • Wählen Sie Blau/Grün-Upgrades, wenn Ihre Arbeitslasten weniger störungstolerant sind und eine vorübergehende Kostenerhöhung aufgrund einer höheren Ressourcennutzung akzeptabel ist.

    Weitere Informationen finden Sie unter Cluster aktualisieren, in dem eine zustandsorientierte Arbeitslast ausgeführt wird. Autopilot-Cluster werden automatisch aktualisiert, basierend auf der ausgewählten Release-Version.

  • Verwenden Sie Wartungsfenster, um dafür zu Sorgen, dass Upgrades plangemäß erfolgen. Prüfen Sie vor dem Wartungsfenster, ob die Datenbanksicherungen erfolgreich waren.

  • Bevor Sie Traffic zu den aktualisierten MySQL-Knoten zulassen, sollten Sie Bereitschafts- und Aktivitätsprüfungen verwenden, um sicherzustellen, dass sie für den Traffic bereit sind.

  • Erstellen Sie Prüfungen, um zu sehen, ob die Replikation synchron ist, bevor Sie den Traffic akzeptieren. Je nach Komplexität und Umfang Ihrer Datenbank können Sie dafür benutzerdefinierte Skripts verwenden.

Budget für Pod-Störungen (Pod Disruption Budget, PDB) festlegen

Wenn ein MySQL-InnoDB-Cluster in GKE ausgeführt wird, muss jederzeit eine ausreichende Anzahl von Instanzen ausgeführt werden, um die Quorumanforderung zu erfüllen.

Für diese Anleitung müssen bei einem MySQL-Cluster mit drei Instanzen zwei Instanzen verfügbar sein, um ein Quorum zu bilden. Mit einer PodDisruptionBudget-Richtlinie können Sie die Anzahl der Pods begrenzen, die zu einer bestimmten Zeit beendet werden können. Dies ist sowohl dem stabilen Zustand Ihrer zustandsorientierten Dienste als auch den Clusterupgrades zuträglich.

Damit eine begrenzte Anzahl an Pods gleichzeitig unterbrochen wird, legen Sie das PDB für Ihre Arbeitslast auf maxUnavailable: 1 fest. Damit wird gesichert, dass während des Dienstvorgangs nie mehr als ein Pod ausgeführt wird.

Das folgende Richtlinienmanifest PodDisruptionBudget legt die Anzahl der maximal nicht verfügbaren Pods für Ihre MySQL-Anwendung auf "1" fest.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mysql-pdb
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: mysql

So wenden Sie die PDB-Richtlinie auf Ihren Cluster an:

  1. Wenden Sie die PDB-Richtlinie mit kubectl an.

    kubectl apply -n mysql1 -f mysql-pdb-maxunavailable.yaml
    
  2. Rufen Sie den Status des PDB auf.

    kubectl get poddisruptionbudgets -n mysql1 mysql-pdb -o yaml
    

    Im status-Abschnitt der Ausgabe sehen Sie sich die Anzahl der Pods currentHealthy und desiredHealthy an. Die Ausgabe sieht in etwa so aus:

    status:
    ...
      currentHealthy: 3
      desiredHealthy: 2
      disruptionsAllowed: 1
      expectedPods: 3
    ...
    

Upgrade der MySQL-Binärdateien planen

Kubernetes und GKE bieten Features zur Vereinfachung von Upgrades der MySQL-Binärdatei. Sie müssen jedoch einige Vorgänge ausführen, um sich auf die Upgrades vorzubereiten.

Beachten Sie vor dem Upgrade die folgenden Hinweise:

  • Upgrades sollten zuerst in einer Testumgebung durchgeführt werden. Für Produktionssysteme sollten Sie weitere Tests in einer Vorproduktionsumgebung machen.
  • Bei einigen binären Releases ist kein Downgrade der Version mehr möglich, nachdem ein Upgrade durchgeführt wurde. Nehmen Sie sich die Zeit, um die Auswirkungen eines Upgrades zu verstehen.
  • Replikationsquellen können in eine neuere Version repliziert werden. Das Kopieren von einer neueren in eine ältere Version wird jedoch in der Regel nicht unterstützt.
  • Achten Sie darauf, dass Sie eine vollständige Datenbanksicherung haben, bevor Sie die aktualisierte Version bereitstellen.
  • Beachten Sie dabei den flüchtigen Charakter von Kubernetes-Pods. Jeder Konfigurationsstatus, der vom Pod gespeichert und nicht im nichtflüchtigen Volume enthalten ist, geht verloren, wenn der Pod noch einmal bereitgestellt wird.
  • Verwenden Sie für binäre MySQL-Upgrades dieselbe PDB, eine Aktualisierungsstrategie für Knotenpools und die zuvor beschriebenen Prüfungen.

In einer Produktionsumgebung sollten Sie folgende Best Practices befolgen:

  • Erstellen Sie ein Container-Image mit der neuen MySQL-Version.
  • Image-Build-Anweisungen in einem Versionsverwaltungs-Repository beibehalten
  • Verwenden Sie eine automatisierte Pipeline zum Erstellen und Testen von Images wie Cloud Build und speichern Sie die Binärdatei des Images in einer Image-Registry, z. B. Artifact Registry.

Zur Vereinfachung dieser Anleitung werden Sie kein Container-Image erstellen und beibehalten, sondern öffentliche MySQL-Images verwenden.

Aktualisierte MySQL-Binärdatei bereitstellen

Um das MySQL-Binärupgrade durchzuführen, führen Sie einen deklarativen Befehl aus, der die Image-Version der StatefulSet-Ressource ändert. GKE führt die erforderlichen Schritte aus, um den aktuellen Pod zu beenden, einen neuen Pod mit der aktualisierten Binärdatei bereitzustellen und den nichtflüchtigen Speicher an den neuen Pod anzuhängen.

  1. Prüfen Sie, ob das PDB erstellt wurde.

    kubectl get poddisruptionbudgets -n mysql1
    
  2. Liste der zustandsorientierten Sets abrufen.

    kubectl get statefulsets -n mysql1
    
  3. Rufen Sie die Liste der laufenden Pods mit dem app-Label ab.

    kubectl get pods --selector=app=mysql -n mysql1
    
  4. Aktualisieren Sie das MySQL-Image im zustandsorientierten Satz.

    kubectl  -n mysql1 \
        set image statefulset/dbc1 \
        mysql=mysql/mysql-server:8.0.30
    

    Die Ausgabe sieht in etwa so aus:

    statefulset.apps/mysql image updated
    
  5. Prüfen Sie den Status der beendenden Pods und neuen Pods.

    kubectl get pods --selector=app=mysql -n mysql1
    

Upgrade der MySQL-Binärdatei validieren

Während des Upgrades können Sie den Status des Rollouts, der neuen Pods und des vorhandenen Service prüfen.

  1. Bestätigen Sie das Upgrade mit dem Befehl rollout status.

    kubectl rollout status statefulset/dbc1 -n mysql1
    

    Die Ausgabe sieht in etwa so aus:

    partitioned roll out complete: 3 new pods have been updated...
    
  2. Um die Image-Version zu prüfen, inspizieren Sie das zustandsorientierte Set.

    kubectl get statefulsets -o wide -n mysql1
    

    Die Ausgabe sieht in etwa so aus:

    NAME   READY   AGE   CONTAINERS   IMAGES
    dbc1   3/3     37m   mysql        mysql/mysql-server:8.0.30
    
  3. Prüfen Sie den Clusterstatus.

    kubectl -n mysql1 \
         exec -it dbc1-0 -- \
           /bin/bash \
             -c 'mysqlsh \
             --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-1.mysql.mysql1.svc.cluster.local" \
             --js \
             --execute "print(dba.getClusterSet().status({extended:1})); print(\"\\n\")"'
    

    Suchen Sie bei jeder Clusterinstanz in der Ausgabe nach den Status- und Versionswerten. Die Ausgabe sieht in etwa so aus:

    ...
      "status": "ONLINE",
      "version": "8.0.30"
    ...
    

Rollback des letzten Rollouts der Anwendungsbereitstellung durchführen

Wenn Sie die Bereitstellung einer aktualisierten Binärversion wiederherstellen, wird der Rollout-Prozess rückgängig gemacht und es wird eine neue Gruppe von Pods mit der vorherigen Image-Version bereitgestellt.

Verwenden Sie den rollout undo-Befehl, um die Bereitstellung auf die vorherige Arbeitsversion zurückzusetzen:

kubectl rollout undo statefulset/dbc1 -n mysql1

Die Ausgabe sieht in etwa so aus:

statefulset.apps/dbc1 rolled back

Datenbankcluster horizontal skalieren

Um Ihren MySQL-InnoDB-Cluster horizontal zu skalieren, fügen Sie dem GKE-Cluster-Knotenpool zusätzliche Knoten hinzu (nur bei Verwendung von Standard), stellen zusätzliche MySQL-Instanzen bereit und fügen dann die einzelnen Instanzen dem vorhandenen MySQL-InnoDB-Cluster hinzu.

Knoten zum Standardcluster hinzufügen

Dieser Vorgang ist nicht erforderlich, wenn Sie einen Autopilot-Cluster verwenden.

Folgen Sie der nachstehenden Anleitung für Cloud Shell oder für die Google Cloud Console, um Ihrem Standardcluster Knoten hinzuzufügen. Eine ausführliche Anleitung finden Sie unter Größe eines Knotenpools ändern.

gcloud

Ändern Sie in Cloud Shell die Größe des Standardknotenpools auf acht Instanzen pro verwalteter Instanzgruppe.

gcloud container clusters resize ${CLUSTER_NAME} \
     --node-pool default-pool \
     --num-nodes=8

Console

So fügen Sie Ihrem Standardcluster Knoten hinzu:

  1. Öffnen Sie in der Google Cloud Console die Cluster-Seite gkemulti-west1.
  2. Wählen Sie Knoten aus und klicken Sie auf Standardpool.
  3. Scrollen Sie nach unten zu Instanzgruppen.
  4. Ändern Sie für jede Instanzgruppe den Number of nodes-Wert von 5 auf 8 Knoten.

MySQL-Pods dem primären Cluster hinzufügen

So stellen Sie zusätzliche MySQL-Pods bereit, um den Cluster horizontal zu skalieren:

  1. Aktualisieren Sie in Cloud Shell die Anzahl der Replikate im MySQL-Deployment von drei auf fünf Replikate.

    kubectl scale  -n mysql1 --replicas=5 -f c1-mysql.yaml
    
  2. Prüfen Sie den Fortschritt der Bereitstellung.

    kubectl -n mysql1 get pods --selector=app=mysql -o wide
    

    Wenn Sie feststellen möchten, ob die Pods bereit sind, überwachen Sie das Deployment mit dem --watch-Flag. Wenn Sie Autopilot-Cluster verwenden und Pod Unschedulable-Fehler angezeigt werden, kann dies darauf hindeuten, dass GKE Knoten bereitstellt, um die zusätzlichen Pods bereitzustellen.

  3. Gruppenreplikationseinstellungen für die neuen, dem Cluster hinzuzufügenden MySQL-Instanzen konfigurieren

    bash ../scripts/c1-clustersetup.sh 3 4
    

    Das Skript sendet die Befehle an die Instanzen, die auf den Pods mit den Ordinalzahlen 3 bis 4 ausgeführt werden.

  4. Öffnen Sie MySQL Shell.

    kubectl -n mysql1 \
      exec -it dbc1-0 -- \
          /bin/bash \
            -c 'mysqlsh \
            --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
    
  5. Konfigurieren Sie die beiden neuen MySQL-Instanzen.

    dba.configureInstance('root:$MYSQL_ROOT_PASSWORD@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    dba.configureInstance('root:$MYSQL_ROOT_PASSWORD@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    

    Die Befehle prüfen, ob die Instanz für die MySQL-InnoDB-Clusternutzung ordnungsgemäß konfiguriert ist, und führen die erforderlichen Konfigurationsänderungen durch.

  6. Fügen Sie dem primären Cluster eine der neuen Instanzen hinzu.

    cluster = dba.getCluster()
    cluster.addInstance('icadmin@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    
  7. Fügen Sie dem primären Cluster eine zweite neue Instanz hinzu.

    cluster.addInstance('icadmin@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    
  8. Rufen Sie den ClusterSet-Status ab, der auch den Clusterstatus enthält.

    clusterset = dba.getClusterSet()
    clusterset.status({extended: 1})
    

    Die Ausgabe sieht in etwa so aus:

    "domainName": "clusterset",
    "globalPrimaryInstance": "dbc1-0.mysql:3306",
    "metadataServer": "dbc1-0.mysql:3306",
    "primaryCluster": "mycluster",
    "status": "HEALTHY",
    "statusText": "All Clusters available."
    
  9. Beenden Sie MySQL Shell.

    \q
    

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Projekt löschen

Sie vermeiden weitere Kosten am einfachsten, wenn Sie das für die Anleitung erstellte Projekt löschen.

Google Cloud-Projekt löschen:

gcloud projects delete PROJECT_ID

Nächste Schritte