Ce document est destiné aux administrateurs de bases de données, aux architectes cloud et aux professionnels des opérations qui souhaitent déployer une topologie MySQL à disponibilité élevée sur Google Kubernetes Engine.
Suivez ce tutoriel pour découvrir comment déployer un cluster MySQL InnoDB, un ClusterSet MySQL InnoDB et un middleware MySQL Router sur votre cluster GKE, et comment effectuer des mises à niveau.
Objectifs
Dans ce tutoriel, vous allez apprendre à effectuer les opérations suivantes :- Créer et déployer un service Kubernetes avec état
- Déployer un cluster MySQL InnoDB pour la haute disponibilité
- Déployer un middleware Router pour le routage des opérations de base de données
- Déployer un ClusterSet MySQL InnoDB pour la tolérance aux sinistres
- Simuler un basculement de cluster MySQL
- Mettre à niveau une version MySQL
Les sections suivantes décrivent l'architecture de la solution que vous allez créer dans ce tutoriel.
Cluster MySQL InnoDB
Dans votre cluster GKE régional, à l'aide d'un StatefulSet, vous déployez une instance de base de données MySQL avec la dénomination et la configuration nécessaires pour créer un cluster MySQL InnoDB. Pour assurer la tolérance aux pannes et la haute disponibilité, vous déployez trois pods d'instance de base de données. Ainsi, la majorité des pods de différentes zones sont disponibles à tout moment pour une élection primaire réussie à l'aide d'un protocole de consensus, et votre cluster InnoDB MySQL est tolérant aux défaillances de zone uniques.
Une fois le déploiement effectué, vous désignez un pod comme instance principale pour diffuser les opérations de lecture et d'écriture. Les deux autres pods sont des instances répliquées secondaires en lecture seule. Si l'instance principale subit une défaillance d'infrastructure, vous pouvez promouvoir l'un de ces deux pods d'instances répliquées en instance principale.
Vous déployez trois pods MySQL Router dans un espace de noms distinct pour assurer le routage de connexion afin d'améliorer la résilience. Au lieu de se connecter directement au service de base de données, vos applications se connectent aux pods MySQL Router. Les pods Router connaissent l'état et l'objectif de chaque pod du cluster MySQL InnoDB, et acheminent les opérations d'application vers le pod opérationnel correspondant. L'état de routage est mis en cache dans les pods Router et mis à jour à partir des métadonnées du cluster stockées sur chaque nœud du cluster InnoDB MySQL. En cas de défaillance d'une instance, le routeur ajuste le routage des connexions vers une instance active.
ClusterSet MySQL InnoDB
Vous pouvez créer un ClusterSet MySQL InnoDB à partir d'un cluster MySQL InnoDB initial. Cela vous permet d'augmenter la tolérance aux sinistres si le cluster principal n'est plus disponible.
Si l'instance principale de cluster MySQL InnoDB n'est plus disponible, vous pouvez promouvoir un cluster d'instances répliquées du ClusterSet en instance principale. Lorsque vous utilisez le middleware MySQL Router, votre application n'a pas besoin de suivre l'état de l'instance de base de données principale. Le routage est ajusté pour envoyer des connexions à la nouvelle instance principale une fois l'élection terminée. Cependant, il est de votre responsabilité de vérifier que les applications qui se connectent à votre middleware MySQL Router suivent les bonnes pratiques de résilience, afin que de nouvelles tentatives d'exécution des connexions soient effectuées en cas d'erreur lors du basculement du cluster.
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Avant de commencer
Configurer votre projet
- 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.
-
Make sure that billing is enabled for your Google Cloud project.
-
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.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
Configurer les rôles
-
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: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
Configurer votre environnement
Dans ce tutoriel, vous utilisez Cloud Shell pour gérer les ressources hébergées sur Google Cloud. Cloud Shell est préinstallé avec Docker et les CLI kubectl
et gcloud.
Pour utiliser Cloud Shell afin de configurer votre environnement, procédez comme suit :
Définir des variables d'environnement.
export PROJECT_ID=PROJECT_ID export CLUSTER_NAME=gkemulti-west export REGION=COMPUTE_REGION
Remplacez les valeurs suivantes :
- PROJECT_ID : ID de votre projet Google Cloud.
- COMPUTE_REGION : votre région Compute Engine.
Pour ce tutoriel, la région est
us-west1
. En règle générale, vous définissez une région proche de vous.
Définissez les variables d'environnement par défaut.
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
Clonez le dépôt de code.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Accédez au répertoire de travail.
cd kubernetes-engine-samples/databases/gke-stateful-mysql/kubernetes
Créer un cluster GKE
Dans cette section, vous allez créer un cluster GKE régional. Contrairement à un cluster zonal, le plan de contrôle d'un cluster régional est répliqué dans plusieurs zones. Par conséquent, l'interruption d'une zone unique n'entraîne pas l'indisponibilité du plan de contrôle.
Pour créer un cluster GKE, procédez comme suit :
Autopilot
Dans Cloud Shell, créez un cluster GKE Autopilot dans la région
us-west1
.gcloud container clusters create-auto $CLUSTER_NAME \ --region=$REGION
Obtenez les identifiants du cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Déployez un service dans trois zones.
kubectl apply -f prepare-for-ha.yaml
Par défaut, Autopilot provisionne des ressources dans deux zones. Le déploiement défini dans
prepare-for-ha.yaml
garantit que Autopilot provisionne les nœuds dans trois zones de votre cluster en définissantreplicas:3
,podAntiAffinity
avecrequiredDuringSchedulingIgnoredDuringExecution
, ettopologyKey: "topology.kubernetes.io/zone"
.Vérifiez l'état du déploiement.
kubectl get deployment prepare-three-zone-ha --watch
Lorsque trois pods sont prêts, annulez cette commande avec
CTRL+C
. Le résultat ressemble à ce qui suit :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
Exécutez ce script pour vérifier que vos pods ont été déployés dans trois zones.
bash ../scripts/inspect_pod_node.sh default
Chaque ligne de la sortie correspond à un pod et la deuxième colonne indique la zone cloud. Le résultat ressemble à ce qui suit :
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
Dans Cloud Shell, créez un cluster GKE standard dans la région
us-west1
.gcloud container clusters create $CLUSTER_NAME \ --region=$REGION \ --machine-type="e2-standard-2" \ --disk-type="pd-standard" \ --num-nodes="5"
Obtenez les identifiants du cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Déployer des StatefulSets MySQL
Dans cette section, vous allez déployer un StatefulSet MySQL. Chaque StatefulSet est constitué de trois instances répliquées MySQL.
Pour déployer le StatefulSet MySQL, procédez comme suit :
Créez un espace de noms pour le StatefulSet.
kubectl create namespace mysql1
Créez le secret MySQL.
kubectl apply -n mysql1 -f secret.yaml
Le mot de passe est déployé avec chaque pod. Il permet aux scripts et aux commandes de gestion de déployer le cluster et le ClusterSet MySQL InnoDB dans ce tutoriel.
Créez la ressource StorageClass.
kubectl apply -n mysql1 -f storageclass.yaml
Cette classe de stockage utilise le type de disque persistant
pd-balanced
qui équilibre les performances et les coûts. Le champvolumeBindingMode
est défini surWaitForFirstConsumer
, ce qui signifie que GKE retarde le provisionnement d'un PersistentVolume jusqu'à ce que le pod soit créé. Ce paramètre garantit que le disque est provisionné dans la zone dans laquelle le pod est programmé.Déployez le StatefulSet des pods d'instances MySQL.
kubectl apply -n mysql1 -f c1-mysql.yaml
Cette commande déploie le StatefulSet composé de trois instances répliquées. Dans ce tutoriel, le cluster MySQL principal est déployé dans trois zones de la région
us-west1
. Le résultat ressemble à ce qui suit :service/mysql created statefulset.apps/dbc1 created
Dans ce tutoriel, les limites et demandes de ressources sont définies sur des valeurs minimales afin de réduire les coûts. Lorsque vous planifiez une charge de travail de production, assurez-vous de définir ces valeurs de manière appropriée pour les besoins de votre organisation.
Vérifiez que le StatefulSet a bien été créé.
kubectl get statefulset -n mysql1 --watch
La préparation du StatefulSet peut prendre environ 10 minutes.
Lorsque les trois pods sont prêts, quittez la commande à l'aide de
Ctrl+C
. Si vous voyez des erreursPodUnscheduleable
en raison d'un processeur ou d'une mémoire insuffisants, attendez quelques minutes que le plan de contrôle procède au redimensionnement pour s'adapter à la charge de travail volumineuse.Le résultat ressemble à ce qui suit :
NAME READY AGE dbc1 1/3 39s dbc1 2/3 50s dbc1 3/3 73s
Pour inspecter l'emplacement des pods sur les nœuds du cluster GKE, exécutez le script suivant :
bash ../scripts/inspect_pod_node.sh mysql1 mysql
La sortie affiche le nom du pod, le nom du nœud GKE et la zone dans laquelle le nœud est provisionné. Elle ressemble à ce qui suit :
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
Les colonnes de la sortie représentent respectivement le nom d'hôte, la zone cloud et le nom du pod.
La règle
topologySpreadConstraints
de la spécification StatefulSet (c1-mysql.yaml
) indique au programmeur de placer les pods uniformément dans le domaine de défaillance (topology.kubernetes.io/zone
).La règle
podAntiAffinity
applique la contrainte selon laquelle les pods ne doivent pas être placés sur le même nœud du cluster GKE (kubernetes.io/hostname
). Pour les pods des instances MySQL, cette règle entraîne le déploiement uniforme des pods dans les trois zones de la région Google Cloud. Cet emplacement permet d'assurer la haute disponibilité du cluster MySQL InnoDB en plaçant chaque instance de base de données dans un domaine de défaillance distinct.
Préparer le cluster MySQL InnoDB principal
Pour configurer un cluster InnoDB MySQL, procédez comme suit :
Dans le terminal Cloud Shell, définissez les configurations de réplication de groupes pour les instances MySQL à ajouter à votre cluster.
bash ../scripts/c1-clustersetup.sh
Le script se connectera à distance à chacune des trois instances MySQL pour définir et conserver les variables d'environnement suivantes :
group_replication_ip_allowlist
: permet à l'instance du cluster de se connecter à n'importe quelle instance du groupe.binlog_transaction_dependency_tracking='WRITESET'
: autorise les transactions en parallèle qui n'entrent pas en conflit.
Dans les versions de MySQL antérieures à la version 8.0.22, utilisez
group_replication_ip_whitelist
au lieu degroup_replication_ip_allowlist
.Ouvrez un deuxième terminal, de sorte que vous n'ayez pas à créer un shell pour chaque pod.
Connectez-vous à MySQL Shell sur le 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"'
Vérifiez la liste d'autorisation de réplication de groupes MySQL pour vous connecter à d'autres instances.
\sql SELECT @@group_replication_ip_allowlist;
Le résultat ressemble à ce qui suit :
+----------------------------------+ | @@group_replication_ip_allowlist | +----------------------------------+ | mysql.mysql1.svc.cluster.local | +----------------------------------+
Vérifiez que l'identifiant
server-id
est unique sur chacune des instances.\sql SELECT @@server_id;
Le résultat ressemble à ce qui suit :
+-------------+ | @@server_id | +-------------+ | 21 | +-------------+
Configurez les instances de sorte qu'elles utilisent le cluster InnoDB MySQL et créez un compte administrateur sur chaque instance.
\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")});
Toutes les instances doivent avoir le même nom d'utilisateur et le même mot de passe pour que le cluster MySQL InnoDB fonctionne correctement. Chaque commande génère une sortie semblable à celle-ci :
... 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.
Vérifiez que l'instance est prête à être utilisée dans un cluster MySQL InnoDB.
dba.checkInstanceConfiguration()
Le résultat ressemble à ce qui suit :
... The instance 'dbc1-0.mysql.mysql1.svc.cluster.local:3306' is valid to be used in an InnoDB cluster. { "status": "ok" }
Vous pouvez éventuellement vous connecter à chaque instance MySQL et répéter cette commande. Par exemple, exécutez la commande suivante pour vérifier l'état sur l'instance
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()"'
Créer le cluster MySQL InnoDB principal
Créez ensuite le cluster MySQL InnoDB à l'aide de la commande d'administration MySQL createCluster
. Commencez avec l'instance dbc1-0
, qui sera l'instance principale du cluster, puis ajoutez deux autres instances répliquées au cluster.
Pour initialiser le cluster MySQL InnoDB, procédez comme suit :
Créez le cluster MySQL InnoDB.
var cluster=dba.createCluster('mycluster');
L'exécution de la commande
createCluster
déclenche les opérations suivantes :- Déploiement du schéma de métadonnées
- Vérification que la configuration de la réplication de groupe est correcte
- Enregistrement de la configuration en tant qu'instance source du nouveau cluster
- Création des comptes internes nécessaires, tels que le compte utilisateur de réplication
- Démarrage de la réplication de groupe
Cette commande initialise un cluster MySQL InnoDB avec l'hôte
dbc1-0
en tant qu'instance principale. La référence du cluster est stockée dans la variable du cluster.La sortie ressemble à ceci :
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.
Ajoutez la deuxième instance au cluster.
cluster.addInstance('icadmin@dbc1-1.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Ajoutez l'instance restante au cluster.
cluster.addInstance('icadmin@dbc1-2.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Le résultat ressemble à ce qui suit :
... The instance 'dbc1-2.mysql:3306' was successfully added to the cluster.
Vérifiez l'état du cluster.
cluster.status()
Cette commande affiche l'état du cluster. La topologie se compose de trois hôtes, une instance principale et deux secondaires. Vous pouvez éventuellement appeler
cluster.status({extended:1})
.Le résultat ressemble à ce qui suit :
{ "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" }
Vous pouvez éventuellement appeler
cluster.status({extended:1})
pour obtenir d'autres détails sur l'état.
Créer un exemple de base de données
Pour créer un exemple de base de données, procédez comme suit :
Créez une base de données et chargez des données dans la base de données.
\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) );
Insérez des exemples de données dans la base de données. Pour insérer des données, vous devez être connecté à l'instance principale du cluster.
INSERT INTO loan (firstname, lastname, status) VALUES ( 'Fred','Flintstone','pending'); INSERT INTO loan (firstname, lastname, status) VALUES ( 'Betty','Rubble','approved');
Vérifiez que la table contient les trois lignes insérées à l'étape précédente.
SELECT * FROM loan;
Le résultat ressemble à ce qui suit :
+---------+-----------+------------+----------+ | loan_id | firstname | lastname | status | +---------+-----------+------------+----------+ | 1 | Fred | Flintstone | pending | | 2 | Betty | Rubble | approved | +---------+-----------+------------+----------+ 2 rows in set (0.0010 sec)
Créer un ClusterSet MySQL InnoDB
Vous pouvez créer un ClusterSet MySQL InnoDB pour gérer la réplication de votre cluster principal vers des clusters d'instances répliquées à l'aide d'un canal de réplication ClusterSet dédié.
Un ClusterSet MySQL InnoDB assure la tolérance aux sinistres pour les déploiements de clusters MySQL InnoDB en associant un cluster MySQL InnoDB principal à une ou plusieurs instances répliquées situées dans d'autres emplacements, tels que plusieurs zones et plusieurs régions.
Si vous avez fermé MySQL Shell, créez un shell en exécutant la commande suivante dans un nouveau terminal 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"'
Pour créer un ClusterSet MySQL InnoDB, procédez comme suit :
Dans votre terminal MySQL Shell, obtenez un objet de cluster.
\js cluster=dba.getCluster()
Le résultat ressemble à ce qui suit :
<Cluster:mycluster>
Initialisez un ClusterSet MySQL InnoDB avec le cluster MySQL InnoDB existant stocké dans l'objet de cluster en tant qu'instance principale.
clusterset=cluster.createClusterSet('clusterset')
Le résultat ressemble à ce qui suit :
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>
Vérifiez l'état de votre ClusterSet MySQL InnoDB.
clusterset.status()
Le résultat ressemble à ce qui suit :
{ "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." }
Vous pouvez éventuellement appeler
clusterset.status({extended:1})
pour obtenir d'autres détails sur l'état, y compris des informations sur le cluster.Quittez MySQL Shell.
\q
Déployer un routeur MySQL
Vous pouvez déployer un routeur MySQL pour diriger le trafic des applications clientes vers les clusters appropriés. Le routage est basé sur le port de connexion de l'application qui émet une opération de base de données :
- Les écritures sont acheminées vers l'instance de cluster principale du ClusterSet principal.
- Les lectures peuvent être acheminées vers n'importe quelle instance du cluster principal.
Lorsque vous démarrez un routeur MySQL, il est amorcé lors du déploiement du ClusterSet MySQL InnoDB. Les instances MySQL Router connectées au ClusterSet MySQL InnoDB sont informées des commutations contrôlées ou des basculements d'urgence, et dirigent le trafic vers le nouveau cluster principal.
Pour déployer un routeur MySQL, procédez comme suit :
Dans le terminal Cloud Shell, déployez le routeur MySQL.
kubectl apply -n mysql1 -f c1-router.yaml
Le résultat ressemble à ce qui suit :
configmap/mysql-router-config created service/mysql-router created deployment.apps/mysql-router created
Vérifiez la disponibilité du déploiement MySQL Router.
kubectl -n mysql1 get deployment mysql-router --watch
Lorsque les trois pods sont prêts, la sortie ressemble à ce qui suit :
NAME READY UP-TO-DATE AVAILABLE AGE mysql-router 3/3 3 0 3m36s
Si une erreur
PodUnschedulable
s'affiche dans la console, patientez une à deux minutes pendant que GKE provisionne davantage de nœuds. Actualisez la page.3/3 OK
devrait s'afficher.Démarrez MySQL Shell sur n'importe quel membre du cluster existant.
kubectl -n mysql1 exec -it dbc1-0 -- \ /bin/bash -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
Cette commande se connecte au pod
dbc1-0
, puis démarre un shell connecté à l'instance MySQLdbc1-0
.Vérifiez la configuration du routeur.
clusterset=dba.getClusterSet() clusterset.listRouters()
Le résultat ressemble à ce qui suit :
{ "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::": { ... } } }
Quittez MySQL Shell.
\q
Exécutez ce script pour inspecter l'emplacement des pods MySQL Router.
bash ../scripts/inspect_pod_node.sh mysql1 | sort
Le script montre l'emplacement des nœuds et de la zone cloud de tous les pods de l'espace de noms
mysql1
. Sa sortie est semblable à la suivante :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
Vous pouvez observer que les pods MySQL Router sont répartis équitablement entre les zones. Autrement dit, ils ne sont pas placés sur le même nœud qu'un pod MySQL ou sur le même nœud qu'un autre pod MySQL Router.
Gérer les mises à niveau des clusters MySQL InnoDB et GKE
Les mises à jour de MySQL et de Kubernetes sont publiées régulièrement. Suivez les bonnes pratiques opérationnelles pour mettre régulièrement à jour votre environnement logiciel. Par défaut, GKE gère automatiquement les mises à niveau des clusters et des pools de nœuds. Kubernetes et GKE fournissent également des fonctionnalités supplémentaires pour faciliter les mises à niveau logicielles MySQL.
Planifier les mises à niveau de GKE
Vous pouvez prendre des mesures proactives et définir des configurations pour limiter les risques et faciliter la mise à niveau des clusters lorsque vous exécutez des services avec état, y compris les suivants :
Clusters standards : suivez les bonnes pratiques de GKE pour mettre à niveau les clusters. Choisissez une stratégie de mise à niveau appropriée pour vous assurer que les mises à niveau se produisent pendant l'intervalle de maintenance :
- Choisissez les mises à niveau de la surutilisation si l'optimisation des coûts est importante et si vos charges de travail peuvent tolérer un arrêt progressif en moins de 60 minutes.
- Choisissez des mises à niveau bleu-vert si les charges de travail sont moins tolérantes aux perturbations, et qu'une augmentation temporaire des coûts due à une utilisation plus élevée des ressources est acceptable.
Pour en savoir plus, consultez la page Mettre à niveau un cluster exécutant une charge de travail avec état. Les clusters Autopilot sont automatiquement mis à niveau en fonction de la version disponible sélectionnée.
Utilisez des intervalles de maintenance pour vous assurer que les mises à niveau se produisent lorsque vous le souhaitez. Avant l'intervalle de maintenance, assurez-vous que les sauvegardes de votre base de données ont abouti.
Avant d'autoriser le trafic vers les nœuds MySQL mis à niveau, utilisez les vérifications d'aptitude et d'activité pour vous assurer qu'ils sont prêts à recevoir le trafic.
Créez des vérifications qui évaluent si la réplication est synchronisée avant d'accepter le trafic. Cette opération peut être effectuée via des scripts personnalisés, en fonction de la complexité et de l'échelle de votre base de données.
Définir une règle de budget d'interruption de pod (PBD)
Lorsqu'un cluster MySQL InnoDB est exécuté sur GKE, il doit y avoir un nombre suffisant d'instances en cours d'exécution à tout moment pour répondre au quorum requis.
Dans ce tutoriel, en tenant compte d'un cluster MySQL composé de trois instances, deux instances doivent être disponibles pour former un quorum. Une règle PodDisruptionBudget
vous permet de limiter le nombre de pods pouvant être arrêtés à tout moment. Elle est utile à la fois pour les opérations à état stable de vos services avec état et pour les mises à niveau de clusters.
Pour vous assurer qu'un nombre limité de pods sont interrompus simultanément, vous devez définir le budget d'interruption de pod de votre charge de travail sur maxUnavailable: 1
. Cela garantit qu'un pod au maximum ne s'exécute pas dans l'opération du service à tout moment.
Le fichier manifeste suivant de la règle PodDisruptionBudget
définit le nombre maximal de pods indisponibles sur un pour votre application MySQL.
Pour appliquer la règle PDB à votre cluster, procédez comme suit :
Appliquez la règle PDB à l'aide de
kubectl
.kubectl apply -n mysql1 -f mysql-pdb-maxunavailable.yaml
Affichez l'état du PDB.
kubectl get poddisruptionbudgets -n mysql1 mysql-pdb -o yaml
Dans la section
status
de la sortie, consultez le nombre de podscurrentHealthy
etdesiredHealthy
. Le résultat ressemble à ce qui suit :status: ... currentHealthy: 3 desiredHealthy: 2 disruptionsAllowed: 1 expectedPods: 3 ...
Planifier les mises à niveau du binaire MySQL
Kubernetes et GKE fournissent des fonctionnalités qui facilitent les mises à niveau du binaire MySQL. Toutefois, vous devez effectuer certaines opérations pour préparer les mises à niveau.
Tenez compte des points suivants avant de commencer le processus de mise à niveau :
- Les mises à niveau doivent d'abord être effectuées dans un environnement de test. Pour les systèmes de production, vous devez effectuer des tests supplémentaires dans un environnement de préproduction.
- Pour certaines versions du binaire, vous ne pouvez pas revenir à une version antérieure une fois la mise à niveau effectuée. Prenez le temps nécessaire pour bien comprendre les implications d'une mise à niveau.
- Les sources de réplication peuvent être répliquées sur une version plus récente. Toutefois, il n'est généralement pas possible d'effectuer une copie d'une version plus récente vers une version plus ancienne.
- Vérifiez que vous disposez d'une sauvegarde complète de la base de données avant de déployer la version mise à niveau.
- Tenez compte de la nature éphémère des pods Kubernetes. Tout état de configuration stocké par le pod qui ne se trouve pas sur le volume persistant sera perdu lors du redéploiement du pod.
- Pour les mises à niveau du binaire MySQL, utilisez le même PDB, la même stratégie de mise à jour du pool de nœuds et les mêmes vérifications que celles décrites précédemment.
Dans un environnement de production, vous devez suivre les bonnes pratiques suivantes :
- Créez une image de conteneur avec la nouvelle version de MySQL.
- Conservez les instructions de création d'images dans un dépôt de contrôle de source.
- Utilisez un pipeline automatisé de compilation et de test d'images, tel que Cloud Build, et stockez le binaire d'images dans un registre d'images tel qu'Artifact Registry.
Pour simplifier ce tutoriel, vous n'allez pas créer ni conserver d'image de conteneur, mais utiliser les images publiques MySQL.
Déployer le binaire MySQL mis à niveau
Pour effectuer la mise à niveau du binaire MySQL, vous devez exécuter une commande déclarative qui modifie la version de l'image de la ressource StatefulSet. GKE effectue les étapes nécessaires pour arrêter le pod actuel, déployer un nouveau pod avec le binaire mis à niveau et associer le disque persistant au nouveau pod.
Vérifiez que le budget d'interruption de pod a été créé.
kubectl get poddisruptionbudgets -n mysql1
Obtenez la liste des ensembles avec état.
kubectl get statefulsets -n mysql1
Obtenez la liste des pods en cours d'exécution à l'aide de l'étiquette
app
.kubectl get pods --selector=app=mysql -n mysql1
Mettez à jour l'image MySQL dans l'ensemble avec état.
kubectl -n mysql1 \ set image statefulset/dbc1 \ mysql=mysql/mysql-server:8.0.30
Le résultat ressemble à ce qui suit :
statefulset.apps/mysql image updated
Vérifiez l'état des pods arrêtés et des nouveaux pods.
kubectl get pods --selector=app=mysql -n mysql1
Valider la mise à niveau du binaire MySQL
Pendant la mise à niveau, vous pouvez vérifier l'état du déploiement, des nouveaux pods et du service existant.
Confirmez la mise à niveau en exécutant la commande
rollout status
.kubectl rollout status statefulset/dbc1 -n mysql1
Le résultat ressemble à ce qui suit :
partitioned roll out complete: 3 new pods have been updated...
Confirmez la version de l'image en inspectant l'ensemble avec état.
kubectl get statefulsets -o wide -n mysql1
Le résultat ressemble à ce qui suit :
NAME READY AGE CONTAINERS IMAGES dbc1 3/3 37m mysql mysql/mysql-server:8.0.30
Vérifiez l'état du 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\")"'
Pour chaque instance de cluster, recherchez les valeurs d'état et de version dans la sortie. Le résultat ressemble à ce qui suit :
... "status": "ONLINE", "version": "8.0.30" ...
Effectuer un rollback pour le dernier déploiement de l'application
Lorsque vous annulez le déploiement d'une version binaire mise à niveau, le processus de déploiement est annulé et un nouvel ensemble de pods est déployé avec la version d'image précédente.
Pour rétablir le déploiement à la version de travail précédente, exécutez la commande rollout undo
:
kubectl rollout undo statefulset/dbc1 -n mysql1
Le résultat ressemble à ce qui suit :
statefulset.apps/dbc1 rolled back
Procéder au scaling horizontal de votre cluster de base de données
Pour procéder au scaling horizontal de votre cluster MySQL InnoDB, vous devez ajouter des nœuds supplémentaires au pool de nœuds du cluster GKE (uniquement si vous utilisez un cluster standard), déployer d'autres instances MySQL, puis ajouter chaque instance au cluster MySQL InnoDB existant.
Ajouter des nœuds à votre cluster standard
Cette opération n'est pas nécessaire si vous utilisez un cluster Autopilot.
Pour ajouter des nœuds à votre cluster standard, suivez les instructions ci-dessous pour Cloud Shell ou la console Google Cloud. Pour connaître la procédure détaillée, consultez la section Redimensionner un pool de nœuds.
gcloud
Dans Cloud Shell, redimensionnez le pool de nœuds par défaut en définissant huit instances dans chaque groupe d'instances géré.
gcloud container clusters resize ${CLUSTER_NAME} \
--node-pool default-pool \
--num-nodes=8
Console
Pour ajouter des nœuds à votre cluster standard, procédez comme suit :
- Ouvrez la page du cluster
gkemulti-west1
dans la console Google Cloud. - Sélectionnez Nœuds, puis cliquez sur le pool par défaut.
- Faites défiler la page jusqu'à Groupes d'instances.
- Pour chaque groupe d'instances, redimensionnez la valeur
Number of nodes
de 5 à 8 nœuds.
Ajouter des pods MySQL au cluster principal
Pour déployer des pods MySQL supplémentaires afin d'effectuer le scaling horizontal de votre cluster, procédez comme suit :
Dans Cloud Shell, passez le nombre d'instances répliquées du déploiement MySQL de trois à cinq.
kubectl scale -n mysql1 --replicas=5 -f c1-mysql.yaml
Vérifiez l'avancement du déploiement.
kubectl -n mysql1 get pods --selector=app=mysql -o wide
Pour déterminer si les pods sont prêts, utilisez l'option
--watch
pour surveiller le déploiement. Si vous utilisez des clusters Autopilot et que des erreursPod Unschedulable
s'affichent, cela peut indiquer que GKE provisionne des nœuds pour accueillir les pods supplémentaires.Configurez les paramètres de réplication de groupe pour les nouvelles instances MySQL à ajouter au cluster.
bash ../scripts/c1-clustersetup.sh 3 4
Le script envoie les commandes aux instances exécutées sur les pods avec les ordinaux 3 à 4.
Ouvrez MySQL Shell.
kubectl -n mysql1 \ exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh \ --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
Configurez les deux nouvelles instances 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")});
Les commandes vérifient si l'instance est correctement configurée pour utiliser le cluster MySQL InnoDB et effectuent les modifications de configuration nécessaires.
Ajoutez l'une des nouvelles instances au cluster principal.
cluster = dba.getCluster() cluster.addInstance('icadmin@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Ajoutez une deuxième instance au cluster principal.
cluster.addInstance('icadmin@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Obtenez l'état du ClusterSet, qui inclut également l'état du cluster.
clusterset = dba.getClusterSet() clusterset.status({extended: 1})
Le résultat ressemble à ce qui suit :
"domainName": "clusterset", "globalPrimaryInstance": "dbc1-0.mysql:3306", "metadataServer": "dbc1-0.mysql:3306", "primaryCluster": "mycluster", "status": "HEALTHY", "statusText": "All Clusters available."
Quittez MySQL Shell.
\q
Effectuer un nettoyage
Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.
Supprimer le projet
Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Étapes suivantes
- Découvrez comment l'intégration MySQL de Google Cloud Observability collecte les métriques de performances associées à InnoDB.
- Découvrez la sauvegarde pour GKE, un service de sauvegarde et de restauration des charges de travail dans GKE.
- Découvrez les Volumes persistants plus en détail.