<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>REST on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/rest/</link><description>Recent content in REST on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Wed, 04 Jul 2018 11:45:55 +0000</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/rest/index.xml" rel="self" type="application/rss+xml"/><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></channel></rss>