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. Um Fehlertoleranz und Hochverfügbarkeit zu gewährleisten, 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.
Nach der Bereitstellung weisen Sie einen Pod als primäre Instanz zu, die sowohl Lese- als auch Schreibvorgänge ausführt. Die beiden anderen Pods sind sekundäre schreibgeschützte Replikate. Wenn bei der primären Instanz ein Infrastrukturfehler auftritt, können Sie einen dieser beiden Replikat-Pods zur primären Instanz 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 anhand der 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. So können Sie die Ausfallsicherheit erhöhen, wenn der primäre Cluster nicht mehr verfügbar ist.
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 so angepasst, dass Verbindungen nach der Wahl an die neue primäre Datenbank gesendet werden. 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.
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.
Vorbereitung
Projekt einrichten
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.
-
Enable the GKE API.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.
-
Enable the GKE API.
Rollen einrichten
-
Grant roles to your user account. Run the following command once for each of the following IAM roles:
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_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
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:
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 auswählen, die sich in Ihrer Nähe befindet.
Legen Sie die Standardumgebungsvariablen fest.
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
Klonen Sie das Code-Repository.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
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
Erstellen Sie in Cloud Shell einen GKE AutoAutpilot-Cluster in der Region
us-west1
.gcloud container clusters create-auto $CLUSTER_NAME \ --region=$REGION
Rufen Sie die Anmeldedaten für den GKE-Cluster ab:.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Stellen Sie einen Service über drei Zonen hinweg bereit.
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 werdenreplicas:3
,podAntiAffinity
,requiredDuringSchedulingIgnoredDuringExecution
undtopologyKey: "topology.kubernetes.io/zone"
festgelegt.Prüfen Sie den Status der Bereitstellung.
kubectl get deployment prepare-three-zone-ha --watch
Wenn Sie drei Pods im Status „Bereit“ sehen, 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
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
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"
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 einen MySQL-StatefulSet bereit. Jedes StatefulSet besteht aus drei MySQL-Replikaten.
So stellen Sie das MySQL-StatefulSet bereit:
Erstellen Sie einen Namespace für das StatefulSet.
kubectl create namespace mysql1
Erstellen Sie das MySQL-Secret:
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.
Erstellen Sie die StorageClass.
kubectl apply -n mysql1 -f storageclass.yaml
Diese Speicherklasse verwendet den nichtflüchtigen Speichertyp
pd-balanced
, der eine Balance zwischen Leistung und Kosten bietet. DasvolumeBindingMode
-Feld ist aufWaitForFirstConsumer
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.StatefulSet der MySQL-Instanz-Pods bereitstellen.
kubectl apply -n mysql1 -f c1-mysql.yaml
Mit diesem Befehl wird das StatefulSet mit drei Replikaten bereitgestellt. 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 sind die Ressourcenlimits und ‑anfragen auf minimale Werte gesetzt, um Kosten zu sparen. Achten Sie bei der Planung einer Produktionsarbeitslast darauf, dass diese Werte den Anforderungen Ihrer Organisation entsprechen.
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.
Wenn alle drei Pods bereit sind, beenden Sie den Befehl mit
Ctrl+C
. WennPodUnscheduleable
-Fehler aufgrund unzureichender CPU- oder Arbeitsspeicherressourcen auftreten, warten Sie einige Minuten, bis die Steuerungsebene entsprechend der hohen Arbeitslast skaliert wurde.Die Ausgabe sieht in etwa so aus:
NAME READY AGE dbc1 1/3 39s dbc1 2/3 50s dbc1 3/3 73s
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 enthält den Pod-Namen, den GKE-Knotennamen und die Zone, in der der Knoten bereitgestellt wird. Sie 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:
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
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 vongroup_replication_ip_allowlist
.Öffnen Sie ein zweites Terminal, damit Sie nicht für jeden Pod eine Shell erstellen müssen.
Stellen Sie eine Verbindung zur MySQL-Shell im Pod her
dbc1-0
.kubectl -n mysql1 exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'
Prüfen Sie die Replikations-Zulassungsliste der MySQL-Gruppen, um eine Verbindung zu anderen Instanzen herzustellen.
\sql SELECT @@group_replication_ip_allowlist;
Die Ausgabe sieht in etwa so aus:
+----------------------------------+ | @@group_replication_ip_allowlist | +----------------------------------+ | mysql.mysql1.svc.cluster.local | +----------------------------------+
Prüfen Sie, ob
server-id
pro Instanz einmalig ist.\sql SELECT @@server_id;
Die Ausgabe sieht in etwa so aus:
+-------------+ | @@server_id | +-------------+ | 21 | +-------------+
Konfigurieren Sie jede Instanz für die Verwendung von MySQL InnoDB Cluster 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.
Prüfen Sie, 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 den MySQL InnoDB-Cluster mit dem MySQL Admin-Befehl createCluster
. 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:
Erstellen Sie den MySQL-InnoDB-Cluster.
var cluster=dba.createCluster('mycluster');
Durch Ausführen des Befehls
createCluster
werden folgende Vorgänge ausgelöst:- 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.
Fügen Sie dem Cluster die zweite Instanz hinzu.
cluster.addInstance('icadmin@dbc1-1.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
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.
Prü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 auch
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})
anrufen, um weitere Statusdetails zu erhalten.
Beispieldatenbank erstellen
So erstellen Sie eine Beispieldatenbank:
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) );
Fügen Sie Beispieldaten in die Datenbank ein. Um Daten einzufügen, 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');
Prüfen Sie, ob die Tabelle die drei im vorherigen Schritt eingefügten Zeilen enthält.
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 ein MySQL InnoDB-ClusterSet erstellen, um die Replikation von Ihrem primären Cluster zu Replikatclustern mithilfe eines dedizierten ClusterSet-Replikationskanals zu verwalten.
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:
Rufen Sie in Ihrem MySQL Shell-Terminal ein Clusterobjekt ab.
\js cluster=dba.getCluster()
Die Ausgabe sieht in etwa so aus:
<Cluster:mycluster>
Initialisieren Sie ein MySQL-InnoDB-ClusterSet mit dem vorhandenen MySQL-InnoDB-Cluster, das im Clusterobjekt als primär 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>
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 weitere Statusdetails zu erhalten, einschließlich Informationen zum Cluster.Beenden Sie die MySQL-Shell.
\q
Stellen Sie eine MySQL-Router bereit
Sie können einen MySQL-Router bereitstellen, um den Traffic der Clientanwendung an die richtigen 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:
Stellen Sie den MySQL-Router im Cloud Shell-Terminal 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
Prüfen Sie die Bereitschaft der MySQL-Router-Bereitstellung.
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 Sie3/3 OK
sehen.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-Instanzdbc1-0
verbunden ist.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::": { ... } } }
Beenden Sie die MySQL-Shell.
\q
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
Updates 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 Vereinfachung von 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.
So wenden Sie die PDB-Richtlinie auf Ihren Cluster an:
Wenden Sie die PDB-Richtlinie mit
kubectl
an.kubectl apply -n mysql1 -f mysql-pdb-maxunavailable.yaml
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 PodscurrentHealthy
unddesiredHealthy
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 die folgenden Überlegungen, bevor Sie mit dem Upgrade beginnen:
- 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 auf eine neuere Version repliziert werden. Das Kopieren von einer neueren Version in eine ältere wird jedoch in der Regel nicht unterstützt.
- Erstellen Sie vor der Bereitstellung der aktualisierten Version eine vollständige Datenbanksicherung.
- 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 Version von MySQL.
- Speichern Sie die Anleitung zum Erstellen des Images in einem Quellkontroll-Repository.
- 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
Zum Upgrade der MySQL-Binärdateien führen Sie einen deklarativen Befehl aus, mit dem die Image-Version der StatefulSet-Ressource geändert wird. GKE führt die erforderlichen Schritte aus, um den aktuellen Pod zu beenden, einen neuen Pod mit dem aktualisierten Binärprogramm bereitzustellen und den nichtflüchtigen Speicher an den neuen Pod anzuhängen.
Prüfen Sie, ob das PDB erstellt wurde.
kubectl get poddisruptionbudgets -n mysql1
Liste der StatefulSets abrufen
kubectl get statefulsets -n mysql1
Rufen Sie die Liste der laufenden Pods mit dem
app
-Label ab.kubectl get pods --selector=app=mysql -n mysql1
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
Prüfen Sie den Status der beendeten und der neuen Pods.
kubectl get pods --selector=app=mysql -n mysql1
Upgrade der MySQL-Binärdateien validieren
Während des Upgrades können Sie den Status des Roll-outs, der neuen Pods und des vorhandenen Dienstes prüfen.
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...
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
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" ...
Letztes App-Bereitstellungs-Rollback 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 detaillierte 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:
- Öffnen Sie in der Google Cloud Console die Cluster-Seite
gkemulti-west1
. - Wählen Sie Knoten aus und klicken Sie auf Standardpool.
- Scrollen Sie nach unten zu Instanzgruppen.
- Ändern Sie für jede Instanzgruppe den
Number of nodes
-Wert von 5 auf 8 Knoten.
MySQL-Pods zum primären Cluster hinzufügen
So stellen Sie zusätzliche MySQL-Pods bereit, um Ihren Cluster horizontal zu skalieren:
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
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 undPod Unschedulable
-Fehler angezeigt werden, kann dies darauf hindeuten, dass GKE Knoten bereitstellt, um die zusätzlichen Pods bereitzustellen.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.
Öffnen Sie MySQL Shell.
kubectl -n mysql1 \ exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh \ --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
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")});
Mit den Befehlen wird geprüft, ob die Instanz für die Verwendung von MySQL InnoDB Cluster richtig konfiguriert ist, und die erforderlichen Konfigurationsänderungen werden vorgenommen.
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'});
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'});
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."
Beenden Sie die 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.
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Nächste Schritte
- Wie die MySQL-Integration von Google Cloud Observability Leistungsmesswerte im Zusammenhang mit InnoDB erfasst.
- Informationen zur Sicherung für GKE, einem Dienst zum Sichern und Wiederherstellen von Arbeitslasten in GKE.
- Mehr über nichtflüchtige Volumes erfahren