5.4. Reprise après sinistre
5.4.1. À propos de la reprise après sinistre
La documentation sur la reprise après sinistre fournit des informations aux administrateurs sur la façon de reprendre après plusieurs situations de sinistre pouvant survenir avec leur cluster OpenShift Container Platform. En tant qu'administrateur, vous devrez peut-être suivre une ou plusieurs des procédures suivantes pour remettre votre cluster en état de fonctionnement.
La reprise après sinistre nécessite la présence d'au moins un hôte de plan de contrôle sain.
- Rétablissement d'un état antérieur de la grappe
Cette solution gère les situations où vous souhaitez restaurer votre cluster à un état antérieur, par exemple, si un administrateur supprime quelque chose de critique. Cela inclut également les situations où vous avez perdu la majorité de vos hôtes du plan de contrôle, ce qui entraîne la perte du quorum etcd et la mise hors ligne du cluster. Tant que vous avez effectué une sauvegarde etcd, vous pouvez suivre cette procédure pour restaurer votre cluster dans un état antérieur.
Le cas échéant, il peut également s'avérer nécessaire de récupérer des certificats de plan de contrôle expirés.
AvertissementLa restauration d'un état antérieur de la grappe est une action destructrice et déstabilisante pour une grappe en cours d'exécution. Cette procédure ne doit être utilisée qu'en dernier recours.
Avant d'effectuer une restauration, voir À propos de la restauration de l'état du cluster pour plus d'informations sur l'impact sur le cluster.
NoteSi la majorité de vos maîtres sont encore disponibles et que vous avez un quorum etcd, suivez la procédure pour remplacer un seul membre etcd en mauvaise santé.
- Récupération des certificats expirés du plan de contrôle
- Cette solution permet de gérer les situations où les certificats du plan de contrôle ont expiré. Par exemple, si vous arrêtez votre cluster avant la première rotation des certificats, qui a lieu 24 heures après l'installation, vos certificats ne seront pas renouvelés et expireront. Vous pouvez suivre cette procédure pour récupérer les certificats de plan de contrôle expirés.
5.4.2. Rétablissement d'un état antérieur de la grappe
Pour restaurer le cluster à un état antérieur, vous devez avoir préalablement sauvegardé les données etcd en créant un snapshot. Vous utiliserez cet instantané pour restaurer l'état du cluster.
5.4.2.1. À propos de la restauration de l'état des clusters
Vous pouvez utiliser une sauvegarde etcd pour restaurer votre cluster à un état antérieur. Cela peut être utilisé pour récupérer les situations suivantes :
- Le cluster a perdu la majorité des hôtes du plan de contrôle (perte de quorum).
- Un administrateur a supprimé un élément critique et doit restaurer le cluster.
La restauration d'un état antérieur de la grappe est une action destructrice et déstabilisante pour une grappe en cours d'exécution. Elle ne doit être utilisée qu'en dernier recours.
Si vous êtes en mesure de récupérer des données à l'aide du serveur API Kubernetes, alors etcd est disponible et vous ne devez pas restaurer à l'aide d'une sauvegarde etcd.
La restauration d'etcd ramène effectivement un cluster dans le temps et tous les clients connaîtront un historique parallèle et conflictuel. Cela peut avoir un impact sur le comportement des composants de surveillance tels que les kubelets, les gestionnaires de contrôleurs Kubernetes, les contrôleurs SDN et les contrôleurs de volumes persistants.
Les opérateurs du serveur API Kubernetes, du gestionnaire de contrôleur Kubernetes, du planificateur Kubernetes et de etcd peuvent se retrouver bloqués lorsque les fichiers sur le disque sont en conflit avec le contenu de etcd. Cela peut nécessiter des actions manuelles pour résoudre les problèmes.
Dans les cas extrêmes, le cluster peut perdre la trace des volumes persistants, supprimer des charges de travail critiques qui n'existent plus, réimager des machines et réécrire des bundles d'autorité de certification avec des certificats expirés.
5.4.2.2. Rétablissement d'un état antérieur de la grappe
Vous pouvez utiliser une sauvegarde etcd enregistrée pour restaurer un état antérieur du cluster ou restaurer un cluster qui a perdu la majorité des hôtes du plan de contrôle.
Si votre cluster utilise un jeu de machines de plan de contrôle, voir "Dépannage du jeu de machines de plan de contrôle" pour une procédure de récupération etcd plus simple.
Lorsque vous restaurez votre cluster, vous devez utiliser une sauvegarde etcd provenant de la même version de z-stream. Par exemple, un cluster OpenShift Container Platform 4.7.2 doit utiliser une sauvegarde etcd provenant de la version 4.7.2.
Conditions préalables
-
Accès au cluster en tant qu'utilisateur ayant le rôle
cluster-admin
. - Un hôte de plan de contrôle sain à utiliser comme hôte de reprise.
- Accès SSH aux hôtes du plan de contrôle.
-
Un répertoire de sauvegarde contenant à la fois l'instantané etcd et les ressources pour les pods statiques, qui proviennent de la même sauvegarde. Les noms de fichiers dans le répertoire doivent être dans les formats suivants :
snapshot_<datetimestamp>.db
etstatic_kuberesources_<datetimestamp>.tar.gz
.
Pour les nœuds de plan de contrôle sans récupération, il n'est pas nécessaire d'établir une connectivité SSH ou d'arrêter les pods statiques. Vous pouvez supprimer et recréer d'autres machines de plan de contrôle sans récupération, une par une.
Procédure
- Sélectionnez un hôte du plan de contrôle à utiliser comme hôte de restauration. Il s'agit de l'hôte sur lequel vous exécuterez l'opération de restauration.
Établir une connectivité SSH avec chacun des nœuds du plan de contrôle, y compris l'hôte de reprise.
Le serveur API Kubernetes devient inaccessible après le démarrage du processus de restauration, de sorte que vous ne pouvez pas accéder aux nœuds du plan de contrôle. Pour cette raison, il est recommandé d'établir une connectivité SSH à chaque hôte du plan de contrôle dans un terminal séparé.
ImportantSi vous n'effectuez pas cette étape, vous ne pourrez pas accéder aux hôtes du plan de contrôle pour terminer la procédure de restauration, et vous ne pourrez pas récupérer votre cluster à partir de cet état.
Copiez le répertoire de sauvegarde etcd sur l'hôte du plan de contrôle de reprise.
Cette procédure suppose que vous avez copié le répertoire
backup
contenant le snapshot etcd et les ressources pour les pods statiques dans le répertoire/home/core/
de votre hôte de plan de contrôle de récupération.Arrêtez les pods statiques sur tous les autres nœuds du plan de contrôle.
NoteIl n'est pas nécessaire d'arrêter manuellement les pods sur l'hôte de récupération. Le script de récupération arrêtera les pods sur l'hôte de récupération.
- Accéder à un hôte du plan de contrôle qui n'est pas l'hôte de reprise.
Déplacer le fichier pod etcd existant hors du répertoire kubelet manifest :
$ sudo mv /etc/kubernetes/manifests/etcd-pod.yaml /tmp
Vérifiez que les pods etcd sont arrêtés.
$ sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"
La sortie de cette commande doit être vide. Si ce n'est pas le cas, attendez quelques minutes et vérifiez à nouveau.
Déplacez le fichier pod du serveur API Kubernetes existant hors du répertoire kubelet manifest :
$ sudo mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
Vérifiez que les pods du serveur API Kubernetes sont arrêtés.
$ sudo crictl ps | grep kube-apiserver | egrep -v "operator|guard"
La sortie de cette commande doit être vide. Si ce n'est pas le cas, attendez quelques minutes et vérifiez à nouveau.
Déplacez le répertoire de données etcd vers un autre emplacement :
$ sudo mv /var/lib/etcd/ /tmp
- Répétez cette étape sur chacun des autres hôtes du plan de contrôle qui n'est pas l'hôte de reprise.
- Accéder à l'hôte du plan de contrôle de récupération.
Si le proxy à l'échelle du cluster est activé, assurez-vous que vous avez exporté les variables d'environnement
NO_PROXY
,HTTP_PROXY
, etHTTPS_PROXY
.AstuceVous pouvez vérifier si le proxy est activé en examinant la sortie de
oc get proxy cluster -o yaml
. Le proxy est activé si les champshttpProxy
,httpsProxy
etnoProxy
ont des valeurs définies.Exécutez le script de restauration sur l'hôte du plan de contrôle de récupération et indiquez le chemin d'accès au répertoire de sauvegarde etcd :
$ sudo -E /usr/local/bin/cluster-restore.sh /home/core/backup
Exemple de sortie de script
...stopping kube-scheduler-pod.yaml ...stopping kube-controller-manager-pod.yaml ...stopping etcd-pod.yaml ...stopping kube-apiserver-pod.yaml Waiting for container etcd to stop .complete Waiting for container etcdctl to stop .............................complete Waiting for container etcd-metrics to stop complete Waiting for container kube-controller-manager to stop complete Waiting for container kube-apiserver to stop ..........................................................................................complete Waiting for container kube-scheduler to stop complete Moving etcd data-dir /var/lib/etcd/member to /var/lib/etcd-backup starting restore-etcd static pod starting kube-apiserver-pod.yaml static-pod-resources/kube-apiserver-pod-7/kube-apiserver-pod.yaml starting kube-controller-manager-pod.yaml static-pod-resources/kube-controller-manager-pod-7/kube-controller-manager-pod.yaml starting kube-scheduler-pod.yaml static-pod-resources/kube-scheduler-pod-8/kube-scheduler-pod.yaml
NoteLe processus de restauration peut entraîner l'entrée des nœuds dans l'état
NotReady
si les certificats des nœuds ont été mis à jour après la dernière sauvegarde etcd.Vérifiez que les nœuds sont dans l'état
Ready
.Exécutez la commande suivante :
$ oc get nodes -w
Exemple de sortie
NAME STATUS ROLES AGE VERSION host-172-25-75-28 Ready master 3d20h v1.25.0 host-172-25-75-38 Ready infra,worker 3d20h v1.25.0 host-172-25-75-40 Ready master 3d20h v1.25.0 host-172-25-75-65 Ready master 3d20h v1.25.0 host-172-25-75-74 Ready infra,worker 3d20h v1.25.0 host-172-25-75-79 Ready worker 3d20h v1.25.0 host-172-25-75-86 Ready worker 3d20h v1.25.0 host-172-25-75-98 Ready infra,worker 3d20h v1.25.0
Il peut s'écouler plusieurs minutes avant que tous les nœuds ne communiquent leur état.
Si des nœuds sont dans l'état
NotReady
, connectez-vous aux nœuds et supprimez tous les fichiers PEM du répertoire/var/lib/kubelet/pki
sur chaque nœud. Vous pouvez vous connecter aux nœuds par SSH ou utiliser la fenêtre de terminal de la console web.$ ssh -i <ssh-key-path> core@<master-hostname>
Exemple de répertoire
pki
sh-4.4# pwd /var/lib/kubelet/pki sh-4.4# ls kubelet-client-2022-04-28-11-24-09.pem kubelet-server-2022-04-28-11-24-15.pem kubelet-client-current.pem kubelet-server-current.pem
Redémarrer le service kubelet sur tous les hôtes du plan de contrôle.
À partir de l'hôte de récupération, exécutez la commande suivante :
$ sudo systemctl restart kubelet.service
- Répétez cette étape sur tous les autres hôtes du plan de contrôle.
Approuver les RSC en attente :
Obtenir la liste des CSR actuels :
$ oc get csr
Exemple de sortie
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-2s94x 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending 1 csr-4bd6t 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending 2 csr-4hl85 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending 3 csr-zhhhp 3m8s kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending 4 ...
Examinez les détails d'un CSR pour vérifier qu'il est valide :
oc describe csr <csr_name> 1
- 1
<csr_name>
est le nom d'un CSR figurant dans la liste des CSR actuels.
Approuver chaque CSR
node-bootstrapper
valide :$ oc adm certificate approve <csr_name>
Pour les installations fournies par l'utilisateur, approuver chaque CSR de service kubelet valide :
$ oc adm certificate approve <csr_name>
Vérifiez que le plan de contrôle à membre unique a bien démarré.
Depuis l'hôte de récupération, vérifiez que le conteneur etcd est en cours d'exécution.
$ sudo crictl ps | grep etcd | grep -v operator
Exemple de sortie
3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0
Depuis l'hôte de récupération, vérifiez que le pod etcd est en cours d'exécution.
$ oc -n openshift-etcd get pods -l k8s-app=etcd
NoteSi vous essayez d'exécuter
oc login
avant d'exécuter cette commande et que vous recevez l'erreur suivante, attendez quelques instants pour que les contrôleurs d'authentification démarrent et réessayez.Unable to connect to the server: EOF
Exemple de sortie
NAME READY STATUS RESTARTS AGE etcd-ip-10-0-143-125.ec2.internal 1/1 Running 1 2m47s
Si l'état est
Pending
, ou si la sortie indique plus d'un pod etcd en cours d'exécution, attendez quelques minutes et vérifiez à nouveau.
NoteN'effectuez l'étape suivante que si vous utilisez le plugin réseau
OVNKubernetes
.Supprimer les objets nœuds associés aux hôtes du plan de contrôle qui ne sont pas l'hôte du plan de contrôle de reprise.
oc delete node <non-recovery-controlplane-host-1> <non-recovery-controlplane-host-2>
Vérifier que le Cluster Network Operator (CNO) redéploie le plan de contrôle OVN-Kubernetes et qu'il ne référence plus les mauvaises adresses IP des contrôleurs. Pour vérifier ce résultat, vérifiez régulièrement la sortie de la commande suivante. Attendez qu'elle renvoie un résultat vide avant de passer à l'étape suivante.
$ oc -n openshift-ovn-kubernetes get ds/ovnkube-master -o yaml | grep -E '<wrong_master_ip_1>|<wrong_master_ip_2>'
NoteCela peut prendre au moins 5 à 10 minutes pour que le plan de contrôle OVN-Kubernetes soit redéployé et que la commande précédente renvoie une sortie vide.
Désactivez la garde du quorum en entrant la commande suivante :
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
Cette commande permet de s'assurer que vous pouvez recréer les secrets et déployer les pods statiques avec succès.
Redémarrez les pods Kubernetes d'Open Virtual Network (OVN) sur tous les hôtes.
NoteLes webhooks de validation et de mutation des admissions peuvent rejeter les pods. Si vous ajoutez d'autres webhooks dont l'adresse
failurePolicy
estFail
, ils peuvent rejeter des pods et le processus de restauration peut échouer. Vous pouvez éviter cela en sauvegardant et en supprimant les webhooks lors de la restauration de l'état de la grappe. Une fois l'état du cluster restauré avec succès, vous pouvez réactiver les webhooks.Vous pouvez également définir temporairement
failurePolicy
surIgnore
pendant la restauration de l'état de la grappe. Une fois l'état de la grappe restauré avec succès, vous pouvez définirfailurePolicy
surFail
.Supprimez la base de données en direction du nord (nbdb) et la base de données en direction du sud (sbdb). Accédez à l'hôte de reprise et aux nœuds de plan de contrôle restants à l'aide de Secure Shell (SSH) et exécutez la commande suivante :
$ sudo rm -f /var/lib/ovn/etc/*.db
Supprimez tous les pods du plan de contrôle OVN-Kubernetes en exécutant la commande suivante :
$ oc delete pods -l app=ovnkube-master -n openshift-ovn-kubernetes
Assurez-vous que tous les pods du plan de contrôle OVN-Kubernetes sont à nouveau déployés et sont dans un état
Running
en exécutant la commande suivante :$ oc get pods -l app=ovnkube-master -n openshift-ovn-kubernetes
Exemple de sortie
NAME READY STATUS RESTARTS AGE ovnkube-master-nb24h 4/4 Running 0 48s ovnkube-master-rm8kw 4/4 Running 0 47s ovnkube-master-zbqnh 4/4 Running 0 56s
Supprimez tous les pods
ovnkube-node
en exécutant la commande suivante :$ oc get pods -n openshift-ovn-kubernetes -o name | grep ovnkube-node | while read p ; do oc delete $p -n openshift-ovn-kubernetes ; done
Assurez-vous que tous les pods
ovnkube-node
sont à nouveau déployés et sont dans un étatRunning
en exécutant la commande suivante :$ oc get pods -n openshift-ovn-kubernetes | grep ovnkube-node
Supprimer et recréer les autres machines du plan de contrôle qui ne sont pas des machines de récupération, une par une. Une fois les machines recréées, une nouvelle révision est forcée et etcd passe automatiquement à l'échelle supérieure.
Si vous utilisez une installation bare metal fournie par l'utilisateur, vous pouvez recréer une machine de plan de contrôle en utilisant la même méthode que celle utilisée pour la créer à l'origine. Pour plus d'informations, voir "Installation d'un cluster fourni par l'utilisateur sur bare metal".
AvertissementNe supprimez pas et ne recréez pas la machine pour l'hôte de récupération.
Si vous utilisez une infrastructure fournie par l'installateur ou si vous avez utilisé l'API Machine pour créer vos machines, procédez comme suit :
AvertissementNe supprimez pas et ne recréez pas la machine pour l'hôte de récupération.
Pour les installations bare metal sur une infrastructure fournie par l'installateur, les machines du plan de contrôle ne sont pas recréées. Pour plus d'informations, voir "Remplacement d'un nœud de plan de contrôle bare-metal".
Obtenir la machine de l'un des hôtes du plan de contrôle perdus.
Dans un terminal ayant accès au cluster en tant qu'utilisateur cluster-admin, exécutez la commande suivante :
$ oc get machines -n openshift-machine-api -o wide
Exemple de sortie :
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-0 Running m4.xlarge us-east-1 us-east-1a 3h37m ip-10-0-131-183.ec2.internal aws:///us-east-1a/i-0ec2782f8287dfb7e stopped 1 clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-143-125.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-154-194.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running
- 1
- Il s'agit de la machine du plan de contrôle de l'hôte du plan de contrôle perdu,
ip-10-0-131-183.ec2.internal
.
Enregistrez la configuration de la machine dans un fichier sur votre système de fichiers :
$ oc get machine clustername-8qw5l-master-0 \ 1 -n openshift-machine-api \ -o yaml \ > new-master-machine.yaml
- 1
- Indiquez le nom de la machine du plan de contrôle pour l'hôte du plan de contrôle perdu.
Modifiez le fichier
new-master-machine.yaml
créé à l'étape précédente pour lui attribuer un nouveau nom et supprimer les champs inutiles.Retirer toute la section
status
:status: addresses: - address: 10.0.131.183 type: InternalIP - address: ip-10-0-131-183.ec2.internal type: InternalDNS - address: ip-10-0-131-183.ec2.internal type: Hostname lastUpdated: "2020-04-20T17:44:29Z" nodeRef: kind: Node name: ip-10-0-131-183.ec2.internal uid: acca4411-af0d-4387-b73e-52b2484295ad phase: Running providerStatus: apiVersion: awsproviderconfig.openshift.io/v1beta1 conditions: - lastProbeTime: "2020-04-20T16:53:50Z" lastTransitionTime: "2020-04-20T16:53:50Z" message: machine successfully created reason: MachineCreationSucceeded status: "True" type: MachineCreation instanceId: i-0fdb85790d76d0c3f instanceState: stopped kind: AWSMachineProviderStatus
Changez le nom du champ
metadata.name
.Il est recommandé de conserver le même nom de base que l'ancienne machine et de remplacer le numéro de fin par le prochain numéro disponible. Dans cet exemple,
clustername-8qw5l-master-0
est remplacé parclustername-8qw5l-master-3
:apiVersion: machine.openshift.io/v1beta1 kind: Machine metadata: ... name: clustername-8qw5l-master-3 ...
Supprimer le champ
spec.providerID
:providerID: aws:///us-east-1a/i-0fdb85790d76d0c3f
Supprimer les champs
metadata.annotations
etmetadata.generation
:annotations: machine.openshift.io/instance-state: running ... generation: 2
Supprimer les champs
metadata.resourceVersion
etmetadata.uid
:resourceVersion: "13291" uid: a282eb70-40a2-4e89-8009-d05dd420d31a
Supprimer la machine de l'hôte du plan de contrôle perdu :
oc delete machine -n openshift-machine-api clustername-8qw5l-master-0 1
- 1
- Indiquez le nom de la machine du plan de contrôle pour l'hôte du plan de contrôle perdu.
Vérifiez que la machine a été supprimée :
$ oc get machines -n openshift-machine-api -o wide
Exemple de sortie :
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-143-125.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-154-194.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running
Créez une machine en utilisant le fichier
new-master-machine.yaml
:$ oc apply -f new-master-machine.yaml
Vérifiez que la nouvelle machine a été créée :
$ oc get machines -n openshift-machine-api -o wide
Exemple de sortie :
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-143-125.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-154-194.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-master-3 Provisioning m4.xlarge us-east-1 us-east-1a 85s ip-10-0-173-171.ec2.internal aws:///us-east-1a/i-015b0888fe17bc2c8 running 1 clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running
- 1
- La nouvelle machine,
clustername-8qw5l-master-3
, est en cours de création et sera prête après le changement de phase deProvisioning
àRunning
.
La création de la nouvelle machine peut prendre quelques minutes. L'opérateur du cluster etcd se synchronisera automatiquement lorsque la machine ou le nœud reviendra à un état sain.
- Répétez ces étapes pour chaque hôte du plan de contrôle perdu qui n'est pas l'hôte de récupération.
Dans une fenêtre de terminal séparée, connectez-vous au cluster en tant qu'utilisateur ayant le rôle
cluster-admin
en entrant la commande suivante :$ oc login -u <cluster_admin> 1
- 1
- Pour
<cluster_admin>
, indiquez un nom d'utilisateur avec le rôlecluster-admin
.
Forcer le redéploiement de etcd.
Dans un terminal ayant accès au cluster en tant qu'utilisateur
cluster-admin
, exécutez la commande suivante :$ oc patch etcd cluster -p='{"spec" : {\i1}"forceRedeploymentReason" : \N-"recovery-'\N"$( date --rfc-3339=ns )'\N'\N"}'' -type=merge} --type=merge 1
- 1
- La valeur
forceRedeploymentReason
doit être unique, c'est pourquoi un horodatage est ajouté.
Lorsque l'opérateur du cluster etcd effectue un redéploiement, les nœuds existants sont démarrés avec de nouveaux pods, comme lors de la mise à l'échelle initiale.
Réactivez la garde du quorum en entrant la commande suivante :
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
Vous pouvez vérifier que la section
unsupportedConfigOverrides
est supprimée de l'objet en entrant cette commande :$ oc get etcd/cluster -oyaml
Vérifier que tous les nœuds sont mis à jour avec la dernière révision.
Dans un terminal ayant accès au cluster en tant qu'utilisateur
cluster-admin
, exécutez la commande suivante :$ oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Examinez la condition d'état
NodeInstallerProgressing
pour etcd afin de vérifier que tous les nœuds sont à la dernière révision. La sortie indiqueAllNodesAtLatestRevision
lorsque la mise à jour est réussie :AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- Dans cet exemple, le dernier numéro de révision est
7
.
Si le résultat comprend plusieurs numéros de révision, tels que
2 nodes are at revision 6; 1 nodes are at revision 7
, cela signifie que la mise à jour est toujours en cours. Attendez quelques minutes et réessayez.Une fois etcd redéployé, forcez de nouveaux déploiements pour le plan de contrôle. Le serveur API Kubernetes se réinstallera sur les autres nœuds car le kubelet est connecté aux serveurs API à l'aide d'un équilibreur de charge interne.
Dans un terminal ayant accès au cluster en tant qu'utilisateur
cluster-admin
, exécutez les commandes suivantes.Forcer un nouveau déploiement pour le serveur API Kubernetes :
$ oc patch kubeapiserver cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
Vérifier que tous les nœuds sont mis à jour avec la dernière révision.
$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Examinez l'état de
NodeInstallerProgressing
pour vérifier que tous les nœuds sont à la dernière révision. La sortie indiqueAllNodesAtLatestRevision
lorsque la mise à jour est réussie :AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- Dans cet exemple, le dernier numéro de révision est
7
.
Si le résultat comprend plusieurs numéros de révision, tels que
2 nodes are at revision 6; 1 nodes are at revision 7
, cela signifie que la mise à jour est toujours en cours. Attendez quelques minutes et réessayez.Forcer un nouveau déploiement pour le gestionnaire de contrôleur Kubernetes :
$ oc patch kubecontrollermanager cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
Vérifier que tous les nœuds sont mis à jour avec la dernière révision.
$ oc get kubecontrollermanager -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Examinez l'état de
NodeInstallerProgressing
pour vérifier que tous les nœuds sont à la dernière révision. La sortie indiqueAllNodesAtLatestRevision
lorsque la mise à jour est réussie :AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- Dans cet exemple, le dernier numéro de révision est
7
.
Si le résultat comprend plusieurs numéros de révision, tels que
2 nodes are at revision 6; 1 nodes are at revision 7
, cela signifie que la mise à jour est toujours en cours. Attendez quelques minutes et réessayez.Forcer un nouveau déploiement pour le planificateur Kubernetes :
$ oc patch kubescheduler cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
Vérifier que tous les nœuds sont mis à jour avec la dernière révision.
$ oc get kubescheduler -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Examinez l'état de
NodeInstallerProgressing
pour vérifier que tous les nœuds sont à la dernière révision. La sortie indiqueAllNodesAtLatestRevision
lorsque la mise à jour est réussie :AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- Dans cet exemple, le dernier numéro de révision est
7
.
Si le résultat comprend plusieurs numéros de révision, tels que
2 nodes are at revision 6; 1 nodes are at revision 7
, cela signifie que la mise à jour est toujours en cours. Attendez quelques minutes et réessayez.
Vérifiez que tous les hôtes du plan de contrôle ont démarré et rejoint le cluster.
Dans un terminal ayant accès au cluster en tant qu'utilisateur
cluster-admin
, exécutez la commande suivante :$ oc -n openshift-etcd get pods -l k8s-app=etcd
Exemple de sortie
etcd-ip-10-0-143-125.ec2.internal 2/2 Running 0 9h etcd-ip-10-0-154-194.ec2.internal 2/2 Running 0 9h etcd-ip-10-0-173-171.ec2.internal 2/2 Running 0 9h
Pour s'assurer que toutes les charges de travail reviennent à un fonctionnement normal à la suite d'une procédure de récupération, redémarrez chaque pod qui stocke les informations de l'API Kubernetes. Cela inclut les composants d'OpenShift Container Platform tels que les routeurs, les opérateurs et les composants tiers.
Notez que la restauration de tous les services peut prendre plusieurs minutes après l'exécution de cette procédure. Par exemple, l'authentification à l'aide de oc login
peut ne pas fonctionner immédiatement jusqu'à ce que les pods du serveur OAuth soient redémarrés.
5.4.2.3. Ressources complémentaires
5.4.2.4. Problèmes et solutions de contournement pour la restauration d'un état de stockage persistant
Si votre cluster OpenShift Container Platform utilise un stockage persistant sous quelque forme que ce soit, un état du cluster est généralement stocké en dehors d'etcd. Il peut s'agir d'un cluster Elasticsearch fonctionnant dans un pod ou d'une base de données fonctionnant dans un objet StatefulSet
. Lorsque vous restaurez à partir d'une sauvegarde etcd, l'état des charges de travail dans OpenShift Container Platform est également restauré. Cependant, si le snapshot etcd est ancien, l'état peut être invalide ou obsolète.
Le contenu des volumes persistants (PV) ne fait jamais partie de l'instantané etcd. Lorsque vous restaurez un cluster OpenShift Container Platform à partir d'un instantané etcd, les charges de travail non critiques peuvent avoir accès aux données critiques, et vice-versa.
Voici quelques exemples de scénarios qui produisent un état périmé :
- La base de données MySQL s'exécute dans un pod sauvegardé par un objet PV. La restauration d'OpenShift Container Platform à partir d'un snapshot etcd ne rétablit pas le volume sur le fournisseur de stockage et ne produit pas de pod MySQL en cours d'exécution, malgré les tentatives répétées de démarrage du pod. Vous devez restaurer manuellement ce pod en restaurant le volume sur le fournisseur de stockage, puis en modifiant le PV pour qu'il pointe vers le nouveau volume.
- Le pod P1 utilise le volume A, qui est attaché au nœud X. Si l'instantané etcd est pris alors qu'un autre pod utilise le même volume sur le nœud Y, alors lorsque la restauration etcd est effectuée, le pod P1 pourrait ne pas être en mesure de démarrer correctement en raison du fait que le volume est toujours attaché au nœud Y. OpenShift Container Platform n'est pas conscient de l'attachement et ne le détache pas automatiquement. Lorsque cela se produit, le volume doit être détaché manuellement du nœud Y afin que le volume puisse s'attacher au nœud X, puis le pod P1 peut démarrer.
- Les informations d'identification du fournisseur de cloud ou du fournisseur de stockage ont été mises à jour après que l'instantané etcd a été pris. Par conséquent, les pilotes ou opérateurs CSI qui dépendent de ces informations d'identification ne fonctionnent pas. Il se peut que vous deviez mettre à jour manuellement les informations d'identification requises par ces pilotes ou opérateurs.
Un périphérique est supprimé ou renommé à partir des nœuds OpenShift Container Platform après que l'instantané etcd a été pris. L'opérateur de stockage local crée des liens symboliques pour chaque PV qu'il gère à partir des répertoires
/dev/disk/by-id
ou/dev
. Cette situation peut amener les PV locaux à faire référence à des périphériques qui n'existent plus.Pour résoudre ce problème, l'administrateur doit
- Supprimer manuellement les PV dont les dispositifs ne sont pas valides.
- Supprimer les liens symboliques des nœuds respectifs.
-
Supprimer les objets
LocalVolume
ouLocalVolumeSet
(voir StorageConfiguring persistent storage Persistent storage using local volumes Deleting the Local Storage Operator Resources).
5.4.3. Récupération des certificats expirés du plan de contrôle
5.4.3.1. Récupération des certificats expirés du plan de contrôle
Le cluster peut récupérer automatiquement les certificats du plan de contrôle qui ont expiré.
Cependant, vous devez approuver manuellement les demandes de signature de certificat (CSR) en attente sur node-bootstrapper
pour récupérer les certificats des kubelets. Pour les installations fournies par l'utilisateur, il se peut que vous deviez également approuver les CSR de service des kubelets en attente.
Procédez comme suit pour approuver les CSR en attente :
Procédure
Obtenir la liste des CSR actuels :
$ oc get csr
Exemple de sortie
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-2s94x 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending 1 csr-4bd6t 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending 2 csr-4hl85 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending 3 csr-zhhhp 3m8s kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending 4 ...
Examinez les détails d'un CSR pour vérifier qu'il est valide :
oc describe csr <csr_name> 1
- 1
<csr_name>
est le nom d'un CSR figurant dans la liste des CSR actuels.
Approuver chaque CSR
node-bootstrapper
valide :$ oc adm certificate approve <csr_name>
Pour les installations fournies par l'utilisateur, approuver chaque kubelet valide servant de CSR :
$ oc adm certificate approve <csr_name>
5.4.4. Reprise après sinistre pour un cluster hébergé dans une région AWS
Si vous avez besoin d'une reprise après sinistre (DR) pour un cluster hébergé, vous pouvez récupérer un cluster hébergé dans la même région au sein d'AWS. Par exemple, vous avez besoin d'une reprise après sinistre lorsque la mise à niveau d'un cluster de gestion échoue et que le cluster hébergé est en lecture seule.
Les plans de contrôle hébergés sont une fonctionnalité d'aperçu technologique uniquement. Les fonctionnalités de l'aperçu technologique ne sont pas prises en charge par les accords de niveau de service (SLA) de production de Red Hat et peuvent ne pas être complètes sur le plan fonctionnel. Red Hat ne recommande pas de les utiliser en production. Ces fonctionnalités offrent un accès anticipé aux fonctionnalités des produits à venir, ce qui permet aux clients de tester les fonctionnalités et de fournir un retour d'information pendant le processus de développement.
Pour plus d'informations sur la portée de l'assistance des fonctionnalités de l'aperçu technologique de Red Hat, voir Portée de l'assistance des fonctionnalités de l'aperçu technologique.
Le processus de DR comporte trois étapes principales :
- Sauvegarde du cluster hébergé sur le cluster de gestion source
- Restauration du cluster hébergé sur un cluster de gestion de destination
- Suppression du cluster hébergé du cluster de gestion source
Vos charges de travail restent en cours d'exécution pendant le processus. L'API du cluster peut être indisponible pendant un certain temps, mais cela n'affectera pas les services exécutés sur les nœuds de travail.
Le cluster de gestion source et le cluster de gestion de destination doivent avoir les drapeaux --external-dns
pour gérer l'URL du serveur API, comme indiqué dans cet exemple :
Exemple : Drapeaux DNS externes
--external-dns-provider=aws \ --external-dns-credentials=<AWS Credentials location> \ --external-dns-domain-filter=<DNS Base Domain>
Ainsi, l'URL du serveur se termine par https://api-sample-hosted.sample-hosted.aws.openshift.com
.
Si vous n'incluez pas les drapeaux --external-dns
pour maintenir l'URL du serveur API, le cluster hébergé ne peut pas être migré.
5.4.4.1. Exemple d'environnement et de contexte
Considérons un scénario dans lequel vous avez trois clusters à restaurer. Deux sont des clusters de gestion et un est un cluster hébergé. Vous pouvez restaurer soit le plan de contrôle uniquement, soit le plan de contrôle et les nœuds. Avant de commencer, vous avez besoin des informations suivantes :
- Espace de noms Source MGMT : L'espace de noms de la gestion de la source
- Source MGMT ClusterName : Le nom du cluster de gestion source
-
Source MGMT Kubeconfig : Le fichier de gestion des sources
kubeconfig
-
Destination MGMT Kubeconfig : Le fichier de gestion de destination
kubeconfig
-
HC Kubeconfig : Le fichier du cluster hébergé
kubeconfig
- Fichier de clé SSH : La clé publique SSH
- Secret d'extraction : le fichier secret d'extraction pour accéder aux images de la version
- Références AWS
- Région AWS
- Domaine de base : Le domaine de base DNS à utiliser comme domaine DNS externe
- Nom du seau S3 : Le seau dans la région AWS où vous prévoyez de télécharger la sauvegarde etcd
Ces informations sont présentées dans l'exemple suivant de variables d'environnement.
Exemple de variables d'environnement
SSH_KEY_FILE=${HOME}/.ssh/id_rsa.pub BASE_PATH=${HOME}/hypershift BASE_DOMAIN="aws.sample.com" PULL_SECRET_FILE="${HOME}/pull_secret.json" AWS_CREDS="${HOME}/.aws/credentials" AWS_ZONE_ID="Z02718293M33QHDEQBROL" CONTROL_PLANE_AVAILABILITY_POLICY=SingleReplica HYPERSHIFT_PATH=${BASE_PATH}/src/hypershift HYPERSHIFT_CLI=${HYPERSHIFT_PATH}/bin/hypershift HYPERSHIFT_IMAGE=${HYPERSHIFT_IMAGE:-"quay.io/${USER}/hypershift:latest"} NODE_POOL_REPLICAS=${NODE_POOL_REPLICAS:-2} # MGMT Context MGMT_REGION=us-west-1 MGMT_CLUSTER_NAME="${USER}-dev" MGMT_CLUSTER_NS=${USER} MGMT_CLUSTER_DIR="${BASE_PATH}/hosted_clusters/${MGMT_CLUSTER_NS}-${MGMT_CLUSTER_NAME}" MGMT_KUBECONFIG="${MGMT_CLUSTER_DIR}/kubeconfig" # MGMT2 Context MGMT2_CLUSTER_NAME="${USER}-dest" MGMT2_CLUSTER_NS=${USER} MGMT2_CLUSTER_DIR="${BASE_PATH}/hosted_clusters/${MGMT2_CLUSTER_NS}-${MGMT2_CLUSTER_NAME}" MGMT2_KUBECONFIG="${MGMT2_CLUSTER_DIR}/kubeconfig" # Hosted Cluster Context HC_CLUSTER_NS=clusters HC_REGION=us-west-1 HC_CLUSTER_NAME="${USER}-hosted" HC_CLUSTER_DIR="${BASE_PATH}/hosted_clusters/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}" HC_KUBECONFIG="${HC_CLUSTER_DIR}/kubeconfig" BACKUP_DIR=${HC_CLUSTER_DIR}/backup BUCKET_NAME="${USER}-hosted-${MGMT_REGION}" # DNS AWS_ZONE_ID="Z07342811SH9AA102K1AC" EXTERNAL_DNS_DOMAIN="hc.jpdv.aws.kerbeross.com"
5.4.4.2. Vue d'ensemble du processus de sauvegarde et de restauration
Le processus de sauvegarde et de restauration fonctionne comme suit :
Sur le cluster de gestion 1, que vous pouvez considérer comme le cluster de gestion source, le plan de contrôle et les travailleurs interagissent en utilisant l'API DNS externe. L'API DNS externe est accessible et un équilibreur de charge se trouve entre les clusters de gestion.
Vous prenez un instantané du cluster hébergé, qui comprend etcd, le plan de contrôle et les nœuds de travail. Au cours de ce processus, les nœuds de travail continuent d'essayer d'accéder à l'API DNS externe même si elle n'est pas accessible, les charges de travail sont en cours d'exécution, le plan de contrôle est sauvegardé dans un fichier manifeste local et etcd est sauvegardé dans un seau S3. Le plan de données est actif et le plan de contrôle est en pause.
Sur le cluster de gestion 2, que vous pouvez considérer comme le cluster de gestion de destination, vous restaurez etcd à partir du seau S3 et restaurez le plan de contrôle à partir du fichier manifeste local. Au cours de ce processus, l'API DNS externe est arrêtée, l'API du cluster hébergé devient inaccessible et tous les travailleurs qui utilisent l'API sont incapables de mettre à jour leurs fichiers manifestes, mais les charges de travail sont toujours en cours d'exécution.
L'API DNS externe est à nouveau accessible et les nœuds de travail l'utilisent pour passer au cluster de gestion 2. L'API DNS externe peut accéder à l'équilibreur de charge qui pointe vers le plan de contrôle.
Sur le cluster de gestion 2, le plan de contrôle et les nœuds de travail interagissent en utilisant l'API DNS externe. Les ressources sont supprimées du cluster de gestion 1, à l'exception de la sauvegarde S3 de etcd. Si vous essayez de configurer à nouveau le cluster hébergé sur le cluster de gestion 1, cela ne fonctionnera pas.
Vous pouvez sauvegarder et restaurer manuellement votre cluster hébergé ou exécuter un script pour terminer le processus. Pour plus d'informations sur le script, voir "Exécution d'un script pour sauvegarder et restaurer un cluster hébergé".
5.4.4.3. Sauvegarde d'un cluster hébergé
Pour récupérer votre cluster hébergé dans votre cluster de gestion cible, vous devez d'abord sauvegarder toutes les données pertinentes.
Procédure
Créez un fichier configmap pour déclarer le cluster de gestion des sources en entrant cette commande :
$ oc create configmap mgmt-parent-cluster -n default --from-literal=from=${MGMT_CLUSTER_NAME}
Arrêtez la réconciliation dans le cluster hébergé et dans les pools de nœuds en entrant ces commandes :
PAUSED_UNTIL="true" oc patch -n ${HC_CLUSTER_NS} hostedclusters/${HC_CLUSTER_NAME} -p '{"spec":{"pausedUntil":"'${PAUSED_UNTIL}'"}}' --type=merge oc scale deployment -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --replicas=0 kube-apiserver openshift-apiserver openshift-oauth-apiserver control-plane-operator
PAUSED_UNTIL="true" oc patch -n ${HC_CLUSTER_NS} hostedclusters/${HC_CLUSTER_NAME} -p '{"spec":{"pausedUntil":"'${PAUSED_UNTIL}'"}}' --type=merge oc patch -n ${HC_CLUSTER_NS} nodepools/${NODEPOOLS} -p '{"spec":{"pausedUntil":"'${PAUSED_UNTIL}'"}}' --type=merge oc scale deployment -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --replicas=0 kube-apiserver openshift-apiserver openshift-oauth-apiserver control-plane-operator
Sauvegardez etcd et téléchargez les données vers un panier S3 en exécutant ce script bash :
AstuceEnveloppez ce script dans une fonction et appelez-le à partir de la fonction principale.
# ETCD Backup ETCD_PODS="etcd-0" if [ "${CONTROL_PLANE_AVAILABILITY_POLICY}" = "HighlyAvailable" ]; then ETCD_PODS="etcd-0 etcd-1 etcd-2" fi for POD in ${ETCD_PODS}; do # Create an etcd snapshot oc exec -it ${POD} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -- env ETCDCTL_API=3 /usr/bin/etcdctl --cacert /etc/etcd/tls/client/etcd-client-ca.crt --cert /etc/etcd/tls/client/etcd-client.crt --key /etc/etcd/tls/client/etcd-client.key --endpoints=localhost:2379 snapshot save /var/lib/data/snapshot.db oc exec -it ${POD} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -- env ETCDCTL_API=3 /usr/bin/etcdctl -w table snapshot status /var/lib/data/snapshot.db FILEPATH="/${BUCKET_NAME}/${HC_CLUSTER_NAME}-${POD}-snapshot.db" CONTENT_TYPE="application/x-compressed-tar" DATE_VALUE=`date -R` SIGNATURE_STRING="PUT\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n${FILEPATH}" set +x ACCESS_KEY=$(grep aws_access_key_id ${AWS_CREDS} | head -n1 | cut -d= -f2 | sed "s/ //g") SECRET_KEY=$(grep aws_secret_access_key ${AWS_CREDS} | head -n1 | cut -d= -f2 | sed "s/ //g") SIGNATURE_HASH=$(echo -en ${SIGNATURE_STRING} | openssl sha1 -hmac "${SECRET_KEY}" -binary | base64) set -x # FIXME: this is pushing to the OIDC bucket oc exec -it etcd-0 -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -- curl -X PUT -T "/var/lib/data/snapshot.db" \ -H "Host: ${BUCKET_NAME}.s3.amazonaws.com" \ -H "Date: ${DATE_VALUE}" \ -H "Content-Type: ${CONTENT_TYPE}" \ -H "Authorization: AWS ${ACCESS_KEY}:${SIGNATURE_HASH}" \ https://${BUCKET_NAME}.s3.amazonaws.com/${HC_CLUSTER_NAME}-${POD}-snapshot.db done
Pour plus d'informations sur la sauvegarde d'etcd, voir "Sauvegarde et restauration d'etcd sur un cluster hébergé".
Sauvegardez les objets Kubernetes et OpenShift Container Platform en entrant les commandes suivantes. Vous devez sauvegarder les objets suivants :
-
HostedCluster
etNodePool
objets de l'espace de noms HostedCluster -
HostedCluster
secrets de l'espace de noms HostedCluster -
HostedControlPlane
de l'espace de noms du plan de contrôle hébergé -
Cluster
de l'espace de noms du plan de contrôle hébergé -
AWSCluster
,AWSMachineTemplate
, etAWSMachine
de l'espace de noms du plan de contrôle hébergé -
MachineDeployments
,MachineSets
, etMachines
de l'espace de noms du plan de contrôle hébergé ControlPlane
secrets de l'espace de noms du plan de contrôle hébergémkdir -p ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS} ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} chmod 700 ${BACKUP_DIR}/namespaces/ # HostedCluster echo "Backing Up HostedCluster Objects:" oc get hc ${HC_CLUSTER_NAME} -n ${HC_CLUSTER_NS} -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/hc-${HC_CLUSTER_NAME}.yaml echo "--> HostedCluster" sed -i '' -e '/^status:$/,$d' ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/hc-${HC_CLUSTER_NAME}.yaml # NodePool oc get np ${NODEPOOLS} -n ${HC_CLUSTER_NS} -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/np-${NODEPOOLS}.yaml echo "--> NodePool" sed -i '' -e '/^status:$/,$ d' ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/np-${NODEPOOLS}.yaml # Secrets in the HC Namespace echo "--> HostedCluster Secrets:" for s in $(oc get secret -n ${HC_CLUSTER_NS} | grep "^${HC_CLUSTER_NAME}" | awk '{print $1}'); do oc get secret -n ${HC_CLUSTER_NS} $s -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/secret-${s}.yaml done # Secrets in the HC Control Plane Namespace echo "--> HostedCluster ControlPlane Secrets:" for s in $(oc get secret -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} | egrep -v "docker|service-account-token|oauth-openshift|NAME|token-${HC_CLUSTER_NAME}" | awk '{print $1}'); do oc get secret -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} $s -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/secret-${s}.yaml done # Hosted Control Plane echo "--> HostedControlPlane:" oc get hcp ${HC_CLUSTER_NAME} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/hcp-${HC_CLUSTER_NAME}.yaml # Cluster echo "--> Cluster:" CL_NAME=$(oc get hcp ${HC_CLUSTER_NAME} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o jsonpath={.metadata.labels.\*} | grep ${HC_CLUSTER_NAME}) oc get cluster ${CL_NAME} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/cl-${HC_CLUSTER_NAME}.yaml # AWS Cluster echo "--> AWS Cluster:" oc get awscluster ${HC_CLUSTER_NAME} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/awscl-${HC_CLUSTER_NAME}.yaml # AWS MachineTemplate echo "--> AWS Machine Template:" oc get awsmachinetemplate ${NODEPOOLS} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/awsmt-${HC_CLUSTER_NAME}.yaml # AWS Machines echo "--> AWS Machine:" CL_NAME=$(oc get hcp ${HC_CLUSTER_NAME} -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o jsonpath={.metadata.labels.\*} | grep ${HC_CLUSTER_NAME}) for s in $(oc get awsmachines -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --no-headers | grep ${CL_NAME} | cut -f1 -d\ ); do oc get -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} awsmachines $s -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/awsm-${s}.yaml done # MachineDeployments echo "--> HostedCluster MachineDeployments:" for s in $(oc get machinedeployment -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o name); do mdp_name=$(echo ${s} | cut -f 2 -d /) oc get -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} $s -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/machinedeployment-${mdp_name}.yaml done # MachineSets echo "--> HostedCluster MachineSets:" for s in $(oc get machineset -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o name); do ms_name=$(echo ${s} | cut -f 2 -d /) oc get -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} $s -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/machineset-${ms_name}.yaml done # Machines echo "--> HostedCluster Machine:" for s in $(oc get machine -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o name); do m_name=$(echo ${s} | cut -f 2 -d /) oc get -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} $s -o yaml > ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/machine-${m_name}.yaml done
-
Nettoyez les itinéraires
ControlPlane
en entrant cette commande :$ oc delete routes -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --all
En entrant cette commande, vous permettez à l'opérateur ExternalDNS de supprimer les entrées Route53.
Vérifiez que les entrées de Route53 sont propres en exécutant ce script :
function clean_routes() { if [[ -z "${1}" ]];then echo "Give me the NS where to clean the routes" exit 1 fi # Constants if [[ -z "${2}" ]];then echo "Give me the Route53 zone ID" exit 1 fi ZONE_ID=${2} ROUTES=10 timeout=40 count=0 # This allows us to remove the ownership in the AWS for the API route oc delete route -n ${1} --all while [ ${ROUTES} -gt 2 ] do echo "Waiting for ExternalDNS Operator to clean the DNS Records in AWS Route53 where the zone id is: ${ZONE_ID}..." echo "Try: (${count}/${timeout})" sleep 10 if [[ $count -eq timeout ]];then echo "Timeout waiting for cleaning the Route53 DNS records" exit 1 fi count=$((count+1)) ROUTES=$(aws route53 list-resource-record-sets --hosted-zone-id ${ZONE_ID} --max-items 10000 --output json | grep -c ${EXTERNAL_DNS_DOMAIN}) done } # SAMPLE: clean_routes "<HC ControlPlane Namespace>" "<AWS_ZONE_ID>" clean_routes "${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}" "${AWS_ZONE_ID}"
Vérification
Vérifiez tous les objets d'OpenShift Container Platform et le seau S3 pour vous assurer que tout se passe comme prévu.
Prochaines étapes
Restaurez votre cluster hébergé.
5.4.4.4. Restauration d'un cluster hébergé
Rassemblez tous les objets que vous avez sauvegardés et restaurez-les dans votre cluster de gestion de destination.
Conditions préalables
Vous avez sauvegardé les données de votre cluster de gestion des sources.
Assurez-vous que le fichier kubeconfig
du cluster de gestion de destination est placé tel qu'il est défini dans la variable KUBECONFIG
ou, si vous utilisez le script, dans la variable MGMT2_KUBECONFIG
. Utilisez export KUBECONFIG=<Kubeconfig FilePath>
ou, si vous utilisez le script, export KUBECONFIG=${MGMT2_KUBECONFIG}
.
Procédure
Vérifiez que le nouveau cluster de gestion ne contient aucun espace de noms du cluster que vous restaurez en entrant ces commandes :
# Just in case export KUBECONFIG=${MGMT2_KUBECONFIG} BACKUP_DIR=${HC_CLUSTER_DIR}/backup # Namespace deletion in the destination Management cluster $ oc delete ns ${HC_CLUSTER_NS} || true $ oc delete ns ${HC_CLUSTER_NS}-{HC_CLUSTER_NAME} || true
Recréez les espaces de noms supprimés en entrant ces commandes :
# Namespace creation $ oc new-project ${HC_CLUSTER_NS} $ oc new-project ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}
Rétablissez les secrets dans l'espace de noms HC en entrant cette commande :
$ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/secret-*
Restaurez les objets dans l'espace de noms du plan de contrôle
HostedCluster
en entrant ces commandes :# Secrets $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/secret-* # Cluster $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/hcp-* $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/cl-*
Si vous récupérez les nœuds et le pool de nœuds pour réutiliser les instances AWS, restaurez les objets dans l'espace de noms du plan de contrôle HC en entrant ces commandes :
# AWS $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/awscl-* $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/awsmt-* $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/awsm-* # Machines $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/machinedeployment-* $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/machineset-* $ oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}/machine-*
Restaurez les données etcd et le cluster hébergé en exécutant ce script bash :
ETCD_PODS="etcd-0" if [ "${CONTROL_PLANE_AVAILABILITY_POLICY}" = "HighlyAvailable" ]; then ETCD_PODS="etcd-0 etcd-1 etcd-2" fi HC_RESTORE_FILE=${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/hc-${HC_CLUSTER_NAME}-restore.yaml HC_BACKUP_FILE=${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/hc-${HC_CLUSTER_NAME}.yaml HC_NEW_FILE=${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/hc-${HC_CLUSTER_NAME}-new.yaml cat ${HC_BACKUP_FILE} > ${HC_NEW_FILE} cat > ${HC_RESTORE_FILE} <<EOF restoreSnapshotURL: EOF for POD in ${ETCD_PODS}; do # Create a pre-signed URL for the etcd snapshot ETCD_SNAPSHOT="s3://${BUCKET_NAME}/${HC_CLUSTER_NAME}-${POD}-snapshot.db" ETCD_SNAPSHOT_URL=$(AWS_DEFAULT_REGION=${MGMT2_REGION} aws s3 presign ${ETCD_SNAPSHOT}) # FIXME no CLI support for restoreSnapshotURL yet cat >> ${HC_RESTORE_FILE} <<EOF - "${ETCD_SNAPSHOT_URL}" EOF done cat ${HC_RESTORE_FILE} if ! grep ${HC_CLUSTER_NAME}-snapshot.db ${HC_NEW_FILE}; then sed -i '' -e "/type: PersistentVolume/r ${HC_RESTORE_FILE}" ${HC_NEW_FILE} sed -i '' -e '/pausedUntil:/d' ${HC_NEW_FILE} fi HC=$(oc get hc -n ${HC_CLUSTER_NS} ${HC_CLUSTER_NAME} -o name || true) if [[ ${HC} == "" ]];then echo "Deploying HC Cluster: ${HC_CLUSTER_NAME} in ${HC_CLUSTER_NS} namespace" oc apply -f ${HC_NEW_FILE} else echo "HC Cluster ${HC_CLUSTER_NAME} already exists, avoiding step" fi
Si vous récupérez les nœuds et le pool de nœuds pour réutiliser les instances AWS, restaurez le pool de nœuds en entrant cette commande :
oc apply -f ${BACKUP_DIR}/namespaces/${HC_CLUSTER_NS}/np-*
Vérification
Pour vérifier que les nœuds sont entièrement restaurés, utilisez cette fonction :
timeout=40 count=0 NODE_STATUS=$(oc get nodes --kubeconfig=${HC_KUBECONFIG} | grep -v NotReady | grep -c "worker") || NODE_STATUS=0 while [ ${NODE_POOL_REPLICAS} != ${NODE_STATUS} ] do echo "Waiting for Nodes to be Ready in the destination MGMT Cluster: ${MGMT2_CLUSTER_NAME}" echo "Try: (${count}/${timeout})" sleep 30 if [[ $count -eq timeout ]];then echo "Timeout waiting for Nodes in the destination MGMT Cluster" exit 1 fi count=$((count+1)) NODE_STATUS=$(oc get nodes --kubeconfig=${HC_KUBECONFIG} | grep -v NotReady | grep -c "worker") || NODE_STATUS=0 done
Prochaines étapes
Arrêtez et supprimez votre cluster.
5.4.4.5. Suppression d'un cluster hébergé de votre cluster de gestion des sources
Après avoir sauvegardé votre cluster hébergé et l'avoir restauré sur votre cluster de gestion de destination, vous arrêtez et supprimez le cluster hébergé sur votre cluster de gestion source.
Conditions préalables
Vous avez sauvegardé vos données et les avez restaurées dans votre cluster de gestion des sources.
Assurez-vous que le fichier kubeconfig
du cluster de gestion de destination est placé tel qu'il est défini dans la variable KUBECONFIG
ou, si vous utilisez le script, dans la variable MGMT_KUBECONFIG
. Utilisez export KUBECONFIG=<Kubeconfig FilePath>
ou, si vous utilisez le script, export KUBECONFIG=${MGMT_KUBECONFIG}
.
Procédure
Mettez à l'échelle les objets
deployment
etstatefulset
en entrant ces commandes :# Just in case export KUBECONFIG=${MGMT_KUBECONFIG} # Scale down deployments oc scale deployment -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --replicas=0 --all oc scale statefulset.apps -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --replicas=0 --all sleep 15
Supprimez les objets
NodePool
en entrant les commandes suivantes :NODEPOOLS=$(oc get nodepools -n ${HC_CLUSTER_NS} -o=jsonpath='{.items[?(@.spec.clusterName=="'${HC_CLUSTER_NAME}'")].metadata.name}') if [[ ! -z "${NODEPOOLS}" ]];then oc patch -n "${HC_CLUSTER_NS}" nodepool ${NODEPOOLS} --type=json --patch='[ { "op":"remove", "path": "/metadata/finalizers" }]' oc delete np -n ${HC_CLUSTER_NS} ${NODEPOOLS} fi
Supprimez les objets
machine
etmachineset
en entrant ces commandes :# Machines for m in $(oc get machines -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o name); do oc patch -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} ${m} --type=json --patch='[ { "op":"remove", "path": "/metadata/finalizers" }]' || true oc delete -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} ${m} || true done oc delete machineset -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --all || true
Supprimez l'objet cluster en entrant ces commandes :
# Cluster C_NAME=$(oc get cluster -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o name) oc patch -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} ${C_NAME} --type=json --patch='[ { "op":"remove", "path": "/metadata/finalizers" }]' oc delete cluster.cluster.x-k8s.io -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --all
Supprimez les machines AWS (objets Kubernetes) en entrant ces commandes. Ne vous préoccupez pas de la suppression des machines AWS réelles. Les instances cloud ne seront pas affectées.
# AWS Machines for m in $(oc get awsmachine.infrastructure.cluster.x-k8s.io -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} -o name) do oc patch -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} ${m} --type=json --patch='[ { "op":"remove", "path": "/metadata/finalizers" }]' || true oc delete -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} ${m} || true done
Supprimez les objets de l'espace de noms
HostedControlPlane
etControlPlane
HC en entrant ces commandes :# Delete HCP and ControlPlane HC NS oc patch -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} hostedcontrolplane.hypershift.openshift.io ${HC_CLUSTER_NAME} --type=json --patch='[ { "op":"remove", "path": "/metadata/finalizers" }]' oc delete hostedcontrolplane.hypershift.openshift.io -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} --all oc delete ns ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} || true
Supprimez les objets de l'espace de noms
HostedCluster
et HC en entrant ces commandes :# Delete HC and HC Namespace oc -n ${HC_CLUSTER_NS} patch hostedclusters ${HC_CLUSTER_NAME} -p '{"metadata":{"finalizers":null}}' --type merge || true oc delete hc -n ${HC_CLUSTER_NS} ${HC_CLUSTER_NAME} || true oc delete ns ${HC_CLUSTER_NS} || true
Vérification
Pour vérifier que tout fonctionne, entrez les commandes suivantes :
# Validations export KUBECONFIG=${MGMT2_KUBECONFIG} oc get hc -n ${HC_CLUSTER_NS} oc get np -n ${HC_CLUSTER_NS} oc get pod -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} oc get machines -n ${HC_CLUSTER_NS}-${HC_CLUSTER_NAME} # Inside the HostedCluster export KUBECONFIG=${HC_KUBECONFIG} oc get clusterversion oc get nodes
Prochaines étapes
Supprimez les pods OVN dans le cluster hébergé afin de pouvoir vous connecter au nouveau plan de contrôle OVN qui s'exécute dans le nouveau cluster de gestion :
-
Chargez la variable d'environnement
KUBECONFIG
avec le chemin kubeconfig du cluster hébergé. Entrez cette commande :
$ oc delete pod -n openshift-ovn-kubernetes --all
5.4.4.6. Exécution d'un script pour sauvegarder et restaurer un cluster hébergé
Pour accélérer le processus de sauvegarde d'un cluster hébergé et sa restauration dans la même région sur AWS, vous pouvez modifier et exécuter un script.
Procédure
Remplacez les variables du script suivant par vos propres informations :
# Fill the Common variables to fit your environment, this is just a sample SSH_KEY_FILE=${HOME}/.ssh/id_rsa.pub BASE_PATH=${HOME}/hypershift BASE_DOMAIN="aws.sample.com" PULL_SECRET_FILE="${HOME}/pull_secret.json" AWS_CREDS="${HOME}/.aws/credentials" CONTROL_PLANE_AVAILABILITY_POLICY=SingleReplica HYPERSHIFT_PATH=${BASE_PATH}/src/hypershift HYPERSHIFT_CLI=${HYPERSHIFT_PATH}/bin/hypershift HYPERSHIFT_IMAGE=${HYPERSHIFT_IMAGE:-"quay.io/${USER}/hypershift:latest"} NODE_POOL_REPLICAS=${NODE_POOL_REPLICAS:-2} # MGMT Context MGMT_REGION=us-west-1 MGMT_CLUSTER_NAME="${USER}-dev" MGMT_CLUSTER_NS=${USER} MGMT_CLUSTER_DIR="${BASE_PATH}/hosted_clusters/${MGMT_CLUSTER_NS}-${MGMT_CLUSTER_NAME}" MGMT_KUBECONFIG="${MGMT_CLUSTER_DIR}/kubeconfig" # MGMT2 Context MGMT2_CLUSTER_NAME="${USER}-dest" MGMT2_CLUSTER_NS=${USER} MGMT2_CLUSTER_DIR="${BASE_PATH}/hosted_clusters/${MGMT2_CLUSTER_NS}-${MGMT2_CLUSTER_NAME}" MGMT2_KUBECONFIG="${MGMT2_CLUSTER_DIR}/kubeconfig" # Hosted Cluster Context HC_CLUSTER_NS=clusters HC_REGION=us-west-1 HC_CLUSTER_NAME="${USER}-hosted" HC_CLUSTER_DIR="${BASE_PATH}/hosted_clusters/${HC_CLUSTER_NS}-${HC_CLUSTER_NAME}" HC_KUBECONFIG="${HC_CLUSTER_DIR}/kubeconfig" BACKUP_DIR=${HC_CLUSTER_DIR}/backup BUCKET_NAME="${USER}-hosted-${MGMT_REGION}" # DNS AWS_ZONE_ID="Z026552815SS3YPH9H6MG" EXTERNAL_DNS_DOMAIN="guest.jpdv.aws.kerbeross.com"
- Enregistrez le script dans votre système de fichiers local.
Exécutez le script en entrant la commande suivante :
source <env_file>
où :
env_file
est le nom du fichier dans lequel vous avez enregistré le script.