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 de Google Cloudsuivants :
Vous pouvez obtenir 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, supprimez les ressources que vous avez créées pour éviter que des frais vous soient facturés. 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.
Roles required to create a project
To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles. -
Verify that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. -
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
Roles required to create a project
To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles. -
Verify that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. -
Make sure that you have the following role or roles on the project: role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin
Check for the roles
-
In the Google Cloud console, go to the IAM page.
Go to IAM - Select the project.
-
In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.
Grant the roles
-
In the Google Cloud console, go to the IAM page.
Accéder à IAM - Sélectionnez le projet.
- Cliquez sur Accorder l'accès.
-
Dans le champ Nouveaux comptes principaux, saisissez votre identifiant utilisateur. Il s'agit généralement de l'adresse e-mail d'un compte Google.
- Dans la liste Sélectionner un rôle, sélectionnez un rôle.
- Pour attribuer des rôles supplémentaires, cliquez sur Ajouter un autre rôle et ajoutez tous les rôles supplémentaires.
- Cliquez sur Enregistrer.
Configurer votre environnement
Dans ce tutoriel, vous utilisez Cloud Shell pour gérer les ressources hébergées surGoogle Cloud. Cloud Shell est préinstallé avec Docker et les CLI
kubectlet 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 CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATIONRemplacez les valeurs suivantes :
- PROJECT_ID : ID de votre projet Google Cloud .
- CONTROL_PLANE_LOCATION : région Compute Engine du plan de contrôle de votre cluster. 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 CONTROL_PLANE_LOCATIONClonez le dépôt de code.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samplesAccédez au répertoire de travail.
cd kubernetes-engine-samples/databases/gke-stateful-mysql/kubernetesCré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 \ --location=$CONTROL_PLANE_LOCATIONObtenez les identifiants du cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --location=$CONTROL_PLANE_LOCATIONDéployez un service dans trois zones. Ce tutoriel utilise un déploiement Kubernetes. Un déploiement est un objet de l'API Kubernetes qui vous permet d'exécuter plusieurs instances dupliquées de pods répartis entre les nœuds d'un cluster.
kubectl apply -f prepare-for-ha.yamlPar défaut, Autopilot provisionne des ressources dans deux zones. Le déploiement défini dans
prepare-for-ha.yamlgarantit que Autopilot provisionne les nœuds dans trois zones de votre cluster en définissantreplicas:3,podAntiAffinityavecrequiredDuringSchedulingIgnoredDuringExecution, ettopologyKey: "topology.kubernetes.io/zone".Vérifiez l'état du déploiement.
kubectl get deployment prepare-three-zone-ha --watchLorsque 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 2m16sExécutez ce script pour vérifier que vos pods ont été déployés dans trois zones.
bash ../scripts/inspect_pod_node.sh defaultChaque ligne de la sortie correspond à un pod et la deuxième colonne indique la zone. 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 \ --location=$CONTROL_PLANE_LOCATION \ --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 \ --location=$CONTROL_PLANE_LOCATION
Déployer des StatefulSets MySQL
Dans cette section, vous allez déployer un StatefulSet MySQL. Un StatefulSet est un contrôleur Kubernetes qui conserve une identité unique et persistante pour chacun de ses pods.
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 mysql1Créez le secret MySQL.
kubectl apply -n mysql1 -f secret.yamlLe 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.yamlCette classe de stockage utilise le type de disque persistant
pd-balancedqui équilibre les performances et les coûts. Le champvolumeBindingModeest 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.yamlCette 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 createdDans 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 --watchLa 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 erreursPodUnscheduleableen 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 73sPour inspecter l'emplacement des pods sur les nœuds du cluster GKE, exécutez le script suivant :
bash ../scripts/inspect_pod_node.sh mysql1 mysqlLa 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-2Les colonnes de la sortie représentent respectivement le nom d'hôte, la zone cloud et le nom du pod.
La règle
topologySpreadConstraintsde 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
podAntiAffinityapplique 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.shLe 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_whitelistau 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-idest 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'instancedbc1-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
createClusterdé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-0en 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.yamlLe résultat ressemble à ce qui suit :
configmap/mysql-router-config created service/mysql-router created deployment.apps/mysql-router createdVérifiez la disponibilité du déploiement MySQL Router.
kubectl -n mysql1 get deployment mysql-router --watchLorsque 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 3m36sSi une erreur
PodUnschedulables'affiche dans la console, patientez une à deux minutes pendant que GKE provisionne davantage de nœuds. Actualisez la page.3/3 OKdevrait 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.
\qExécutez ce script pour inspecter l'emplacement des pods MySQL Router.
bash ../scripts/inspect_pod_node.sh mysql1 | sortLe 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-0Vous 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
PodDisruptionBudgetvous 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
PodDisruptionBudgetdé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.yamlAffichez l'état du PDB.
kubectl get poddisruptionbudgets -n mysql1 mysql-pdb -o yamlDans la section
statusde la sortie, consultez le nombre de podscurrentHealthyetdesiredHealthy. 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 mysql1Obtenez la liste des ensembles avec état.
kubectl get statefulsets -n mysql1Obtenez la liste des pods en cours d'exécution à l'aide de l'étiquette
app.kubectl get pods --selector=app=mysql -n mysql1Mettez à jour l'image MySQL dans l'ensemble avec état.
kubectl -n mysql1 \ set image statefulset/dbc1 \ mysql=mysql/mysql-server:8.0.30Le résultat ressemble à ce qui suit :
statefulset.apps/mysql image updatedVé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 mysql1Le 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 mysql1Le résultat ressemble à ce qui suit :
NAME READY AGE CONTAINERS IMAGES dbc1 3/3 37m mysql mysql/mysql-server:8.0.30Vé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 mysql1Le résultat ressemble à ce qui suit :
statefulset.apps/dbc1 rolled backProcé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 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=8Console
Pour ajouter des nœuds à votre cluster standard, procédez comme suit :
- Ouvrez la page du cluster
gkemulti-west1dans 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 nodesde 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.yamlVérifiez l'avancement du déploiement.
kubectl -n mysql1 get pods --selector=app=mysql -o widePour déterminer si les pods sont prêts, utilisez l'option
--watchpour surveiller le déploiement. Si vous utilisez des clusters Autopilot et que des erreursPod Unschedulables'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 4Le 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.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
É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.
-