Comment utiliser Etcdctl et Etd, le magasin de clés de valeur distribuées de CoreOS

introduction

Une des technologies qui rend CoreOS possible est + etcd +, un magasin clé-valeur distribué dans le monde entier. Ce service est utilisé par les machines CoreOS individuelles pour former un cluster et comme plate-forme pour stocker des données accessibles au niveau mondial.

Dans ce guide, nous explorerons le démon + etcd + ainsi que l’utilitaire + etcdctl + et l’API HTTP / JSON pouvant être utilisés pour le contrôler.

Conditions préalables

Pour suivre ce guide, nous supposons que vous avez un groupe de machines CoreOS sur notre https://www.digitalocean.com/community/tutorials/how-to-set-up-a-coreos-cluster-on -digitalocean [mise en place d’un cluster CoreOS sur DigitalOcean]. Cela vous laissera avec trois serveurs dans un seul cluster:

  • coreos-1

  • coreos-2

  • coreos-3

Une fois que ces machines sont opérationnelles, vous pouvez continuer avec ce guide.

Etcd Cluster Discovery Model

L’une des tâches les plus fondamentales confiées à + ​​etcd + est l’organisation de machines individuelles dans un cluster. Cette opération est effectuée au démarrage de CoreOS en procédant à l’enregistrement à l’adresse de découverte fournie dans le fichier + cloud-config + qui est transmis lors de la création.

Le service de découverte exécuté par CoreOS est accessible à partir de + https: // discovery.etcd.io +. Vous pouvez obtenir un nouveau jeton en visitant la page + / new +. Vous y obtiendrez un jeton que vos machines pourront utiliser pour découvrir leurs nœuds compagnons. Cela ressemblera à quelque chose comme ça:

https://discovery.etcd.io/

Vous devez _ fournir_ un nouveau jeton pour chaque nouveau cluster. Cela inclut lorsque vous devez reconstruire le cluster à l’aide de nœuds pouvant avoir la même adresse IP. Les instances + etcd + seront gênées par cela et ne fonctionneront pas correctement pour construire le cluster si vous réutilisez l’adresse de découverte.

En visitant l’adresse de découverte dans votre navigateur Web, vous récupérerez un objet JSON décrivant les machines connues. Cela n’aura aucun nœud au début:

{"action":"get","node":{"key":"/_etcd/registry/dcadc5d4d42328488ecdcd7afae5f57c","dir":true,"modifiedIndex":102511104,"createdIndex":102511104}}

Après l’amorçage de votre cluster, vous pourrez voir plus d’informations ici:

{"action":"get","node":{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda","dir":true,"nodes":[{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/2ddbdb7c872b4bc59dd1969ac166501e","value":"http://10.132.252.38:7001","expiration":"2014-09-19T13:41:26.912303668Z","ttl":598881,"modifiedIndex":102453704,"createdIndex":102453704},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/921a7241c31a499a97d43f785108b17c","value":"http://10.132.248.118:7001","expiration":"2014-09-19T13:41:29.602508981Z","ttl":598884,"modifiedIndex":102453736,"createdIndex":102453736},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/27987f5eaac243f88ca6823b47012c5b","value":"http://10.132.248.121:7001","expiration":"2014-09-19T13:41:41.817958205Z","ttl":598896,"modifiedIndex":102453860,"createdIndex":102453860}],"modifiedIndex":101632353,"createdIndex":101632353}}

Si vous avez besoin de trouver l’URL de découverte d’un cluster, vous pouvez le faire à partir de n’importe quelle machine membre. Ces informations peuvent être extraites de la hiérarchie + / run +:

cat /run/systemd/system/etcd.service.d/20-cloudinit.conf
[Service]
Environment="ETCD_ADDR=10.132.248.118:4001"
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c"
Environment="ETCD_NAME=921a7241c31a499a97d43f785108b17c"
Environment="ETCD_PEER_ADDR=10.132.248.118:7001"

L’URL est stockée dans l’entrée + ETCD_DISCOVERY +.

Lorsque les machines qui exécutent + etcd + démarrent, elles vérifient les informations à cette URL. Il soumettra ses propres informations et requêtes sur les autres membres. Le premier nœud du cluster ne trouvera évidemment pas d’informations sur les autres nœuds, il se désignera donc comme le leader du cluster.

Les machines suivantes contacteront également l’URL de découverte avec leurs informations. Ils recevront des informations sur les machines déjà enregistrées. Ils choisiront ensuite l’une de ces machines et se connecteront directement, où ils obtiendront la liste complète des membres sains du cluster. La réplication et la distribution des données sont effectuées à l’aide de l’algorithme de consensus Raft.

Les données relatives à chacune des machines sont stockées dans une structure de répertoire cachée dans + etcd +. Vous pouvez voir les informations sur les machines que + etcd + connaît en tapant:

etcdctl ls /_etcd/machines --recursive
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
/_etcd/machines/921a7241c31a499a97d43f785108b17c
/_etcd/machines/27987f5eaac243f88ca6823b47012c5b

Les détails transmis par + etcd + aux nouveaux membres du cluster sont contenus dans ces clés. Vous pouvez voir les valeurs individuelles en demandant celles avec + etcdctl +:

etcdctl get /_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
etcd=http%3A%2F%2F10.132.252.38%3A4001&raft=http%3A%2F%2F10.132.252.38%3A7001

Nous examinerons les commandes + etcdctl + plus tard.

Etcdctl Utilisation

Il y a deux façons de base d’interagir avec + etcd +. Via l’API HTTP / JSON et un client, comme l’utilitaire + etcdctl + inclus. Nous allons commencer par «+ etcdctl +».

Affichage des clés et des répertoires

Pour commencer, regardons ce que + etcdctl + est en train de stocker. Nous pouvons voir les clés de premier niveau en tapant:

etcdctl ls /
/coreos.com

Comme vous pouvez le constater, nous avons un résultat. À ce stade, il est difficile de savoir s’il s’agit d’un répertoire ou d’une clé. Nous pouvons essayer de "+ obtenir +" le nœud pour voir la valeur de la clé ou pour voir qu’il s’agit d’un répertoire:

etcdctl get /coreos.com
/coreos.com: is a directory

Afin d’éviter ce processus manuel récursif, nous pouvons demander à + ​​etcdctl + de lister toute sa hiérarchie d’informations visibles en tapant:

etcdctl ls / --recursive
/coreos.com
/coreos.com/updateengine
/coreos.com/updateengine/rebootlock
/coreos.com/updateengine/rebootlock/semaphore

Comme vous pouvez le constater, le répertoire + / coreos.com + initial contenait de nombreux répertoires. Nous pouvons voir à quoi ça ressemble pour extraire des données réelles d’un nœud en demandant les informations au point final:

etcdctl get /coreos.com/updateengine/rebootlock/semaphore
{"semaphore":1,"max":1,"holders":null}

Cela ne contient pas d’informations qui sont très utiles pour nous. Nous pouvons obtenir des métadonnées supplémentaires sur cette entrée en passant par l’option + -o extended +. C’est une option globale, elle doit donc précéder la commande + get +:

etcdctl -o extended get /coreos.com/updateengine/rebootlock/semaphore
Key: /coreos.com/updateengine/rebootlock/semaphore
Created-Index: 6
Modified-Index: 6
TTL: 0
Etcd-Index: 170387
Raft-Index: 444099
Raft-Term: 8

{"semaphore":1,"max":1,"holders":null}

Définition de clés et création de nœuds

Pour créer un nouveau répertoire, vous pouvez utiliser la commande + mkdir + comme suit:

etcdctl mkdir /example

Pour créer une clé, vous pouvez utiliser la commande + mk +:

etcdctl mk /example/key data
data

Cela ne fonctionnera que si la clé n’existe pas déjà. Si nous demandons la valeur de la clé créée, nous pouvons récupérer les données que nous avons définies:

etcdctl get /example/key
data

Pour mettre à jour une clé existante, utilisez la commande + update:

etcdctl update /example/key turtles
turtles

La commande + updatedir + associée aux répertoires n’est probablement utile que si vous avez défini une durée de vie ou la durée de vie d’un répertoire. Cela mettra à jour le temps TTL avec celui passé. Vous pouvez définir la durée de vie des répertoires ou des clés en passant l’argument + - ttl # +, où «#» est le nombre de secondes à conserver:

etcdctl mkdir /here/you/go --ttl 120

Vous pouvez ensuite mettre à jour la durée de vie avec + updatedir +:

etcdctl updatedir /here/you/go --ttl 500

Pour modifier la valeur d’une clé existante ou pour créer une clé si elle n’existe pas, utilisez la commande + set +. Pensez-y comme une combinaison des commandes + k + et + update:

etcdctl set /example/key new
new

Cela peut inclure des chemins inexistants. Les composants de chemin seront créés dynamiquement:

etcdctl set /a/b/c here
here

Pour obtenir cette même fonctionnalité de création si les répertoires n’existent pas, vous pouvez utiliser la commande + setdir +:

etcdctl setdir /x/y/z
  • Remarque *: la commande + setdir + ne fonctionne pas actuellement comme indiqué. Dans la construction actuelle, son utilisation reflète la commande + updatedir + et échouera si le répertoire existe déjà. Il existe un problème en suspens dans le référentiel GitHub.

Supprimer des entrées

Pour supprimer des clés existantes, vous pouvez utiliser les commandes + rm + ou + rmdir +.

La commande + rm + peut être utilisée pour supprimer une clé:

etcdctl rm /a/b/c

Il peut également être utilisé de manière récursive pour supprimer un répertoire et chaque sous-répertoire:

etcdctl rm /a --recursive

Pour supprimer uniquement un répertoire vide ou une clé, utilisez la commande + rmdir +:

etcdctl rmdir /x/y/z

Cela peut être utilisé pour vous assurer que vous ne supprimez que les noeuds finaux des hiérarchies.

Surveiller les changements

Vous pouvez regarder une clé spécifique ou un répertoire entier pour les modifications. Si vous les regardez avec + etcdctl +, l’opération sera suspendue jusqu’à ce que quelque chose se produise.

Pour regarder une clé, utilisez-la sans drapeaux:

etcdctl watch /example/hello

Pour arrêter de regarder, vous pouvez appuyer sur + CTRL-C +. Si une modification est détectée pendant la surveillance, la nouvelle valeur sera renvoyée.

Pour regarder une structure de répertoire complète, utilisez l’indicateur + - recursive +:

etcdctl watch --recursive /example

Vous pouvez voir à quel point cela pourrait être utile en le plaçant dans une construction en boucle simple pour surveiller en permanence l’état des valeurs:

while true; do etcdctl watch --recursive /example; done

Si vous souhaitez exécuter une commande chaque fois qu’une modification est détectée, utilisez la commande + exec-watch +:

etcdctl exec-watch --recursive  /example -- echo "hello"

Cela fera écho “bonjour” à l’écran chaque fois qu’une valeur de ce répertoire change.

Valeurs cachées

Une chose qui n’est pas immédiatement apparente est qu’il existe des structures de répertoire cachées dans + etcd +. Ce sont des répertoires ou des clés qui commencent par un trait de soulignement.

Ceux-ci ne sont pas listés par les outils classiques + etcdctl + et vous devez savoir ce que vous recherchez pour les trouver.

Par exemple, il existe un répertoire caché appelé + / _ coreos.com + qui contient des informations internes sur + flotte +. Vous pouvez voir la hiérarchie en le demandant explicitement:

etcdctl ls --recursive /_coreos.com
/_coreos.com/fleet
/_coreos.com/fleet/states
/_coreos.com/fleet/states/[email protected]
/_coreos.com/fleet/states/[email protected]/2ddbdb7c872b4bc59dd1969ac166501e
/_coreos.com/fleet/states/[email protected]
/_coreos.com/fleet/states/[email protected]/921a7241c31a499a97d43f785108b17c
. . .

Une autre structure de répertoire de ce type se trouve dans + / _ etcd +:

etcdctl ls --recursive /_etcd
/_etcd/machines
/_etcd/machines/27987f5eaac243f88ca6823b47012c5b
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
/_etcd/machines/921a7241c31a499a97d43f785108b17c
/_etcd/config

Celles-ci fonctionnent exactement comme n’importe quelle autre entrée, la seule différence étant qu’elles n’apparaissent pas dans les listes générales. Vous pouvez les créer en commençant simplement votre clé ou le nom du répertoire par un trait de soulignement.

Etcd HTTP / JSON API Usage

L’autre façon d’interagir avec + etcd + est avec la simple API HTTP / JSON.

Pour accéder à l’API, vous pouvez utiliser un programme HTTP simple tel que + curl +. Vous devez fournir l’indicateur + -L + pour suivre les redirections renvoyées. À partir de votre cluster, vous pouvez utiliser l’interface locale + 127.0.0.1 + et le port + 4001 + pour la plupart des requêtes.

  • Remarque *: Pour vous connecter à + ​​etcd + depuis un conteneur Docker, l’adresse + http: //172.17.42.1: 4001 + peut être utilisée. Cela peut être utile aux applications pour mettre à jour leurs configurations en fonction des informations enregistrées.

Vous pouvez accéder à l’espace de clé normal en accédant à + ​​http: //127.0.0.1: 4001 / v2 / keys / + sur l’un des ordinateurs hôtes. Par exemple, pour obtenir une liste des clés / répertoires de niveau supérieur, tapez:

curl -L http://127.0.0.1:4001/v2/keys/
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"modifiedIndex":6,"createdIndex":6},{"key":"/services","dir":true,"modifiedIndex":333,"createdIndex":333}]}}

La barre oblique de fin de la demande est obligatoire. Cela ne résoudra pas correctement sans cela.

Vous pouvez définir ou récupérer des valeurs à l’aide de verbes HTTP normaux.

Pour modifier le comportement de ces opérations, vous pouvez passer des indicateurs à la fin de votre demande en utilisant la syntaxe +? Flag = valeur +. Plusieurs drapeaux peuvent être séparés par un caractère + & +.

Par exemple, pour lister toutes les clés de manière récursive, nous pourrions taper:

curl -L http://127.0.0.1:4001/v2/keys/?recursive=true
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"nodes":[{"key":"/coreos.com/updateengine","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock/semaphore","value":"{\"semaphore\":1,\"max\":1,\"holders\":null}","modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}. . .

Une autre information utile accessible en dehors de l’espace de clé normal est l’information de version, accessible ici:

curl -L http://127.0.0.1:4001/version
etcd 0.4.6

Vous pouvez afficher des statistiques sur chaque relation du chef de groupe avec chaque suiveur en visitant ce noeud final:

curl -L http://127.0.0.1:4001/v2/stats/leader
{"leader":"921a7241c31a499a97d43f785108b17c","followers":{"27987f5eaac243f88ca6823b47012c5b":{"latency":{"current":1.607038,"average":1.3762888642395448,"standardDeviation":1.4404313533578545,"minimum":0.471432,"maximum":322.728852},"counts":{"fail":0,"success":98718}},"2ddbdb7c872b4bc59dd1969ac166501e":{"latency":{"current":1.584985,"average":1.1554367141497013,"standardDeviation":0.6872303198242179,"minimum":0.427485,"maximum":31.959235},"counts":{"fail":0,"success":98723}}}}

Une opération similaire peut être utilisée pour détecter des statistiques sur la machine sur laquelle vous vous trouvez actuellement:

curl -L http://127.0.0.1:4001/v2/stats/self
{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","startTime":"2014-09-11T16:42:03.035382298Z","leaderInfo":{"leader":"921a7241c31a499a97d43f785108b17c","uptime":"1h19m11.469872568s","startTime":"2014-09-12T19:47:25.242151859Z"},"recvAppendRequestCnt":1944480,"sendAppendRequestCnt":201817,"sendPkgRate":40.403374523779064,"sendBandwidthRate":3315.096879676072}

Pour voir les statistiques sur les opérations effectuées, tapez:

curl -L http://127.0.0.1:4001/v2/stats/store
{"getsSuccess":78823,"getsFail":14,"setsSuccess":121370,"setsFail":4,"deleteSuccess":28,"deleteFail":32,"updateSuccess":20468,"updateFail":4,"createSuccess":39,"createFail":102340,"compareAndSwapSuccess":51169,"compareAndSwapFail":0,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":3,"watchers":6}

Ce ne sont là que quelques-unes des opérations qui peuvent être utilisées pour contrôler + etcd + via l’API.

Etcd Configuration

Le service + etcd + peut être configuré de différentes manières.

La première consiste à passer des paramètres avec votre fichier + cloud-config + que vous utilisez pour amorcer vos nœuds. Dans le guide d’amorçage, vous avez un peu expliqué comment procéder:

#cloud-config

coreos:
 etcd:
   discovery: https://discovery.etcd.io/
   addr: $private_ipv4:4001
   peer-addr: $private_ipv4:7001
. . .

Pour voir les options disponibles, utilisez l’indicateur + -h + avec + etcd +:

etcd -h

Pour inclure ces options dans votre + cloud-config +, il suffit de supprimer le tiret principal et de séparer les clés des valeurs avec deux points au lieu d’un signe égal. Donc + -peer-addr = <hôte: port> + devient + peer-addr: <hôte: port> +.

Lors de la lecture du fichier + cloud-config +, CoreOS les traduira en variables d’environnement dans un fichier d’unité stub utilisé pour démarrer le service.

Une autre façon de régler les paramètres de + etcd + est via l’API. Cela se fait généralement en utilisant le port + 7001 + au lieu du standard + 4001 + utilisé pour les requêtes sur les clés.

Par exemple, vous pouvez obtenir certaines des valeurs de configuration actuelles en tapant:

curl -L http://127.0.0.1:7001/v2/admin/config
{"activeSize":9,"removeDelay":1800,"syncInterval":5}

Vous pouvez modifier ces valeurs en transmettant le nouveau JSON en tant que charge utile de données avec une opération PUT:

curl -L http://127.0.0.1:7001/v2/admin/config -XPUT -d '{"activeSize":9,"removeDelay":1800,"syncInterval":5}'
{"activeSize":9,"removeDelay":1800,"syncInterval":5}

Pour obtenir une liste de machines, vous pouvez aller sur le noeud final + / v2 / admin / machines +:

curl -L http://127.0.0.1:7001/v2/admin/machines
[{"name":"27987f5eaac243f88ca6823b47012c5b","state":"follower","clientURL":"http://10.132.248.121:4001","peerURL":"http://10.132.248.121:7001"},{"name":"2ddbdb7c872b4bc59dd1969ac166501e","state":"follower","clientURL":"http://10.132.252.38:4001","peerURL":"http://10.132.252.38:7001"},{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","clientURL":"http://10.132.248.118:4001","peerURL":"http://10.132.248.118:7001"}]

Cela peut être utilisé pour supprimer des machines du cluster de manière forcée avec la méthode DELETE.

Conclusion

Comme vous pouvez le constater, + etcd + peut être utilisé pour stocker ou récupérer des informations à partir de n’importe quelle machine de votre cluster. Cela vous permet de synchroniser les données et fournit un emplacement aux services pour rechercher des données de configuration et des détails de connexion.

Cela est particulièrement utile lors de la création de systèmes distribués, car vous pouvez fournir un point de terminaison simple qui sera valide à partir de n’importe quel emplacement du cluster. En tirant parti de cette ressource, vos services peuvent se configurer de manière dynamique.