Administrer des clusters ETCD
Suite à l’introduction de Kubernetes où j’ai décrit le fonctionnement d’un cluster Kubernetes, je vais expliquer comment administrer le composant ETCD.
Etcd, qu’est-ce-que-c’est ?
Rappel : ETCD est une base de données distribuée de type clé-valeur, qui a été développée en “Go”, le langage de programmation de Google. Dans un cluster Kubernetes, ETCD est chargé de stocker la configuration et les informations nécessaires au fonctionnement du cluster, c’est-à-dire de tous ses composants : les nœuds, les pods, les configs, les secrets, les rôles, les comptes, …
Création d’un cluster Kubernetes avec Kind
Je vais utiliser des clusters [Kubernetes créés avec l’utilitaire Kind
](nc un
parfait candidat pour se préparer aux certifications CKA. En effet, kind
intègre tous les composants contrairement à d’autres solutions comme
minikube ou k3s.
En premier créer un fichier de config pour configurer un cluster avec trois master nodes et un worker. Pourquoi trois nodes et pas deux ? Parce qu’il est fortement conseiller de mettre en place des clusters avec un nombre impair de serveurs.
kind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes: - role: control-plane - role: control-plane - role: control-plane - role: worker
Maintenant lançons la création du cluster avec la dernière version de Kubernetes (voir le lien ci-dessus) :
kind create cluster --config=cluster.yaml --name cluster-1 --image kindest/node:latest
✓ Ensuring node image (kindest/node:v1.23.1) 🖼 ✓ Preparing nodes 📦 📦 📦 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 ✓ Joining worker nodes 🚜Set kubectl context to "kind-cluster-1"You can now use your cluster with:
kubectl cluster-info --context kind-cluster-1
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
Contrôlons nos nodes :
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEcluster-1-control-plane Ready control-plane,master 83m v1.23.1 172.18.0.4 <none> Ubuntu 21.04 4.18.0-348.2.1.el8_5.x86_64 containerd://1.5.2cluster-1-control-plane2 Ready control-plane,master 83m v1.23.1 172.18.0.5 <none> Ubuntu 21.04 4.18.0-348.2.1.el8_5.x86_64 containerd://1.5.2cluster-1-control-plane3 Ready control-plane,master 82m v1.23.1 172.18.0.6 <none> Ubuntu 21.04 4.18.0-348.2.1.el8_5.x86_64 containerd://1.5.2cluster-1-worker Ready <none> 82m v1.23.1 172.18.0.3 <none> Ubuntu 21.04 4.18.0-348.2.1.el8_5.x86_64 containerd://1.5.
Contrôlons que nous avons bien un cluster ETCD :
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESkube-system coredns-64897985d-6wznk 1/1 Running 0 84m 10.244.0.2 cluster-1-control-plane <none> <none>kube-system coredns-64897985d-95x8p 1/1 Running 0 84m 10.244.0.3 cluster-1-control-plane <none> <none>kube-system etcd-cluster-1-control-plane 1/1 Running 0 84m 172.18.0.4 cluster-1-control-plane <none> <none>kube-system etcd-cluster-1-control-plane2 1/1 Running 0 84m 172.18.0.5 cluster-1-control-plane2 <none> <none>kube-system etcd-cluster-1-control-plane3 1/1 Running 0 83m 172.18.0.6 cluster-1-control-plane3 <none> <none>kube-system kindnet-fw86t 1/1 Running 0 84m 172.18.0.4 cluster-1-control-plane <none> <none>kube-system kindnet-k9mrt 1/1 Running 0 83m 172.18.0.6 cluster-1-control-plane3 <none> <none>kube-system kindnet-m4k22 1/1 Running 0 84m 172.18.0.5 cluster-1-control-plane2 <none> <none>kube-system kindnet-wmnp8 1/1 Running 0 83m 172.18.0.3 cluster-1-worker <none> <none>kube-system kube-apiserver-cluster-1-control-plane 1/1 Running 0 84m 172.18.0.4 cluster-1-control-plane <none> <none>kube-system kube-apiserver-cluster-1-control-plane2 1/1 Running 0 84m 172.18.0.5 cluster-1-control-plane2 <none> <none>kube-system kube-apiserver-cluster-1-control-plane3 1/1 Running 1 (83m ago) 83m 172.18.0.6 cluster-1-control-plane3 <none> <none>kube-system kube-controller-manager-cluster-1-control-plane 1/1 Running 1 (84m ago) 84m 172.18.0.4 cluster-1-control-plane <none> <none>kube-system kube-controller-manager-cluster-1-control-plane2 1/1 Running 0 84m 172.18.0.5 cluster-1-control-plane2 <none> <none>kube-system kube-controller-manager-cluster-1-control-plane3 1/1 Running 0 82m 172.18.0.6 cluster-1-control-plane3 <none> <none>kube-system kube-proxy-68hlh 1/1 Running 0 83m 172.18.0.3 cluster-1-worker <none> <none>kube-system kube-proxy-9ns2b 1/1 Running 0 84m 172.18.0.5 cluster-1-control-plane2 <none> <none>kube-system kube-proxy-gzfwh 1/1 Running 0 83m 172.18.0.6 cluster-1-control-plane3 <none> <none>kube-system kube-proxy-hwljt 1/1 Running 0 84m 172.18.0.4 cluster-1-control-plane <none> <none>kube-system kube-scheduler-cluster-1-control-plane 1/1 Running 1 (84m ago) 84m 172.18.0.4 cluster-1-control-plane <none> <none>kube-system kube-scheduler-cluster-1-control-plane2 1/1 Running 0 84m 172.18.0.5 cluster-1-control-plane2 <none> <none>kube-system kube-scheduler-cluster-1-control-plane3 1/1 Running 0 83m 172.18.0.6 cluster-1-control-plane3 <none> <none>local-path-storage local-path-provisioner-d6d9f7ffc-jznc9 1/1 Running 0 84m 10.244.1.2 cluster-1-control-plane2 <none> <none>
Etcd est bien installé sur les 3 nodes masters !
Affichons la configuration du cluster etcd :
kubectl describe pod etcd-cluster-1-control-plane -n kube-systemName: etcd-cluster-1-control-planeNamespace: kube-systemPriority: 2000001000Priority Class Name: system-node-criticalNode: cluster-1-control-plane/172.18.0.4Start Time: Mon, 03 Jan 2022 09:42:25 +0000Labels: component=etcd tier=control-planeAnnotations: kubeadm.kubernetes.io/etcd.advertise-client-urls: https://172.18.0.4:2379 kubernetes.io/config.hash: a6b006f7d9d8f4eb0ad9ccd08c1722ed kubernetes.io/config.mirror: a6b006f7d9d8f4eb0ad9ccd08c1722ed kubernetes.io/config.seen: 2022-01-03T09:42:03.405878931Z kubernetes.io/config.source: file seccomp.security.alpha.kubernetes.io/pod: runtime/defaultStatus: RunningIP: 172.18.0.4IPs: IP: 172.18.0.4Controlled By: Node/cluster-1-control-planeContainers: etcd: Container ID: containerd://3b604561e0d1b49f05dc124361d8e4f7ac3403f3d6326ddccc8a6da3701ecfe3 Image: k8s.gcr.io/etcd:3.5.1-0 Image ID: sha256:25f8c7f3da61c2a810effe5fa779cf80ca171afb0adf94c7cb51eb9a8546629d Port: <none> Host Port: <none> Command: etcd --advertise-client-urls=https://172.18.0.4:2379 --cert-file=/etc/kubernetes/pki/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/etcd --initial-advertise-peer-urls=https://172.18.0.4:2380 --initial-cluster=cluster-1-control-plane=https://172.18.0.4:2380 --key-file=/etc/kubernetes/pki/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://172.18.0.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://172.18.0.4:2380 --name=cluster-1-control-plane --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/etc/kubernetes/pki/etcd/peer.key --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt State: Running Started: Mon, 03 Jan 2022 09:42:07 +0000 Ready: True Restart Count: 0 Requests: cpu: 100m memory: 100Mi Liveness: http-get http://127.0.0.1:2381/health delay=10s timeout=15s period=10s #success=1 #failure=8 Startup: http-get http://127.0.0.1:2381/health delay=10s timeout=15s period=10s #success=1 #failure=24 Environment: <none> Mounts: /etc/kubernetes/pki/etcd from etcd-certs (rw) /var/lib/etcd from etcd-data (rw)Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled TrueVolumes: etcd-certs: Type: HostPath (bare host directory volume) Path: /etc/kubernetes/pki/etcd HostPathType: DirectoryOrCreate etcd-data: Type: HostPath (bare host directory volume) Path: /var/lib/etcd HostPathType: DirectoryOrCreateQoS Class: BurstableNode-Selectors: <none>Tolerations: :NoExecute op=ExistsEvents: <none>
Les informations importantes à retenir dont nous aurons besoin avec la commande etcdctl :
--cert-file=/etc/kubernetes/pki/etcd/server.crt --key-file=/etc/kubernetes/pki/etcd/server.key --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
Connexion au serveur du Control-Plane
Ici comme utilisons kind, nous nous connecterons aux nodes non pas en SSH mais avec la commande docker. En effet, les conteneurs etcd sont vraiment léger et ne possède que peu de commandes.
docker exec -it cluster-1-control-plane bashroot@cluster-1-control-plane:/#
Quelques commandes pour démarrer avec ETCD
Installation de la CLI etcdctl
Nous devons installer la CLI etcdctl sur le master node (Toutes les commandes seront lancées depuis ce node) :
docker exec -it cluster-1-control-plane bashapt updateapt install etcd-clientetcdctl --versionetcdctl version: 3.3.25
Nous utiliserons la version 3 de l’API d’ETCD :
export ETCDCTL_API=3
Contrôle de l’état de santé cluster ETCD
Dans un premier temps listons les membres du cluster ETCD :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt member list --write-out=table+------------------+---------+--------------------------+-------------------------+-------------------------+| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS |+------------------+---------+--------------------------+-------------------------+-------------------------+| 26aead55408e4ad0 | started | cluster-1-control-plane2 | https://172.18.0.5:2380 | https://172.18.0.5:2379 || 5320353a7d98bdee | started | cluster-1-control-plane | https://172.18.0.4:2380 | https://172.18.0.4:2379 || 983acdc6eb33276f | started | cluster-1-control-plane3 | https://172.18.0.6:2380 | https://172.18.0.6:2379 |+------------------+---------+--------------------------+-------------------------+-------------------------+
Nous retrouvons bien nos trois nœuds qui sont en bonne santé. Pour connaître le
leader nous allons plutôt utiliser la commande endpoint status
:
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt endpoint status --write-out=table+-----------------+------------------+---------+---------+-----------+-----------+------------+| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |+-----------------+------------------+---------+---------+-----------+-----------+------------+| 172.18.0.4:2379 | 5320353a7d98bdee | 3.5.1 | 3.2 MB | true | 3 | 28711 || 172.18.0.5:2379 | 26aead55408e4ad0 | 3.5.1 | 3.2 MB | false | 3 | 28712 || 172.18.0.6:2379 | 983acdc6eb33276f | 3.5.1 | 3.2 MB | false | 3 | 28712 |+-----------------+------------------+---------+---------+-----------+-----------+------------+
Le node 1 est le leader !
Si nous arrêtons un noeud le cluster etcd sera toujours fonctionnel. En effet, avec l’algorithme Raft nous avons droit à une défaillance sur les 3 serveurs. Si deux sont inaccessibles, le cluster passe en read-only et du coup le cluster kubernetes devient instable !
Nombre de noeuds | Tolérance de défaillance |
---|---|
1 | 0 |
2 | 0 |
3 | 1 |
4 | 1 |
5 | 2 |
6 | 2 |
Promouvoir un nœud
Il est possible à tout moment de promouvoir un nœud comme leader dans le cas ou vous devriez intervenir sur le noeud master actuel :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt move-leader 26aead55408e4ad0Leadership transferred from 5320353a7d98bdee to 26aead55408e4ad0etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt endpoint status --write-out=table+-----------------+------------------+---------+---------+-----------+-----------+------------+| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |+-----------------+------------------+---------+---------+-----------+-----------+------------+| 172.18.0.4:2379 | 5320353a7d98bdee | 3.5.1 | 3.2 MB | false | 4 | 34709 || 172.18.0.5:2379 | 26aead55408e4ad0 | 3.5.1 | 3.2 MB | true | 4 | 34709 || 172.18.0.6:2379 | 983acdc6eb33276f | 3.5.1 | 3.2 MB | false | 4 | 34709 |+-----------------+------------------+---------+---------+-----------+-----------+------------+
Faire des backups/restaurations d’etcd
Parfois en développement, nous n’utiliserons pas forcément des manifests pour gérer nos déploiements. Donc pour revenir en arrière nous pouvons utiliser des sauvegardes de la base ETCD.
Il suffit d’utiliser les commandes snapshot save
pour le backup et snapshot restore
pour la restauration :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt snapshot save /tmp/snapshot-etcd-1.db
Pour restaurer :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt snapshot restore /tmp/snapshot-etcd-1.db
Jouer avec les clés/valeurs
Ajout de clé/valeur
La commande pour ajout une clé/valeur est put
:
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt put toto test
OK
Afficher une clé/valeur
La commande pour ajout une clé/valeur est get
:
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get tototototest
Par afficher que la valeur on peut ajouter --print-value-only
et pour que la
clé --keys-only
. De même on peut demander l’affichage en json :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get toto -w json{ "header": { "cluster_id": 13122874208970910000, "member_id": 2787355801055808000, "revision": 25139, "raft_term": 3 }, "kvs": [ { "key": "dG90bw==", "create_revision": 8610, "mod_revision": 24658, "version": 2, "value": "dGVzdA==" } ], "count": 1}
Les valeurs sont codées en base64.
echo dG90bw== | base64 -dtoto
Pour afficher toutes les clés commençant par le prefix :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get --prefix tottototiti
Pour afficher tous les objets Kubernetes de la base :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get / --prefix --keys-only
...
/registry/services/specs/default/kubernetes/registry/services/specs/kube-system/kube-dns/registry/storageclasses/standard
Créer/Détruire un dossier
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt mkdir /newpath
Lister toutes les clés
Il est possible d’afficher toutes les clés d’une base avec la commande suivante :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get / --prefix --keys-only
Effacer une clé/valeur
La commande pour ajout une clé/valeur est del
:
etcdctl del toto1
Scruter les changements d’une clé
La commande watch
permet de monitorer une clé. Sur le premier nœud :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt watch toto
Dans une seconde session modifier la valeur ou détruisez-la !
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt put toto titietcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt del toto
Vous devriez voir apparaître des messages dans la première session :
etcdctl --endpoints 172.18.0.4:2379,172.18.0.5:2379,172.18.0.6:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt watch totoPUTtototitiDELETEtoto
Quelques Conseils
Les performances et la stabilité du cluster sont liés aux performances E/S réseau et disque des serveurs. Toute pénurie de ressources peut entraîner une expiration du délai de pulsation, provoquant une instabilité du cluster. Un etcd instable est un cluster ou aucun master n’est élu. Dans de telles circonstances, un cluster ne peut apporter aucune modification à son état actuel.
Il est conseillé d’installer les clusters etcd sur des machines dédiées ou des environnements isolés pour garantir les besoins en ressources.
La version minimale recommandée d’etcd à exécuter en production est 3.2.10+.