Questo documento è destinato agli amministratori di database, ai Cloud Architect e ai professionisti operativi interessati al deployment di una topologia MySQL ad alta disponibilità su Google Kubernetes Engine.
Segui questo tutorial per scoprire come eseguire il deployment di un cluster InnoDB MySQL e di un ClusterSet InnoDB MySQL, oltre al middleware del router MySQL sul tuo cluster GKE e per eseguire gli upgrade.
Obiettivi
In questo tutorial imparerai a:- Creare ed eseguire il deployment di un servizio Kubernetes stateful.
- Esegui il deployment di un cluster MySQL InnoDB per l'alta disponibilità.
- Esegui il deployment del middleware del router per il routing delle operazioni del database.
- Esegui il deployment di un ClusterSet MySQL InnoDB per la tolleranza in caso di emergenza.
- Simula un failover del cluster MySQL.
- Esegui un upgrade della versione MySQL.
Le seguenti sezioni descrivono l'architettura della soluzione che creerai in questo tutorial.
Cluster MySQL InnoDB
Nel tuo cluster GKE a livello di regione, utilizzando uno StatefulSet, esegui il deployment di un'istanza di database MySQL con la denominazione e la configurazione necessarie per creare un cluster MySQL InnoDB. Per offrire tolleranza di errore e disponibilità elevata, esegui il deployment di tre pod di istanze di database. Ciò garantisce che la maggior parte dei pod in zone diverse sia disponibile in qualsiasi momento per un'elezione primaria riuscita utilizzando un protocollo di consenso e rende il cluster MySQL InnoDB tollerante ai singoli errori a livello di zona.
Una volta eseguito il deployment, designi un pod come istanza principale per gestire sia le operazioni di lettura che di scrittura. Gli altri due pod sono repliche secondarie di sola lettura. Se l'istanza principale riscontra un errore dell'infrastruttura, puoi promuovere uno di questi due pod di replica in modo che diventi il pod principale.
In uno spazio dei nomi separato, esegui il deployment di tre pod del router MySQL per fornire il routing delle connessioni e migliorare la resilienza. Anziché connettersi direttamente al servizio di database, le tue applicazioni si connettono ai pod del router MySQL. Ogni pod router è a conoscenza dello stato e dello scopo di ciascun pod di cluster InnoDB MySQL e instrada le operazioni dell'applicazione al rispettivo pod integro. Lo stato di routing viene memorizzato nella cache nei pod del router e aggiornato dai metadati del cluster archiviati su ciascun nodo del cluster InnoDB MySQL. In caso di errore dell'istanza, il router regola il routing delle connessioni a un'istanza live.
ClusterSet MySQL InnoDB
Puoi creare un ClusterSet MySQL InnoDB da un cluster InnoDB iniziale. Ciò consente di aumentare la tolleranza in caso di emergenza se il cluster primario non è più disponibile.
Se l'istanza principale del cluster MySQL InnoDB non è più disponibile, puoi promuovere un cluster di replica in ClusterSet come principale. Quando utilizzi il middleware del router MySQL, l'applicazione non deve monitorare l'integrità dell'istanza del database principale. Il routing viene modificato in modo da inviare connessioni alle nuove primarie dopo le elezioni. Tuttavia, è tua responsabilità assicurarti che le applicazioni che si connettono al middleware del router MySQL seguano le best practice per la resilienza, in modo che vengano effettuati nuovi tentativi di connessione in caso di errore durante il failover del cluster.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.
Prima di iniziare
Configura il progetto
- Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
-
Nella pagina del selettore di progetti della console Google Cloud, fai clic su Crea progetto per iniziare a creare un nuovo progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Attiva l'API GKE.
-
Nella pagina del selettore di progetti della console Google Cloud, fai clic su Crea progetto per iniziare a creare un nuovo progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Attiva l'API GKE.
Configura i ruoli
-
Concedi i ruoli al tuo Account Google. Esegui questo comando una volta per ciascuno dei seguenti ruoli IAM:
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
- Sostituisci
PROJECT_ID
con l'ID progetto. - Sostituisci
EMAIL_ADDRESS
con il tuo indirizzo email. - Sostituisci
ROLE
con ogni singolo ruolo.
- Sostituisci
configura l'ambiente
In questo tutorial utilizzerai Cloud Shell per gestire le risorse ospitate su Google Cloud. Docker, kubectl
e gcloud CLI sono
preinstallati in Cloud Shell.
Per utilizzare Cloud Shell per configurare il tuo ambiente:
Imposta le variabili di ambiente.
export PROJECT_ID=PROJECT_ID export CLUSTER_NAME=gkemulti-west export REGION=COMPUTE_REGION
Sostituisci i seguenti valori:
- PROJECT_ID: il tuo ID progetto Google Cloud.
- COMPUTE_REGION: la tua regione Compute Engine.
Per questo tutorial, la regione è
us-west1
. In genere, l'obiettivo è una regione vicina a te.
Imposta le variabili di ambiente predefinite.
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
clona il repository di codice.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Passa alla directory di lavoro.
cd kubernetes-engine-samples/databases/gke-stateful-mysql/kubernetes
crea un cluster GKE
In questa sezione creerai un cluster GKE a livello di regione. A differenza di un cluster di zona, il piano di controllo di un cluster a livello di regione viene replicato in diverse zone, quindi un'interruzione in una singola zona non rende il piano di controllo non disponibile.
Per creare un cluster GKE, segui questi passaggi:
Autopilot
In Cloud Shell, crea un cluster GKE Autopilot nella regione
us-west1
.gcloud container clusters create-auto $CLUSTER_NAME \ --region=$REGION
Recuperare le credenziali del cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Eseguire il deployment di un servizio su tre zone.
kubectl apply -f prepare-for-ha.yaml
Per impostazione predefinita, Autopilot esegue il provisioning delle risorse in due zone. Il deployment definito in
prepare-for-ha.yaml
assicura che Autopilot esegua il provisioning dei nodi in tre zone del cluster, impostandoreplicas:3
,podAntiAffinity
conrequiredDuringSchedulingIgnoredDuringExecution
etopologyKey: "topology.kubernetes.io/zone"
.Controlla lo stato del deployment.
kubectl get deployment prepare-three-zone-ha --watch
Quando vedi tre pod nello stato Pronto, annulla questo comando con
CTRL+C
. L'output è simile al seguente: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
Esegui questo script per confermare che è stato eseguito il deployment dei pod in tre zone.
bash ../scripts/inspect_pod_node.sh default
Ogni riga dell'output corrisponde a un pod, mentre la seconda colonna indica la zona cloud. L'output è simile al seguente:
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
In Cloud Shell, crea un cluster GKE Standard nella regione
us-west1
.gcloud container clusters create $CLUSTER_NAME \ --region=$REGION \ --machine-type="e2-standard-2" \ --disk-type="pd-standard" \ --num-nodes="5"
Recuperare le credenziali del cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Esegui il deployment degli StatefulSet MySQL
In questa sezione, eseguirai il deployment di un oggetto MySQL StatefulSet. Ogni StatefulSet è composto da tre repliche MySQL.
Per eseguire il deployment di MySQL StatefulSet, segui questi passaggi:
Creare uno spazio dei nomi per lo StatefulSet.
kubectl create namespace mysql1
Creare il secret MySQL.
kubectl apply -n mysql1 -f secret.yaml
La password viene sottoposta a deployment con ogni pod e viene utilizzata da script e comandi di gestione per il deployment di cluster MySQL InnoDB e ClusterSet in questo tutorial.
Creare il oggetto StorageClass.
kubectl apply -n mysql1 -f storageclass.yaml
Questa classe di archiviazione utilizza il tipo di Persistent Disk
pd-balanced
per bilanciare prestazioni e costi. Il campovolumeBindingMode
è impostato suWaitForFirstConsumer
, il che significa che GKE ritarda il provisioning di un PersistentVolume fino alla creazione del pod. Questa impostazione garantisce che venga eseguito il provisioning del disco nella stessa zona in cui viene pianificato il pod.Eseguire il deployment degli StatefulSet di pod di istanze MySQL.
kubectl apply -n mysql1 -f c1-mysql.yaml
Questo comando esegue il deployment dello StatefulSet composto da tre repliche. In questo tutorial, viene eseguito il deployment del cluster MySQL principale in tre zone di
us-west1
. L'output è simile al seguente:service/mysql created statefulset.apps/dbc1 created
In questo tutorial, i limiti delle risorse e le richieste sono impostati su valori minimi per risparmiare sui costi. Quando pianifichi un carico di lavoro di produzione, assicurati di impostare questi valori in modo appropriato per le esigenze della tua organizzazione.
Verifica che lo StatefulSet sia stato creato correttamente.
kubectl get statefulset -n mysql1 --watch
Potrebbero essere necessari circa 10 minuti prima che lo StatefulSet sia pronto.
Quando tutti e tre i pod sono in stato Pronto, esci dal comando utilizzando
Ctrl+C
. Se noti erroriPodUnscheduleable
dovuti a CPU o memoria insufficienti, attendi alcuni minuti affinché il piano di controllo venga ridimensionato per supportare il carico di lavoro di grandi dimensioni.L'output è simile al seguente:
NAME READY AGE dbc1 1/3 39s dbc1 2/3 50s dbc1 3/3 73s
Per ispezionare il posizionamento dei pod sui nodi del cluster GKE, esegui questo script:
bash ../scripts/inspect_pod_node.sh mysql1 mysql
L'output, simile al seguente, mostra il nome del pod, il nome del nodo GKE e la zona in cui viene eseguito il provisioning del nodo:
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
Le colonne nell'output rappresentano rispettivamente il nome host, la zona cloud e il nome del pod.
Il criterio
topologySpreadConstraints
nella specifica StatefulSet (c1-mysql.yaml
) indica allo scheduler di posizionare i pod in modo uniforme nel dominio in errore (topology.kubernetes.io/zone
).Il criterio
podAntiAffinity
applica il vincolo per cui i pod non devono essere posizionati sullo stesso nodo del cluster GKE (kubernetes.io/hostname
). Per i pod di istanza MySQL, questo criterio determina un deployment uniforme dei pod nelle tre zone della regione Google Cloud. Questo posizionamento consente l'alta disponibilità del cluster MySQL InnoDB posizionando ogni istanza del database in un dominio in errore separato.
Prepara il cluster MySQL InnoDB principale
Per configurare un cluster MySQL InnoDB, segui questi passaggi:
Nel terminale Cloud Shell, imposta le configurazioni di replica dei gruppi per le istanze MySQL da aggiungere al cluster.
bash ../scripts/c1-clustersetup.sh
Lo script si connetterà da remoto in ciascuna delle tre istanze MySQL per impostare e mantenere le seguenti variabili di ambiente:
group_replication_ip_allowlist
: consente all'istanza all'interno del cluster di connettersi a qualsiasi istanza del gruppo.binlog_transaction_dependency_tracking='WRITESET'
: consente transazioni in contemporanea senza conflitti.
Nelle versioni MySQL precedenti alla 8.0.22, utilizza
group_replication_ip_whitelist
anzichégroup_replication_ip_allowlist
.Apri un secondo terminale in modo da non dover creare una shell per ogni pod.
Connettiti alla shell di MySQL nel pod
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"'
Verifica la lista consentita di replica dei gruppi MySQL per la connessione ad altre istanze.
\sql SELECT @@group_replication_ip_allowlist;
L'output è simile al seguente:
+----------------------------------+ | @@group_replication_ip_allowlist | +----------------------------------+ | mysql.mysql1.svc.cluster.local | +----------------------------------+
Verifica che
server-id
sia univoco per ciascuna istanza.\sql SELECT @@server_id;
L'output è simile al seguente:
+-------------+ | @@server_id | +-------------+ | 21 | +-------------+
Configura ogni istanza per l'utilizzo del cluster MySQL InnoDB e crea un account amministratore su ogni istanza.
\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")});
Tutte le istanze devono avere lo stesso nome utente e la stessa password per il corretto funzionamento del cluster InnoDB MySQL. Ogni comando produce un output simile al seguente:
... 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.
Verifica che l'istanza sia pronta per essere utilizzata in un cluster InnoDB MySQL.
dba.checkInstanceConfiguration()
L'output è simile al seguente:
... The instance 'dbc1-0.mysql.mysql1.svc.cluster.local:3306' is valid to be used in an InnoDB cluster. { "status": "ok" }
Se vuoi, puoi connetterti a ogni istanza MySQL e ripetere questo comando. Ad esempio, esegui questo comando per verificare lo stato dell'istanza
dbc1-1
: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()"'
Crea il cluster MySQL InnoDB principale
Poi, crea il cluster MySQL InnoDB utilizzando il comando MySQL Admin createCluster
. Inizia con l'istanza dbc1-0
, che sarà l'istanza principale del cluster, quindi aggiungi altre due repliche al cluster.
Per inizializzare il cluster MySQL InnoDB, segui questi passaggi:
Crea il cluster InnoDB MySQL.
var cluster=dba.createCluster('mycluster');
L'esecuzione del comando
createCluster
attiva queste operazioni:- Eseguire il deployment dello schema di metadati.
- Verifica che la configurazione sia corretta per la replica dei gruppi.
- Registralo come istanza seed del nuovo cluster.
- Crea gli account interni necessari, ad esempio l'account utente di replica.
- Avvia replica gruppo.
Questo comando inizializza un cluster InnoDB MySQL con l'host
dbc1-0
come principale. Il riferimento del cluster è archiviato nella variabile del cluster.L'output è simile al seguente:
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.
Aggiungi la seconda istanza al cluster.
cluster.addInstance('icadmin@dbc1-1.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Aggiungi l'istanza rimanente al cluster.
cluster.addInstance('icadmin@dbc1-2.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
L'output è simile al seguente:
... The instance 'dbc1-2.mysql:3306' was successfully added to the cluster.
Verifica lo stato del cluster.
cluster.status()
Questo comando mostra lo stato del cluster. La topologia è composta da tre host, una principale e due secondarie. Se vuoi, puoi chiamare
cluster.status({extended:1})
.L'output è simile al seguente:
{ "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" }
Se vuoi, puoi chiamare
cluster.status({extended:1})
per ottenere ulteriori dettagli sullo stato.
Crea un database di esempio
Per creare un database di esempio:
Crea un database e carica i dati al suo interno.
\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) );
Inserisci i dati di esempio nel database. Per inserire i dati, devi avere una connessione all'istanza principale del cluster.
INSERT INTO loan (firstname, lastname, status) VALUES ( 'Fred','Flintstone','pending'); INSERT INTO loan (firstname, lastname, status) VALUES ( 'Betty','Rubble','approved');
Verifica che la tabella contenga le tre righe inserite nel passaggio precedente.
SELECT * FROM loan;
L'output è simile al seguente:
+---------+-----------+------------+----------+ | loan_id | firstname | lastname | status | +---------+-----------+------------+----------+ | 1 | Fred | Flintstone | pending | | 2 | Betty | Rubble | approved | +---------+-----------+------------+----------+ 2 rows in set (0.0010 sec)
Crea un ClusterSet InnoDB MySQL
Puoi creare un ClusterSet MySQL InnoDB per gestire la replica dal cluster principale ai cluster di replica, utilizzando un canale di replica ClusterSet dedicato.
Un ClusterSet MySQL InnoDB offre tolleranza di emergenza per i deployment di cluster InnoDB MySQL collegando un cluster MySQL InnoDB principale a una o più repliche in località alternative, ad esempio più zone e più regioni.
Se hai chiuso MySQL Shell, crea una nuova shell eseguendo questo comando in un nuovo terminale Cloud Shell:
kubectl -n mysql1 exec -it dbc1-0 -- \
/bin/bash -c 'mysqlsh \
--uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'
Per creare un ClusterSet MySQL InnoDB, segui questi passaggi:
Nel terminale MySQL Shell, recupera un oggetto cluster.
\js cluster=dba.getCluster()
L'output è simile al seguente:
<Cluster:mycluster>
Inizializza un ClusterSet MySQL InnoDB con il cluster MySQL InnoDB esistente archiviato nell'oggetto cluster come principale.
clusterset=cluster.createClusterSet('clusterset')
L'output è simile al seguente:
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>
Controlla lo stato del ClusterSet MySQL InnoDB.
clusterset.status()
L'output è simile al seguente:
{ "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." }
Facoltativamente, puoi chiamare
clusterset.status({extended:1})
per ottenere ulteriori dettagli sullo stato, incluse informazioni sul cluster.Esci dalla shell di MySQL.
\q
Esegui il deployment di un router MySQL
Puoi eseguire il deployment di un router MySQL per indirizzare il traffico delle applicazioni client ai cluster corretti. Il routing si basa sulla porta di connessione dell'applicazione che esegue un'operazione di database:
- Le scritture vengono instradate all'istanza del cluster principale nel ClusterSet principale.
- Le letture possono essere instradate a qualsiasi istanza nel cluster principale.
Quando avvii un router MySQL, viene eseguito il bootstrapping del deployment InnoDB ClusterSet di MySQL. Le istanze del router MySQL collegate al ClusterSet MySQL InnoDB sono a conoscenza di eventuali switchover controllati o failover di emergenza e indirizzano il traffico al nuovo cluster principale.
Per eseguire il deployment di un router MySQL, segui questi passaggi:
Nel terminale Cloud Shell, esegui il deployment del router MySQL.
kubectl apply -n mysql1 -f c1-router.yaml
L'output è simile al seguente:
configmap/mysql-router-config created service/mysql-router created deployment.apps/mysql-router created
Verifica l'idoneità del deployment del router MySQL.
kubectl -n mysql1 get deployment mysql-router --watch
Quando tutti e tre i pod sono pronti, l'output è simile al seguente:
NAME READY UP-TO-DATE AVAILABLE AGE mysql-router 3/3 3 0 3m36s
Se viene visualizzato un errore
PodUnschedulable
nella console, attendi uno o due minuti mentre GKE esegue il provisioning di più nodi. Aggiorna; dovresti vedere3/3 OK
.Avvia MySQL Shell su qualsiasi membro del cluster esistente.
kubectl -n mysql1 exec -it dbc1-0 -- \ /bin/bash -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
Questo comando si connette al pod
dbc1-0
, quindi avvia una shell connessa all'istanza MySQLdbc1-0
.Verifica la configurazione del router.
clusterset=dba.getClusterSet() clusterset.listRouters()
L'output è simile al seguente:
{ "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::": { ... } } }
Esci dalla shell di MySQL.
\q
Esegui questo script per ispezionare il posizionamento dei pod del router MySQL.
bash ../scripts/inspect_pod_node.sh mysql1 | sort
Lo script mostra il nodo e il posizionamento della zona Cloud di tutti i pod nello spazio dei nomi
mysql1
, dove l'output è simile al seguente: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
Puoi osservare che i pod del router MySQL sono distribuiti equamente tra le zone, ovvero non sono posizionati sullo stesso nodo di un pod MySQL o sullo stesso nodo di un altro pod del router MySQL.
Gestisci gli upgrade dei cluster InnoDB GKE e MySQL
Gli aggiornamenti per MySQL e Kubernetes vengono rilasciati con cadenza regolare. Segui le best practice operative per aggiornare regolarmente l'ambiente software. Per impostazione predefinita, GKE gestisce per te gli upgrade di cluster e pool di nodi. Kubernetes e GKE forniscono anche funzionalità aggiuntive per agevolare gli upgrade del software MySQL.
Pianifica gli upgrade di GKE
Puoi adottare misure proattive e impostare configurazioni per mitigare i rischi e facilitare un upgrade dei cluster più fluido quando esegui servizi stateful, tra cui:
Cluster standard: segui le best practice di GKE per l'upgrade dei cluster. Scegli una strategia di upgrade appropriata per assicurarti che gli upgrade vengano eseguiti durante il periodo del periodo di manutenzione:
- Scegli gli upgrade di picco se l'ottimizzazione dei costi è importante e se i tuoi carichi di lavoro possono tollerare un arresto controllato in meno di 60 minuti.
- Scegli gli upgrade blu/verde se i tuoi carichi di lavoro tollerano meno le interruzioni ed è accettabile un aumento temporaneo dei costi dovuto a un maggiore utilizzo delle risorse.
Per saperne di più, consulta Eseguire l'upgrade di un cluster che esegue un carico di lavoro stateful. Viene eseguito l'upgrade automatico dei cluster Autopilot, in base al canale di rilascio selezionato.
Utilizza i periodi di manutenzione per assicurarti che gli upgrade vengano eseguiti quando previsto. Prima del periodo di manutenzione, assicurati che i backup del database siano riusciti.
Prima di consentire il traffico ai nodi MySQL di cui è stato eseguito l'upgrade, utilizza i probe di idoneità e i probe di attività per assicurarti che siano pronti per il traffico.
Crea probe che valutano se la replica è sincronizzata prima di accettare il traffico. Questo può essere fatto tramite script personalizzati, a seconda della complessità e della scala del database.
Imposta un criterio di budget per l'interruzione dei pod (PDB)
Quando un cluster MySQL InnoDB è in esecuzione su GKE, deve essere presente un numero sufficiente di istanze in esecuzione in qualsiasi momento per soddisfare il requisito del quorum.
In questo tutorial, dato un cluster MySQL di tre istanze, devono essere disponibili due istanze per formare un quorum. Un criterio PodDisruptionBudget
consente di limitare il numero di pod che possono essere arrestati in un determinato momento. È utile sia per le operazioni relative allo stato stazionario dei servizi stateful sia per gli upgrade dei cluster.
Per garantire che un numero limitato di pod vengano interrotti contemporaneamente, imposta il
PDB per il tuo carico di lavoro su maxUnavailable: 1
. Ciò garantisce che, in qualsiasi momento dell'operazione del servizio, non sia in esecuzione più di un pod.
Il seguente manifest dei criteri PodDisruptionBudget
imposta il numero massimo di pod non disponibili su uno per la tua applicazione MySQL.
Per applicare il criterio PDB al cluster, segui questi passaggi:
Applica il criterio PDB utilizzando
kubectl
.kubectl apply -n mysql1 -f mysql-pdb-maxunavailable.yaml
Visualizza lo stato del PDB.
kubectl get poddisruptionbudgets -n mysql1 mysql-pdb -o yaml
Nella sezione
status
dell'output, vedi il numero di podcurrentHealthy
edesiredHealthy
. L'output è simile al seguente:status: ... currentHealthy: 3 desiredHealthy: 2 disruptionsAllowed: 1 expectedPods: 3 ...
Pianifica gli upgrade dei programmi binari MySQL
Kubernetes e GKE forniscono funzionalità che facilitano l'upgrade del programma binario MySQL. Tuttavia, devi eseguire alcune operazioni per prepararti agli upgrade.
Prima di iniziare il processo di upgrade, tieni presente quanto segue:
- Gli upgrade devono essere prima eseguiti in un ambiente di test. Per i sistemi di produzione, devi eseguire ulteriori test in un ambiente di pre-produzione.
- Per alcune release binarie, non puoi eseguire il downgrade della versione dopo l'esecuzione di un upgrade. Prenditi il tempo necessario per comprendere le implicazioni di un upgrade.
- Le origini di replica possono essere replicate in una versione più recente. Tuttavia, la copia da una versione più recente a una precedente non è in genere supportata.
- Assicurati di avere un backup completo del database prima di eseguire il deployment della versione aggiornata.
- Tieni presente la natura temporanea dei pod Kubernetes. Qualsiasi stato di configurazione archiviato dal pod e non presente nel volume permanente andrà perso quando viene eseguito nuovamente il deployment del pod.
- Per gli upgrade dei file binari di MySQL, utilizza la stessa PDB, la stessa strategia di aggiornamento del pool di nodi e gli stessi probe come descritto in precedenza.
In un ambiente di produzione, dovresti seguire queste best practice:
- Crea un'immagine container con la nuova versione di MySQL.
- Mantieni le istruzioni di compilazione dell'immagine in un repository di controllo del codice sorgente.
- Utilizza una pipeline automatica di test e creazione delle immagini come Cloud Build e archivia il file binario delle immagini in un registro di immagini come Artifact Registry.
Per semplificare questo tutorial, non creerai e renderai permanente un'immagine container, ma utilizzerai le immagini MySQL pubbliche.
Esegui il deployment del programma binario MySQL di cui è stato eseguito l'upgrade
Per eseguire l'upgrade del programma binario MySQL, devi inviare un comando dichiarativo che modifichi la versione immagine della risorsa StatefulSet. GKE esegue i passaggi necessari per arrestare il pod attuale, eseguire il deployment di un nuovo pod con il programma binario aggiornato e collegare il disco permanente al nuovo pod.
Verifica che il PDB sia stato creato.
kubectl get poddisruptionbudgets -n mysql1
Recupera l'elenco degli oggetti StatefulSet.
kubectl get statefulsets -n mysql1
Recupera l'elenco dei pod in esecuzione utilizzando l'etichetta
app
.kubectl get pods --selector=app=mysql -n mysql1
Aggiorna l'immagine MySQL nel set stateful.
kubectl -n mysql1 \ set image statefulset/dbc1 \ mysql=mysql/mysql-server:8.0.30
L'output è simile al seguente:
statefulset.apps/mysql image updated
Controlla lo stato dei pod in fase di arresto e dei nuovi pod.
kubectl get pods --selector=app=mysql -n mysql1
Convalida l'upgrade del programma binario MySQL
Durante l'upgrade, puoi verificare lo stato dell'implementazione, dei nuovi pod e del servizio esistente.
Conferma l'upgrade eseguendo il comando
rollout status
.kubectl rollout status statefulset/dbc1 -n mysql1
L'output è simile al seguente:
partitioned roll out complete: 3 new pods have been updated...
Conferma la versione dell'immagine ispezionando il set stateful.
kubectl get statefulsets -o wide -n mysql1
L'output è simile al seguente:
NAME READY AGE CONTAINERS IMAGES dbc1 3/3 37m mysql mysql/mysql-server:8.0.30
Controlla lo stato del cluster.
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\")"'
Per ogni istanza del cluster, cerca i valori dello stato e della versione nell'output. L'output è simile al seguente:
... "status": "ONLINE", "version": "8.0.30" ...
Esegui il rollback dell'ultima implementazione del deployment dell'app
Quando ripristini il deployment di una versione binaria aggiornata, il processo di implementazione viene invertito e viene eseguito il deployment di un nuovo set di pod con la versione immagine precedente.
Per ripristinare il deployment alla versione funzionante precedente, usa il comando rollout undo
:
kubectl rollout undo statefulset/dbc1 -n mysql1
L'output è simile al seguente:
statefulset.apps/dbc1 rolled back
Scala il tuo cluster di database orizzontalmente
Per scalare orizzontalmente il tuo cluster MySQL InnoDB, aggiungi altri nodi al pool di nodi del cluster GKE (richiesto solo se utilizzi Standard), esegui il deployment di altre istanze MySQL, quindi aggiungi ogni istanza al cluster InnoDB esistente di MySQL.
Aggiungi nodi al cluster Standard
Questa operazione non è necessaria se utilizzi un cluster Autopilot.
Per aggiungere nodi al cluster Standard, segui le istruzioni riportate di seguito per Cloud Shell o per la console Google Cloud. Per la procedura dettagliata, consulta Ridimensiona un pool di nodi
gcloud
In Cloud Shell, ridimensiona il pool di nodi predefinito a otto istanze in ogni gruppo di istanze gestite.
gcloud container clusters resize ${CLUSTER_NAME} \
--node-pool default-pool \
--num-nodes=8
Console
Per aggiungere nodi al cluster Standard:
- Apri la pagina Cluster
gkemulti-west1
nella console Google Cloud. - Seleziona Nodi e fai clic su Pool predefinito.
- Scorri verso il basso fino a Gruppi di istanze.
- Per ogni gruppo di istanze, ridimensiona il valore
Number of nodes
da 5 a 8 nodi.
Aggiungi i pod MySQL al cluster principale
Per eseguire il deployment di pod MySQL aggiuntivi per scalare il cluster orizzontalmente, segui questi passaggi:
In Cloud Shell, aggiorna il numero di repliche nel deployment MySQL da tre a cinque repliche.
kubectl scale -n mysql1 --replicas=5 -f c1-mysql.yaml
Verifica l'avanzamento del deployment.
kubectl -n mysql1 get pods --selector=app=mysql -o wide
Per determinare se i pod sono pronti, usa il flag
--watch
per osservare il deployment. Se utilizzi cluster Autopilot e vedi erroriPod Unschedulable
, è possibile che GKE stia eseguendo il provisioning dei nodi per ospitare i pod aggiuntivi.Configura le impostazioni di replica dei gruppi per le nuove istanze MySQL da aggiungere al cluster
bash ../scripts/c1-clustersetup.sh 3 4
Lo script invia i comandi alle istanze in esecuzione sui pod con ordinali da 3 a 4.
Apri la shell di MySQL.
kubectl -n mysql1 \ exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh \ --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
Configura le due nuove istanze MySQL.
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")});
I comandi controllano se l'istanza è configurata correttamente per l'utilizzo del cluster MySQL InnoDB ed eseguono le modifiche necessarie alla configurazione.
Aggiungi una delle nuove istanze al cluster principale.
cluster = dba.getCluster() cluster.addInstance('icadmin@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Aggiungi una seconda nuova istanza al cluster principale.
cluster.addInstance('icadmin@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Ottenere lo stato ClusterSet, che include anche lo stato del cluster.
clusterset = dba.getClusterSet() clusterset.status({extended: 1})
L'output è simile al seguente:
"domainName": "clusterset", "globalPrimaryInstance": "dbc1-0.mysql:3306", "metadataServer": "dbc1-0.mysql:3306", "primaryCluster": "mycluster", "status": "HEALTHY", "statusText": "All Clusters available."
Esci dalla shell di MySQL.
\q
Esegui la pulizia
Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.
Elimina il progetto
Il modo più semplice per evitare la fatturazione è eliminare il progetto che hai creato per il tutorial.
Elimina un progetto Google Cloud:
gcloud projects delete PROJECT_ID
Passaggi successivi
- Scopri di più su come l'integrazione di Google Cloud Observability MySQL raccoglie metriche sulle prestazioni relative a InnoDB.
- Scopri di più su backup per GKE, un servizio per il backup e il ripristino dei carichi di lavoro in GKE.
- Esplora i volumi permanenti in modo più dettagliato.