<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Restauration on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/restauration/</link><description>Recent content in Restauration on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Mon, 02 Aug 2021 06:15:00 +0000</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/restauration/index.xml" rel="self" type="application/rss+xml"/><item><title>Sauvegarder son Kubernetes avec Velero (ex Ark)</title><link>https://blog.zwindler.fr/2021/08/02/__trashed-2/</link><pubDate>Mon, 02 Aug 2021 06:15:00 +0000</pubDate><guid>https://blog.zwindler.fr/2021/08/02/__trashed-2/</guid><description>&lt;img src="https://blog.zwindler.fr/2021/08/68747470733a2f2f76656c65726f2e696f2f646f63732f6d61696e2f696d672f76656c65726f2e706e67.webp" alt="Featured image of post Sauvegarder son Kubernetes avec Velero (ex Ark)" /&gt;&lt;h2 id="contexte"&gt;Contexte
&lt;/h2&gt;&lt;p&gt;J’ai écris cet article / tuto en janvier 2019 sans jamais le terminer / mettre en forme. A l’époque, Heptio était en train de se faire racheter par VMware. Au moment où j’allais le poster, VMware a fait quelques modifications dans le tool, notamment en &lt;a class="link" href="https://github.com/vmware-tanzu/velero" target="_blank" rel="noopener"
&gt;changeant le nom de Ark vers Velero et en l’intégrant à Tanzu&lt;/a&gt; (le Kubernetes de VMware).&lt;/p&gt;
&lt;p&gt;Idéalement, j’aurais donc aimé réécrire l’article en remettant tout à jour, les noms, les lignes de commandes, etc. Sauf que je ne l’ai jamais fait. Et aujourd’hui, je ne travaille plus sur des clusters Kubernetes avec des workloads majoritairement Stateful et préfère l’approche Déclarative (type FluxCD) dans l’hypothèse où j’aurais un énorme crash à gérer plutôt que de tenter une restauration, avec tous les effets de bords et les risques que ça implique.&lt;/p&gt;
&lt;p&gt;Cependant, plutôt que de mettre cet article « presque fini » à la corbeille, je prend donc le parti de le poster « tel quel », avec tous les défauts qu’il pourra avoir (notamment si certaines parties sont &lt;em&gt;outdated&lt;/em&gt;). Le concept général lui, restera le même.&lt;/p&gt;
&lt;p&gt;Pour illustrer le propos, j’avais déployé un cluster AKS mais ça marche bien évidemment avec n’importe quel cluster Kubernetes.&lt;/p&gt;
&lt;h2 id="générer-le-cluster-k8s-aks"&gt;Générer le cluster K8s AKS
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;az login
az group create --name myownkubernetescluster --location westeurope \
--subscription &amp;#34;Visual Studio Professional&amp;#34;
az aks create --resource-group myownkubernetescluster --name myawesomeakscluster \
--node-count 3 --enable-addons monitoring --node-vm-size Standard_B2s \
--kubernetes-version 1.10.9 --ssh-key-value ~/.ssh/dgermain_never_expire_rsa_openssl2.pub \
--subscription &amp;#34;Visual Studio Professional&amp;#34;
az aks get-credentials --resource-group myownkubernetescluster --name myawesomeakscluster \
--subscription &amp;#34;Visual Studio Professional&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="éventuellement-ajouter-les-droits-pour-le-dashboard"&gt;Éventuellement ajouter les droits pour le dashboard
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard
az aks browse --resource-group myownkubernetescluster --name myawesomecluster
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="sauvegarde--restauration-avec-velero"&gt;Sauvegarde / restauration avec Velero
&lt;/h2&gt;&lt;p&gt;Information sur Velero (Ark Heptio) &lt;a class="link" href="https://github.com/vmware-tanzu/velero" target="_blank" rel="noopener"
&gt;github.com/vmware-tanzu/velero&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Comme on est sur Azure dans mon exemple :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/vmware-tanzu/velero-plugin-for-microsoft-azure#setup" target="_blank" rel="noopener"
&gt;github.com/vmware-tanzu/velero-plugin-for-microsoft-azure#setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On commencer par créer un ressource group spécifique aux backups (pour ne pas tout perdre si le ressource group est supprimé)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;AZURE_BACKUP_RESOURCE_GROUP=arkbackups
az group create -n $AZURE_BACKUP_RESOURCE_GROUP --location westeurope \
--subscription &amp;#34;Visual Studio Professional&amp;#34;
AZURE_STORAGE_ACCOUNT_ID=&amp;#34;ark$(uuidgen | cut -d &amp;#39;-&amp;#39; -f5 | tr &amp;#39;[A-Z]&amp;#39; &amp;#39;[a-z]&amp;#39;)&amp;#34;
az storage account create \
--name $AZURE_STORAGE_ACCOUNT_ID \
--resource-group $AZURE_BACKUP_RESOURCE_GROUP \
--sku Standard_GRS \
--encryption-services blob \
--https-only true \
--kind BlobStorage \
--access-tier Hot \
--location westeurope \
--subscription &amp;#34;Visual Studio Professional&amp;#34;
az storage container create -n arkblob --public-access off \
--account-name $AZURE_STORAGE_ACCOUNT_ID --subscription &amp;#34;Visual Studio Professional&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Récupérer le groupe de ressource du cluster K8s&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;az group list --query &amp;#39;[].{ ResourceGroup: name, Location:location }&amp;#39; --subscription &amp;#34;Visual Studio Professional&amp;#34;
[...]
{
&amp;#34;Location&amp;#34;: &amp;#34;westeurope&amp;#34;,
&amp;#34;ResourceGroup&amp;#34;: &amp;#34;MC_myownkubernetescluster_myawesomeakscluster_westeurope&amp;#34;
},
{
&amp;#34;Location&amp;#34;: &amp;#34;westeurope&amp;#34;,
&amp;#34;ResourceGroup&amp;#34;: &amp;#34;myownkubernetescluster&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans le cas d’AKS, il s’agit bien de choisir le groupe qui contient les VMs (MC_myownkubernetescluster_myawesomeakscluster_westeurope), et pas celui que vous avez créé en début de procédure (myownkubernetescluster) qui ne contient que l’objet « Kubernetes service ».&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2019/01/aks_ark.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;AZURE_RESOURCE_GROUP=MC_myownkubernetescluster_myawesomeakscluster_westeurope
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Créer un « Service principal » (compte de service dans Azure). Ne pas oublier de stocker le secret (contenu de la variable AZURE_CLIENT_SECRET) car on y aura plus accès a posteriori.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;AZURE_CLIENT_SECRET=`az ad sp create-for-rbac --name &amp;#34;myarkserviceprincipal&amp;#34; --role &amp;#34;Contributor&amp;#34; --query &amp;#39;password&amp;#39; -o tsv`
AZURE_CLIENT_ID=`az ad sp list --display-name &amp;#34;myarkserviceprincipal&amp;#34; --query &amp;#39;[0].appId&amp;#39; -o tsv`
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="récupérer-les-sources"&gt;Récupérer les sources
&lt;/h3&gt;&lt;p&gt;Dans mon cas, la dernière version disponible est la v1.6.2, et j’ai besoin des la version linux amd64&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir velero &amp;amp;&amp;amp; cd velero
wget https://github.com/vmware-tanzu/velero/releases/download/v1.6.2/velero-v1.6.2-linux-amd64.tar.gz
tar -xzf velero-v1.6.2-linux-amd64.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="créer-un-namespace-et-un-service-provider-différents-de-ceux-par-défaut"&gt;Créer un namespace et un service provider (différents de ceux par défaut)
&lt;/h3&gt;&lt;p&gt;Quelque soit le cloud provider, il faut modifier le fichier config/common/00-prereqs.yaml&lt;/p&gt;
&lt;p&gt;Comme indiqué dans la documentation dédiée, ce fichier contient la plupart des informations génériques, notamment, les définitions (CRD pour les backups/restores Ark), le namespace, le service account et les rôles (RBAC).&lt;/p&gt;
&lt;p&gt;Dans notre cas, on doit donc modifier le fichier config/common/00-prereqs.yaml pour qu’il créé un autre namespace, qu’on appellera « backup » pour faire original;&lt;br&gt;
On va aussi modifier le nom du service account pour qu’il colle à celui du Service Principal azure (pas obligatoire, mais c’est pour rester cohérent) et surtout son namespace.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vi config/common/00-prereqs.yaml
[...]
---
apiVersion: v1
kind: Namespace
metadata:
name: backup
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: myarkserviceprincipal
namespace: backup
labels:
component: ark
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: ark
labels:
component: ark
subjects:
- kind: ServiceAccount
namespace: backup
name: myarkserviceprincipal
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ensuite, il faut également modifier les spécifiques à notre cloud provider (ici Azure), en particulier le namespace, mais aussi nos informations de connexion à notre blob&lt;/p&gt;
&lt;p&gt;Dans le déploiement, changer le namespace et le serviceAccountName&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vi config/azure/00-ark-deployment.yaml
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
namespace: backup
name: ark
[...]
spec:
restartPolicy: Always
serviceAccountName: myarkserviceprincipal
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;vi config/azure/05-ark-backupstoragelocation.yaml
---
apiVersion: ark.heptio.com/v1
kind: BackupStorageLocation
metadata:
name: default
namespace: backup
spec:
provider: azure
objectStorage:
bucket: arkblob
config:
resourceGroup: arkbackups
storageAccount: arkANDTHEUUID
vi config/azure/06-ark-volumesnapshotlocation.yaml
---
apiVersion: ark.heptio.com/v1
kind: VolumeSnapshotLocation
metadata:
name: azure-default
namespace: backup
spec:
provider: azure
config:
apiTimeout: 30s
resourceGroup: ark-EUW-sandbox-RG
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Créer les objets sur le cluster Kubernetes sur Azure&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=myawesomeakscluster apply -f config/common/00-prereqs.yaml
customresourcedefinition.apiextensions.k8s.io/backups.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/schedules.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/restores.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/downloadrequests.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/deletebackuprequests.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/podvolumebackups.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/podvolumerestores.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/resticrepositories.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/backupstoragelocations.ark.heptio.com created
customresourcedefinition.apiextensions.k8s.io/volumesnapshotlocations.ark.heptio.com created
namespace/backup created
serviceaccount/arkeuwsandboxsp created
clusterrolebinding.rbac.authorization.k8s.io/ark created
kubectl --context=myawesomeakscluster apply -f config/azure/
deployment.apps/ark created
backupstoragelocation.ark.heptio.com/default created
volumesnapshotlocation.ark.heptio.com/azure-default created
daemonset.apps/restic created
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A noter : avant le premier appel de ark, sur chaque machine, il faudra spécifier dans quel namespace est ark sur notre cluster K8s.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;./ark client config set namespace=backup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Créer le secret du service provider&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#AZURE_RESOURCE_GROUP=MC_myownkubernetescluster_myawesomeakscluster_westeurope
AZURE_SUBSCRIPTION_ID=d717105a-ac1d-457c-8ef8-7467aa90df5c
AZURE_TENANT_ID=15eb2494-5298-4347-81a3-e2d3c08a0f82
AZURE_CLIENT_ID=f44ae340-97a2-4d54-bdc5-c4d7b2a49a2a
AZURE_CLIENT_SECRET=r+VGoBqOwraH9uVdk/sED3Ezdb7bIZI1xjvZyyvmnzM=
kubectl --context=myawesomeakscluster --namespace=backup create secret generic ark-azure-credentials \
--from-literal AZURE_SUBSCRIPTION_ID=${AZURE_SUBSCRIPTION_ID} \
--from-literal AZURE_TENANT_ID=${AZURE_TENANT_ID} \
--from-literal AZURE_CLIENT_ID=${AZURE_CLIENT_ID} \
--from-literal AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET} \
--from-literal AZURE_RESOURCE_GROUP=${AZURE_RESOURCE_GROUP}
secret/ark-azure-credentials created
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="créer-des-données-dans-le-cluster-pour-vérifier-le-fonctionnement"&gt;Créer des données dans le cluster pour vérifier le fonctionnement
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl create ns testrestore
namespace/testrestore created
kubectl run pod ubuntu --image=ubuntu --namespace=testrestore
deployment.apps/pod created
kubectl --namespace=testrestore get all
NAME READY STATUS RESTARTS AGE
pod/pod-5945cc9b88-sq8c8 0/1 RunContainerError 1 14s
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/pod 1 1 1 0 14s
NAME DESIRED CURRENT READY AGE
replicaset.apps/pod-5945cc9b88 1 1 0 14s
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="créer-une-backup"&gt;Créer une backup
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;./ark backup create $(date +&amp;#34;%Y%m%d-%H%M&amp;#34;)
Backup request &amp;#34;20190109-1553&amp;#34; submitted successfully.
Run `ark backup describe 20190109-1553` or `ark backup logs 20190109-1553` for more details.
./ark backup describe 09-01-2019
Name: 09-01-2019
Namespace: backup
Labels:
Annotations:
Phase: New
Namespaces:
Included: *
Excluded:
Resources:
Included: *
Excluded:
Cluster-scoped: auto
Label selector:
Storage Location:
Snapshot PVs: auto
TTL: 720h0m0s
Hooks:
Backup Format Version: 0
Started: &amp;lt;n/a&amp;gt;
Completed: &amp;lt;n/a&amp;gt;
Expiration: 0001-01-01 00:00:00 +0000 UTC
Validation errors:
Persistent Volumes:
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="restaurer-une-backup"&gt;Restaurer une backup
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --namespace=testrestore delete ns testrestore
namespace &amp;#34;testrestore&amp;#34; deleted
./ark backup get
NAME STATUS CREATED EXPIRES STORAGE LOCATION SELECTOR
20190109-1553 Completed 2019-01-02 14:30:17 +0100 CET 23d default
./ark restore create restore-01 --from-backup 20190109-1553
Restore request &amp;#34;restore-01&amp;#34; submitted successfully.
Run `ark restore describe restore-01` or `ark restore logs restore-01` for more details.
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Gérez vos sauvegardes ElasticSearch avec Curator</title><link>https://blog.zwindler.fr/2018/12/11/gerez-vos-sauvegardes-elasticsearch-avec-curator/</link><pubDate>Tue, 11 Dec 2018 12:45:39 +0000</pubDate><guid>https://blog.zwindler.fr/2018/12/11/gerez-vos-sauvegardes-elasticsearch-avec-curator/</guid><description>&lt;img src="https://blog.zwindler.fr/2017/10/elastic_3.webp" alt="Featured image of post Gérez vos sauvegardes ElasticSearch avec Curator" /&gt;&lt;h2 id="curator-et-elasticsearch"&gt;Curator et Elasticsearch
&lt;/h2&gt;&lt;p&gt;Il y a quelques mois, j’ai écris un article pour parler de mon expérience &lt;a class="link" href="https://blog.zwindler.fr/2018/07/04/sauvegarder-et-restaurer-des-index-dans-elasticsearch/" &gt;« supprime tes données dans ton cluster Elasticsearch par erreur »&lt;/a&gt;. Et par conséquent, &lt;a class="link" href="https://blog.zwindler.fr/2018/07/04/sauvegarder-et-restaurer-des-index-dans-elasticsearch/" &gt;de la sauvegarde que j’avais mis en place&lt;/a&gt; pour éviter de se retrouver sans rien en cas de récidive ;-).&lt;/p&gt;
&lt;p&gt;Le moins qu’on puisse dire, c’est que l’utilisation des API pour une opération aussi régulière qu’une sauvegarde (ou la suppression des vieux index, par exemple) est quelque chose d’assez lourd à mettre en place.&lt;/p&gt;
&lt;p&gt;Un des lecteurs avait pris le temps de me conseiller un outil fourni par les gens de chez Elastic, et qui permet de gérer plus simplement ces tâches fastidieuses : &lt;a class="link" href="https://www.elastic.co/guide/en/elasticsearch/client/curator/current/index.html" target="_blank" rel="noopener"
&gt;Curator&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="prérequis-côté-serveur"&gt;Prérequis côté serveur
&lt;/h2&gt;&lt;p&gt;J’avais donc dis que je regarderai et j’ai donc profité d’un de mes clusters ElasticSearch sur Kubernetes pour tester l’outil.&lt;/p&gt;
&lt;p&gt;La première chose à faire est donc de récupérer l’adresse IP (ou le nom DNS) qui nous permet d’accéder à l’API web de notre cluster ElasticSearch. Pour rester cohérent avec l’exemple, je vais dérouler la procédure de mise en place d’une sauvegarde avec &lt;strong&gt;Curator&lt;/strong&gt; dans un cluster Kubernetes qui contient un cluster ElasticSearch existant (ça ne complique pas beaucoup). Mais dans tout les cas il vous faudra une adresse ;-).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=andromeda --namespace=elastic get svc elasticsearch
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch ClusterIP 10.10.10.15 9200/TCP,9300/TCP 115d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;En se connectant dans le container Elastic, je peux regarder comment est configuré la base, et en particulier les destinations physiques « repo ».&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=andromeda --namespace=elastic exec -it docker-elasticsearch-0 /bin/bash
cat /opt/elasticsearch/config/elasticsearch.yml
[...]
path:
data: ${ELASTICSEARTCH_DATA_DIR}/data
logs: ${ELASTICSEARTCH_DATA_DIR}/logs
repo: ${REPO_LOCATIONS}
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans le cas d’ElasticSearch en tant que container Docker, il existe dans l’image Docker officielle une variable &lt;strong&gt;REPO_LOCATIONS&lt;/strong&gt;. Dans mon cas, j’ai donc modifié la configuration de mon déploiement pour spécifier à ElasticSearch où trouver les variables.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[...]
- env:
- name: REPO_LOCATIONS
value: &amp;#39;[&amp;#34;/data/bkp&amp;#34;]&amp;#39;
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pour ceux qui n’utilisent pas Elasticsearch en tant que cluster Docker (&lt;a class="link" href="https://blog.zwindler.fr/2017/10/03/elasticstack-kibana-elasticsearch-logstash-beats/" &gt;si vous l’avez installé avec un de mes playbooks Ansible par exemple&lt;/a&gt;), vous pouvez éditer le fichier de configuration et ajouter les lignes suivantes (et vous assurer que le chemin existe effectivement) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo vim /etc/elasticsearch/elasticsearch.yml
[...]
path:
repo: [&amp;#34;/my/backup/directory/path&amp;#34;]
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Redémarrer ElasticSearch pour prise en compte (ou &lt;em&gt;deletez&lt;/em&gt; le pod, niark niark niark). Notre base ElasticSearch sait maintenant où déposer les futures sauvegardes.&lt;/p&gt;
&lt;h2 id="prérequis-côté-client"&gt;Prérequis côté client
&lt;/h2&gt;&lt;p&gt;Lancer un curl sur l’adresse IP que vous avez collecter au début du tuto, pour voir si on arrive à lister les indices présents.&lt;/p&gt;
&lt;p&gt;Dans mon cas, je lance un container Ubuntu directement dans le cluster K8s pour faire simple.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl --context=andromeda run my-shell --rm -i --tty --image ubuntu -- bash
#install prerequisites for curl
apt-get update
apt-get -y install curl
#do the actual curl
curl -X GET &amp;#34;10.10.10.15:9200/_cat/indices?v&amp;#34;
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open awesomeapp-health-2018.11.30 6VrEZk-XTGm3eeKJEzDZnA 5 1 17054 0 2mb 2mb
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OK ! On a bien accès à l’API. On peut maintenant configurer la variable d’environnement REPO_LOCATIONS&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -XPUT &amp;#39;http://10.10.10.15:9200/_snapshot/svg&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; -d &amp;#39;{
&amp;#34;type&amp;#34;: &amp;#34;fs&amp;#34;,
&amp;#34;settings&amp;#34;: {
&amp;#34;location&amp;#34;: &amp;#34;/data/bkp&amp;#34;,
&amp;#34;compress&amp;#34;: true
}
}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Cette commande devrait vous renvoyer ceci :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{&amp;#34;acknowledged&amp;#34;:true}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="et-maintenant-"&gt;Et maintenant ?
&lt;/h2&gt;&lt;p&gt;Cette partie du tuto était identique (à Kubernetes près) au tutoriel précédent. Maintenant, ça diffère.&lt;/p&gt;
&lt;p&gt;On va installer &lt;strong&gt;Curator&lt;/strong&gt;, mais pas via le gestionnaire de package du système. En effet, si vous avez une version récente d’ElasticSearch et que vous vous contentez d’APT, vous risquez d’obtenir l’erreur suivante :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apt-get install elasticsearch-curator
curator_cli show_indices
elasticsearch.exceptions.ElasticsearchException: Unable to create client connection to Elasticsearch. Error: Elasticsearch version 6.3.0 incompatible with this version of Curator (5.2.0)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La version conseillée par Elastic est l’utilisation du gestionnaire de package Python (pip) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apt-get update
apt-get -y install curl python
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --force-reinstall
pip install elasticsearch-curator --user
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans ce tutoriel, on va commencer par utiliser la CLI de &lt;strong&gt;Curator&lt;/strong&gt;. Mais il faut savoir qu’il existe aussi une version qui permet de jouer des scenarii prédéfinis (les &lt;strong&gt;Actions&lt;/strong&gt;). Du coup, il est logique que tout la partie connexion et authentification soit gérée par un fichier de configuration. Malheureusement, cette partie n’est pas super bien documentée si on se contente de la doc d’install (il faut fouiller un peu). Dans les grandes lignes, voilà ce qu’il faut faire :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir ~/.curator
cat &amp;gt; ~/.curator/curator.yml &amp;lt;&amp;lt; EOF
client:
hosts: 10.10.10.15
port: 9200
url_prefix:
use_ssl: False
certificate:
client_cert:
client_key:
ssl_no_validate: False
http_auth:
timeout: 30
master_only: False
logging:
loglevel: INFO
logfile: /data
logformat: default
blacklist: [&amp;#39;elasticsearch&amp;#39;, &amp;#39;urllib3&amp;#39;]
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ici, j’ai juste ajouté mon IP et mon port de connexion à l’API, mais on peut donc aussi configurer pas mal de choses en plus.&lt;/p&gt;
&lt;p&gt;Curator maintenant configuré, on peut tester la même commande qu’avec le cURL pour lister les indices.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/root/.local/bin/curator_cli show_indices
awesomeapp-health-2018.11.12
awesomeapp-health-2018.11.13
awesomeapp-health-2018.11.14
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="création-dun-snapshot"&gt;Création d’un snapshot
&lt;/h2&gt;&lt;p&gt;Maintenant qu’on a &lt;strong&gt;Curator&lt;/strong&gt; qui peut se connecter à ElasticSearch, on va enfin pouvoir lancer notre sauvegarde, via la feature des snapshots ! (Plus d’info sur les filtres, vous pouvez aller sur &lt;a class="link" href="https://www.elastic.co/guide/en/elasticsearch/client/curator/current/singleton-cli.html" target="_blank" rel="noopener"
&gt;la page de documentation officielle&lt;/a&gt;)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;root/.local/bin/curator_cli snapshot --repository svg --filter_list &amp;#39;{&amp;#34;filtertype&amp;#34;:&amp;#34;none&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La commande devrait prendre un certain temps, en particulier si vous avez beaucoup de données. Une fois qu’elle a rendu la main, vérifiez que le snapshot existe, avec la CLI, et en allant voir le contenu du dossier configuré précédemment.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;root/.local/bin/curator_cli show_snapshots --repository svg
curator-20181204095300
ll /data/bck
total 36
drwxr-xr-x 3 elasticsearch elasticsearch 4096 Dec 4 09:54 ./
drwxr-xr-x 6 elasticsearch elasticsearch 4096 Dec 4 09:47 ../
-rw-r--r-- 1 elasticsearch elasticsearch 29 Dec 4 09:54 incompatible-snapshots
-rw-r--r-- 1 elasticsearch elasticsearch 5522 Dec 4 09:54 index-0
-rw-r--r-- 1 elasticsearch elasticsearch 8 Dec 4 09:54 index.latest
drwxr-xr-x 56 elasticsearch elasticsearch 4096 Dec 4 09:53 indices/
-rw-r--r-- 1 elasticsearch elasticsearch 103 Dec 4 09:53 meta-yMBl9IsPRYGCitWqGjxh2Q.dat
-rw-r--r-- 1 elasticsearch elasticsearch 470 Dec 4 09:54 snap-yMBl9IsPRYGCitWqGjxh2Q.dat
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="je-suis-expert-en-sauvegarde-moi-pas-en-restauration"&gt;Je suis expert en sauvegarde moi, pas en restauration&amp;hellip;
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;True story&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bon, sauvegarder c’est bien, restaurer c’est mieux ! Il existe bien évidemment une commande restore pour ça ;)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;root/.local/bin/curator_cli restore --repository svg --name curator-20181204095300 --filter_list &amp;#39;{&amp;#34;filtertype&amp;#34;:&amp;#34;none&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="et-après-"&gt;Et après !
&lt;/h2&gt;&lt;p&gt;Clairement, on ne va pas se contenter de ça. C’est déjà mieux que précédemment avec les appels d’API, mais on peut faire encore mieux. Déjà, si vous avez fait attention, j’ai teasé qu’on pouvait gérer les indices (et ainsi virer les plus vieux) avec &lt;strong&gt;Curator&lt;/strong&gt;. C’est clairement un usecase hyper sympa de l’outil.&lt;/p&gt;
&lt;p&gt;Ensuite, j’ai également teasé la possibilité de gérer des tâches en mode batch, avec les actions, qui sont des fichiers de définition simple de vos actions à faire avec &lt;strong&gt;Curator&lt;/strong&gt;. Il y aura bien entendu des articles à suivre pour en apprendre plus ;-)&lt;/p&gt;
&lt;h2 id="ressources-additionnelles"&gt;Ressources additionnelles
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/_list_all_indices.html" target="_blank" rel="noopener"
&gt;www.elastic.co/guide/en/elasticsearch/reference/current/_list_all_indices.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://postmarkapp.com/blog/tools-we-use-curator-for-elasticsearch" target="_blank" rel="noopener"
&gt;postmarkapp.com/blog/tools-we-use-curator-for-elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://ikeptwalking.com/taking-elasticsearch-snapshots-using-curator/" target="_blank" rel="noopener"
&gt;ikeptwalking.com/taking-elasticsearch-snapshots-using-curator/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Sauvegarder et restaurer des index dans Elasticsearch</title><link>https://blog.zwindler.fr/2018/07/04/sauvegarder-et-restaurer-des-index-dans-elasticsearch/</link><pubDate>Wed, 04 Jul 2018 11:45:55 +0000</pubDate><guid>https://blog.zwindler.fr/2018/07/04/sauvegarder-et-restaurer-des-index-dans-elasticsearch/</guid><description>&lt;img src="https://blog.zwindler.fr/2017/10/elastic_3.webp" alt="Featured image of post Sauvegarder et restaurer des index dans Elasticsearch" /&gt;&lt;h2 id="un-développeur-sest-dit-jai-besoin-delasticsearch-"&gt;Un développeur s’est dit « J’ai BESOIN d’Elasticsearch ! »
&lt;/h2&gt;&lt;p&gt;Et ce qui devait arriver, arriva. Du jour au lendemain, vous n’avez pas eu le temps de dire « ouf » et vous avez déjà une base Elasticsearch à maintenir en production !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dure vie des #Ops ;-)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="on-va-apprendre-comment-sauvegarder-et-restaurer-des-données-dans-elk"&gt;On va apprendre comment sauvegarder et restaurer des données dans ELK
&lt;/h2&gt;&lt;p&gt;Cet article n’arrive pas par hasard. A la base je voulais faire un article sur l’utilisation d’ELK avec l’API REST. Mais en jouant avec les API (en voulant purger des données de manière ciblée), j’ai supprimé un mois complet de données.&lt;/p&gt;
&lt;p&gt;S’il y a une chose que j’ai apprise avec ce blog, c’est qu’il faut toujours poster l’article sur la solution à un problème AVANT l’article où je parle du problème que j’ai eu. Certains lecteurs ont parfois un peu la tête en l’air, et mieux vaut avoir la solution sous le coude &lt;em&gt;a priori&lt;/em&gt;. ;-)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_deleted_indexes.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Oops&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="les-snapshots"&gt;Les snapshots
&lt;/h2&gt;&lt;p&gt;On ne peut pas dire que cette partie de la documentation d’Elastic soit hyper bien mise en avant. Ca fait partie de ces projets où la mise en place (&lt;em&gt;regardez comme c’est facile à installer&lt;/em&gt;) et tellement mise en avant qu’on ne sait pas comment l’exploiter après.&lt;/p&gt;
&lt;p&gt;Mais en insistant un peu on fini par tomber sur &lt;a class="link" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html" target="_blank" rel="noopener"
&gt;les snapshots&lt;/a&gt;, la feature qui va vous permettre de faire des dumps de vos données à un instant T.&lt;/p&gt;
&lt;h2 id="mise-en-place-du-dossier-de-snap"&gt;Mise en place du dossier de snap
&lt;/h2&gt;&lt;p&gt;La première chose à faire est de configurer notre répertoire où on va déposer/récupérer nos fichiers snapshots. Assurez vous qu’Elasticsearch puisse lire/écrire dedans, bien entendu !&lt;/p&gt;
&lt;p&gt;On commence par indiquer le chemin dans le fichier de configuration d’Elasticsearch (ici &lt;strong&gt;/svg&lt;/strong&gt;)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vi /etc/elasticsearch/elasticsearch.yml
path.repo: [&amp;#34;/svg&amp;#34;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On créé le dossier (ben oui) et on lui donne les droits qui vont bien.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir /svg
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="créer-lemplacement-des-snapshots"&gt;Créer l&amp;rsquo;emplacement des snapshots
&lt;/h2&gt;&lt;p&gt;Maintenant que notre Elasticsearch est configuré, on peut créer un snapshot. Les interactions avec Elasticsearch se font exclusivement en API, donc on dégaine notre plus beau JSON avec cURL :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -XPUT &amp;#39;http://localhost:9200/_snapshot/svg&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; -d &amp;#39;{
&amp;#34;type&amp;#34;: &amp;#34;fs&amp;#34;,
&amp;#34;settings&amp;#34;: {
&amp;#34;location&amp;#34;: &amp;#34;/svg&amp;#34;,
&amp;#34;compress&amp;#34;: true
}
}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans cet exemple, j’exécute la requête en local (localhost), mais vous pouvez bien entendu lancer l’instruction sur des hôtes distants.&lt;/p&gt;
&lt;p&gt;Notez aussi que j’ai ajouté l’option &lt;strong&gt;compress&lt;/strong&gt;, pour des raisons évidentes d’économies d’espace disque et que j’ai indiqué la location à &lt;strong&gt;/svg&lt;/strong&gt;, qu’on a défini précédemment.&lt;/p&gt;
&lt;p&gt;On vérifie que la commande a bien été prise en compte (à partir de maintenant je vais omettre la partie cURL et juste mettre la requête) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET /_snapshot/svg
{
&amp;#34;svg&amp;#34;: {
&amp;#34;type&amp;#34;: &amp;#34;fs&amp;#34;,
&amp;#34;settings&amp;#34;: {
&amp;#34;compress&amp;#34;: &amp;#34;true&amp;#34;,
&amp;#34;location&amp;#34;: &amp;#34;/svg&amp;#34;
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="ça-y-est-on-a-des-sauvegardes-"&gt;Ça y est, on a des sauvegardes ?
&lt;/h2&gt;&lt;p&gt;Non, pas encore tout à fait :-/&lt;/p&gt;
&lt;p&gt;Maintenant que j’ai créé l&amp;rsquo;emplacement, je dois créer le snapshot :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;PUT /_snapshot/svg/snapshot_1
{
&amp;#34;accepted&amp;#34;: true
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Maintenant c’est bon. On peut ensuite vérifier où on en est avec la requête suivante :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET /_snapshot/svg/snapshot_1
{
&amp;#34;snapshots&amp;#34;: [
{
&amp;#34;snapshot&amp;#34;: &amp;#34;snapshot_1&amp;#34;,
&amp;#34;uuid&amp;#34;: &amp;#34;s38NGqRES1uZfiyHiRNJVQ&amp;#34;,
&amp;#34;version_id&amp;#34;: 5060299,
&amp;#34;version&amp;#34;: &amp;#34;5.6.2&amp;#34;,
&amp;#34;indices&amp;#34;: [
&amp;#34;logstash-2017.06.29&amp;#34;,
&amp;#34;logstash-2017.10.18&amp;#34;,
[...]
&amp;#34;logstash-2017.09.10&amp;#34;,
&amp;#34;logstash-2017.10.11&amp;#34;,
&amp;#34;logstash-2017.10.09&amp;#34;
],
&amp;#34;state&amp;#34;: &amp;#34;IN_PROGRESS&amp;#34;,
&amp;#34;start_time&amp;#34;: &amp;#34;2017-10-25T18:36:07.931Z&amp;#34;,
&amp;#34;start_time_in_millis&amp;#34;: 1508956567931,
&amp;#34;end_time&amp;#34;: &amp;#34;1970-01-01T00:00:00.000Z&amp;#34;,
&amp;#34;end_time_in_millis&amp;#34;: 0,
&amp;#34;duration_in_millis&amp;#34;: -1508956567931,
&amp;#34;failures&amp;#34;: [],
&amp;#34;shards&amp;#34;: {
&amp;#34;total&amp;#34;: 0,
&amp;#34;failed&amp;#34;: 0,
&amp;#34;successful&amp;#34;: 0
}
}
]
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Le retour affiche la liste des snapshots existants (ici seulement &lt;strong&gt;snapshot_1&lt;/strong&gt; puisque c’est notre premier). On voit l’ensemble des index (sous &lt;strong&gt;indices&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;On remarque aussi que la variable &lt;em&gt;state&lt;/em&gt; à IN_PROGRESS et dans &lt;em&gt;shards&lt;/em&gt;, &lt;em&gt;successful&lt;/em&gt; est à 0.&lt;/p&gt;
&lt;p&gt;On peut surveiller l’avancement de notre snapshot avec la même commande, un peu plus tard. L’état est passé à SUCCESS.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET /_snapshot/svg/snapshot_1
{
&amp;#34;snapshots&amp;#34;: [
{
&amp;#34;snapshot&amp;#34;: &amp;#34;snapshot_1&amp;#34;,
&amp;#34;uuid&amp;#34;: &amp;#34;s38NGqRES1uZfiyHiRNJVQ&amp;#34;,
&amp;#34;version_id&amp;#34;: 5060299,
&amp;#34;version&amp;#34;: &amp;#34;5.6.2&amp;#34;,
&amp;#34;indices&amp;#34;: [
&amp;#34;logstash-2017.06.29&amp;#34;,
&amp;#34;logstash-2017.10.18&amp;#34;,
&amp;#34;logstash-2017.08.01&amp;#34;,
&amp;#34;logstash-2017.09.23&amp;#34;,
&amp;#34;logstash-2017.09.29&amp;#34;,
&amp;#34;logstash-2017.07.11&amp;#34;,
[...]
],
&amp;#34;state&amp;#34;: &amp;#34;SUCCESS&amp;#34;,
&amp;#34;start_time&amp;#34;: &amp;#34;2017-10-25T18:36:07.931Z&amp;#34;,
&amp;#34;start_time_in_millis&amp;#34;: 1508956567931,
&amp;#34;end_time&amp;#34;: &amp;#34;2017-10-25T18:46:14.231Z&amp;#34;,
&amp;#34;end_time_in_millis&amp;#34;: 1508957174231,
&amp;#34;duration_in_millis&amp;#34;: 606300,
&amp;#34;failures&amp;#34;: [],
&amp;#34;shards&amp;#34;: {
&amp;#34;total&amp;#34;: 621,
&amp;#34;failed&amp;#34;: 0,
&amp;#34;successful&amp;#34;: 621
}
}
]
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Si vous utilisez Kibana avec votre Elasticsearch, vous pouvez aussi vous passer de cURL et utiliser le menu Admin dans Kibana.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_snap01.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="restauration"&gt;Restauration
&lt;/h2&gt;&lt;p&gt;Maintenant qu’on a une sauvegarde, on est hyper contents :)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2018/07/hyper_content.gif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;De tous les indices qu’on a sauvegarder, on peut en sélectionner un (ou plusieurs), et lancer une restauration !&lt;/p&gt;
&lt;p&gt;On lancer la restauration avec une requête à l’API :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;POST /_snapshot/svg/snapshot_1/_restore
{
&amp;#34;indices&amp;#34;: &amp;#34;logstash-2017.10.21&amp;#34;,
&amp;#34;ignore_unavailable&amp;#34;: true,
&amp;#34;include_global_state&amp;#34;: true
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Et paf ! Ça ne marche pas !&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_cannot_restore_open01.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;En fait c’est normal. L’index en question est encore ouvert. Il faut le fermer pour le restaurer&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;However, an existing index can be only restored if it’s &lt;a class="link" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html" title="Open / Close Index API"
target="_blank" rel="noopener"
&gt;closed&lt;/a&gt;{.link} and has the same number of shards as the index in the snapshot. The restore operation automatically opens restored indices if they were closed and creates new indices if they didn’t exist in the cluster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;POST /logstash-2017.10.21/_close
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_cannot_restore_open02.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Et maintenant on peut lancer notre restauration !&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_restore1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Si jamais on n’a pas envie de lancer la restauration des index un par un (ce qui peut être un peu long si vous en avez beaucoup à restaurer ;-p), on peut aussi utiliser des wildcard. Par exemple, si j’ai supprimé les index des 9 premiers jours du mois d’octobre :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;POST /logstash-2017.10.0*/_close
POST /_snapshot/svg/snapshot_1/_restore
{
&amp;#34;indices&amp;#34;: &amp;#34;logstash-2017.10.0*&amp;#34;,
&amp;#34;ignore_unavailable&amp;#34;: true,
&amp;#34;include_global_state&amp;#34;: true
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_already_restore.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Une fois l’opération terminée, j’ai pu récupérer les index bêtement supprimés :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/10/elk_restored.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TADAAAAM&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="bonus--cest-pas-très-industrialisé-tout-ça-"&gt;Bonus : C’est pas très industrialisé tout ça !
&lt;/h2&gt;&lt;p&gt;Comme le fait remarquer à très juste titre &lt;strong&gt;coom&lt;/strong&gt; dans les commentaires, il existe un moyen officiel de gérer ça de façon plus industrielle =&amp;gt; via &lt;a class="link" href="https://github.com/elastic/curator" target="_blank" rel="noopener"
&gt;curator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Curator est un outil officiel d’elastic et il permet de faciliter l’administration de vos indices, et notamment la gestion des snapshots. La documentation contient également des exemples (&lt;a class="link" href="https://www.elastic.co/guide/en/elasticsearch/client/curator/current/ex_snapshot.html" target="_blank" rel="noopener"
&gt;notamment l’exemple de la gestion des snapshots justement&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Si j’ai le temps je ferai un petit article sur les capacités de Curator, qui sont nombreuses.&lt;/p&gt;</description></item><item><title>Sauvegardez vos ESXi 6.5 sans licence avec GhettoVCB</title><link>https://blog.zwindler.fr/2018/01/09/sauvegardez-vos-esxi-6-5-licence-ghettovcb/</link><pubDate>Tue, 09 Jan 2018 12:45:37 +0000</pubDate><guid>https://blog.zwindler.fr/2018/01/09/sauvegardez-vos-esxi-6-5-licence-ghettovcb/</guid><description>&lt;img src="https://blog.zwindler.fr/2017/12/Consolidation_Backup.webp" alt="Featured image of post Sauvegardez vos ESXi 6.5 sans licence avec GhettoVCB" /&gt;&lt;h2 id="ghettovcb-depuis-vmware-infrastructure-3-toujours-compatible-"&gt;GhettoVCB, depuis VMware Infrastructure 3, toujours compatible !
&lt;/h2&gt;&lt;p&gt;En 2010, &lt;a class="link" href="https://blog.zwindler.fr/2010/06/09/sauvegarder-automatiquement-et-proprement-ses-vms-sur-esxi/" &gt;un de mes tout premiers articles sur ce blog parlait d’un script s’appelant GhettoVCB&lt;/a&gt;. Il permettait de réaliser des sauvegardes à chaud sur des ESXi, SANS vCenter. Et c’est là toute la nuance, car si toutes les solutions de sauvegardes d’entreprises savent aujourd’hui sauvegarder des machines virtuelles VMware, elles se basent toutes sur un API (historiquement &lt;strong&gt;VCB&lt;/strong&gt; pour VMware Consolidated Backup).&lt;/p&gt;
&lt;p&gt;Or, &lt;a class="link" href="https://kb.vmware.com/s/article/1021175" target="_blank" rel="noopener"
&gt;l’usage l’API de sauvegarde&lt;/a&gt; (VCB, puis VADP et maintenant VMware vSphere Storage APIs – Data Protection) est conditionnée à la présence d’une licence ! Impossible d’utiliser ces outils avec un ESXi « gratuit » (free).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What licensing is required to use VMware vSphere Storage APIs – Data Protection?&lt;br&gt;
Data Protection APIs are included with all licensed vSphere editions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ce script (&lt;a class="link" href="https://communities.vmware.com/docs/DOC-8760" target="_blank" rel="noopener"
&gt;mis en ligne depuis 2008 !&lt;/a&gt;) se base directement sur les binaires présents sur l’OS, sans passer par l’API VCB. Il fait donc pratiquement la même chose, mais gratuitement. Inutile de vous dire que ce script est très populaire parmi les bidouilleurs au budget limités et souhaitant quand même faire des sauvegardes.&lt;/p&gt;
&lt;p&gt;Je vous met aussi &lt;a class="link" href="https://communities.vmware.com/docs/DOC-8760" target="_blank" rel="noopener"
&gt;le lien vers le post historique&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation
&lt;/h2&gt;&lt;p&gt;Historiquement, en guise « d’installation », il fallait simplement copier le script dans le répertoire de son choix. Aujourd’hui, c’est un peu plus « propre » puisque l’auteur a mis à disposition un VIB qui permet d’installer sur l’ESXi via un package. Les sources ont été hébergées &lt;a class="link" href="https://github.com/lamw/ghettoVCB" target="_blank" rel="noopener"
&gt;sur Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Télécharger le fichier depuis le Github (lien mort), puis le copier en SSH/SCP/SFTP dans &lt;strong&gt;/tmp&lt;/strong&gt;. Se connecter en SSH et installer la VIB :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;esxcli software vib install -v /tmp/ -f
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note : maintenant il faut le build soi même cf &lt;a class="link" href="https://github.com/lamw/ghettoVCB/blob/master/build/README.md" target="_blank" rel="noopener"
&gt;https://github.com/lamw/ghettoVCB/blob/master/build/README.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pas besoin de rebooter avec cette VIB (simple copie du script). E-Z.&lt;/p&gt;
&lt;h2 id="mise-en-place-de-la-sauvegarde"&gt;Mise en place de la sauvegarde
&lt;/h2&gt;&lt;p&gt;La documentation n’a pas été reportée sur le Github malheureusement, mais elle est toujours disponible sur &lt;a class="link" href="https://communities.vmware.com/docs/DOC-8760" target="_blank" rel="noopener"
&gt;le site historique de la communauté VMware&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dans l’exemple suivant, on va, configurer le datastore &lt;strong&gt;VMFS_BCK&lt;/strong&gt; comme destination de notre sauvegarde, sélectionner les VMs qu’on souhaite sauvegarder, et planifier (enfin&amp;hellip; crontab quoi) nos sauvegardes. Youhou !&lt;/p&gt;
&lt;p&gt;Sauf erreur de ma part, la documentation n’indique pas les chemins des fichiers scripts et de configuration. Avant c’était plus simple, vous téléchargiez tout et vous le mettiez dans le dossier que vous vouliez. Maintenant, la VIB dépose le fichier de configuration principal, un template de sauvegarde et un autre de restauration dans &lt;strong&gt;/etc/ghettovcb/&lt;/strong&gt;. Les scripts sont quant à eux installés dans &lt;strong&gt;/opt/ghettovcb/bin/&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Se connecter en SSH sur le serveur VMware concerné. Voici un exemple de configuration de sauvegarde :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /etc/ghettovcb/
vi ghettoVCB.conf
VM_BACKUP_VOLUME=/vmfs/volumes/VMFS_BCK/backup
DISK_BACKUP_FORMAT=thin
VM_BACKUP_ROTATION_COUNT=3
POWER_VM_DOWN_BEFORE_BACKUP=0
ENABLE_HARD_POWER_OFF=0
ITER_TO_WAIT_SHUTDOWN=3
POWER_DOWN_TIMEOUT=5
ENABLE_COMPRESSION=0
VM_SNAPSHOT_MEMORY=0
VM_SNAPSHOT_QUIESCE=0
ALLOW_VMS_WITH_SNAPSHOTS_TO_BE_BACKEDUP=0
SNAPSHOT_TIMEOUT=15
EMAIL_ALERT=0
EMAIL_LOG=0
EMAIL_SERVER=[@IP]
EMAIL_SERVER_PORT=25
EMAIL_DELAY_INTERVAL=1
EMAIL_TO=ghettovcb@zwindler.fr
EMAIL_ERRORS_TO=
EMAIL_FROM=alert_ghettoVCB@zwindler.fr
WORKDIR_DEBUG=0
VM_SHUTDOWN_ORDER=
VM_STARTUP_ORDER=
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ce fichier va nous permettre de configurer toutes les valeurs « par défaut » lors de nos sauvegardes.&lt;/p&gt;
&lt;p&gt;Pour éviter tout souci, vérifiez qu’il y a bien de l’espace disponible sur le datastore choisi et que le chemin existe ;-).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ls /vmfs/volumes/VMFS_BCK/backup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Chacune des valeurs contenues dans la configuration peuvent être surchargées par le fichier de sauvegarde que nous allons créer. Dans cet exemple je ne modifie rien mais là c’est à vous de voir ! Ici, j’ajoute simplement la VM à une liste des machines virtuelles à sauvegarder :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vi /etc/ghettovcb/vm_backup_list
ma_vm_a_sauvegarder
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On commence par lancer le script à la main pour voir en live si ça fonctionne :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/opt/ghettovcb/bin/ghettoVCB.sh -f /etc/ghettovcb/vm_backup_list -g /etc/ghettovcb/ghettoVCB.conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Une fois que le script rend la main, vérifier dans le dossier de destination que la sauvegarde s’est bien réalisée. Il devrait contenir un dossier daté du jour et tous les fichiers de la VM.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /vmfs/volumes/VMFS_BCK/backup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pour faire simple, vous pouvez commencer par une sauvegarde toutes les semaines (dimanche minuit) :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;crontab -e
#Sauvegarde hebdo des VMs critiques
00 0 * * 0 /opt/ghettovcb/bin/ghettoVCB.sh -f /etc/ghettovcb/vm_backup_list -g /etc/ghettovcb/ghettoVCB.conf
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="restauration"&gt;Restauration
&lt;/h2&gt;&lt;p&gt;Nous allons jouer ici le scénario d’une restauration (&lt;strong&gt;ma_vm_a_restaurer&lt;/strong&gt;) située sur le datastore &lt;strong&gt;/vmfs/volumes/VMFS&lt;/strong&gt;. Il faut donc :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mettre de côté la machine HS&lt;/li&gt;
&lt;li&gt;Trouver la sauvegarde que l’on souhaite restaurer&lt;/li&gt;
&lt;li&gt;La restaurer à l&amp;rsquo;emplacement initial de la VM&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="retirer-la-vm-à-restaurer-de-linventaire-et-garder-une-copie-au-cas-où"&gt;Retirer la VM à restaurer de l’inventaire et garder une copie au cas où
&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;vmware-cmd -s unregister ma_vm_a_restaurer
mv /vmfs/volumes/VMFS/ma_vm_a_restaurer /vmfs/volumes/VMFS/ma_vm_a_restaurer.ko
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="retrouver-la-sauvegarde-quon-souhaite-restaurer"&gt;Retrouver la sauvegarde qu’on souhaite restaurer
&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;cd /vmfs/volumes/VMFS_BCK/backup/ma_vm_a_restaurer
ls -l
drwxr-xr-x 1 root root 840 Sep 3 14:12 ma_vm_a_restaurer-2032-09-03_00-00-00
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="réaliser-la-restauration-en-elle-même"&gt;Réaliser la restauration en elle même
&lt;/h3&gt;&lt;p&gt;Ici, on fait une copie du template de restauration et on y modifie les variables comme le chemin souhaité et le datastore cible. On termine l’opération en exécutant le script &lt;strong&gt;ghettoVCB-restore.sh&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /etc/ghettovcb/
cp ghettoVCB-restore_vm_restore_configuration_template ghettoVCB-restore_ma_vm_a_sauvegarder
vi ghettoVCB-restore_ma_vm_a_restaurer
/vmfs/volumes/VMFS_BCK/backup/ma_vm_a_restaurer/ma_vm_a_restaurer-2032-09-03_00-00-00;/vmfs/volumes/VMFS;3
/opt/ghettovcb/bin/ghettoVCB-restore.sh -c /etc/ghettovcb/ghettoVCB-restore_ma_vm_a_restaurer
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="finaliser-la-restauration"&gt;Finaliser la restauration
&lt;/h3&gt;&lt;p&gt;Une fois la recopie de la sauvegarde terminée, la VM devrait réapparaitre (automatiquement) dans l’inventaire de votre serveur VMware (le script effectue le &lt;em&gt;register_vm&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Démarrer la VM. Si tout a fonctionné, la VM devrait rester bloquée et c’est « normal ».&lt;/p&gt;
&lt;p&gt;VMware va détecter qu’il y a eu une opération et vous posera la question pour savoir si c’est une copie ou déplacement. Même si dans la majorité des cas ça ne devrait pas avoir d’impact, il est préférable de répondre « I moved it »/ »Je l’ai déplacé ».&lt;/p&gt;
&lt;p&gt;Dans le cas contraire, VMware modifiera une partie de la VM, notamment son adresse MAC, ce qui n’est pas forcément souhaitable dans le cadre d’une restauration. « I moved it » permet de garder la VM telle quelle.&lt;/p&gt;
&lt;p&gt;Enjoy !&lt;/p&gt;</description></item></channel></rss>