|
Este documento ha sido traducido utilizando tecnología de traducción automática. Si bien nos esforzamos por proporcionar traducciones precisas, no ofrecemos garantías sobre la integridad, precisión o confiabilidad del contenido traducido. En caso de discrepancia, la versión original en inglés prevalecerá y constituirá el texto autorizado. |
Solución de problemas de nodos etcd
Esta sección contiene comandos y consejos para solucionar problemas en nodos con el rol de etcd.
Comprobando si el contenedor etcd está en funcionamiento
El contenedor de etcd debería tener el estado En marcha. La duración mostrada después de Up es el tiempo que el contenedor ha estado en ejecución.
docker ps -a -f=name=etcd$
Resultado de ejemplo:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d26adbd23643 rancher/mirrored-coreos-etcd:v3.5.7 "/usr/local/bin/etcd…" 30 minutes ago Up 30 minutes etcd
Registro del contenedor etcd
El registro del contenedor puede contener información sobre cuál podría ser el problema.
docker logs etcd
| Registro | Explicación |
|---|---|
|
No se puede establecer una conexión con la dirección mostrada en el puerto 2380. Verifica si el contenedor etcd está en funcionamiento en el host con la dirección mostrada. |
|
El clúster etcd ha perdido su quórum y está intentando establecer un nuevo líder. Esto puede suceder cuando la mayoría de los nodos que ejecutan etcd se caen o son inalcanzables. |
|
El cortafuegos del host está impidiendo la comunicación de red. |
|
El nodo cuya instancia etcd registra |
|
El estado del clúster ( |
Comprobaciones del clúster etcd y conectividad
La dirección donde etcd escucha depende de la configuración de dirección del host en el que se está ejecutando etcd. Si se ha configurado una dirección interna para el host en el que se está ejecutando etcd, el punto final para etcdctl debe especificarse explícitamente. Si alguno de los comandos responde con Error: context deadline exceeded, la instancia etcd no está saludable (ya sea que se haya perdido el quórum o que la instancia no esté correctamente unida al clúster)
Verifica los miembros de etcd en todos los nodos
La salida debería contener todos los nodos con el rol de etcd y la salida debería ser idéntica en todos los nodos.
Comando:
docker exec etcd etcdctl member list
Comprobar el estado del endpoint
Los valores para RAFT TERM deben ser iguales y RAFT INDEX no deben estar demasiado alejados entre sí.
Comando:
docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl endpoint status --write-out table
Resultado de ejemplo:
+-----------------+------------------+---------+---------+-----------+-----------+------------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | +-----------------+------------------+---------+---------+-----------+-----------+------------+ | https://IP:2379 | 333ef673fc4add56 | 3.5.7 | 24 MB | false | 72 | 66887 | | https://IP:2379 | 5feed52d940ce4cf | 3.5.7 | 24 MB | true | 72 | 66887 | | https://IP:2379 | db6b3bdb559a848d | 3.5.7 | 25 MB | false | 72 | 66887 | +-----------------+------------------+---------+---------+-----------+-----------+------------+
Comprobar la salud del endpoint
Comando:
docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl endpoint health
Resultado de ejemplo:
https://IP:2379 is healthy: successfully committed proposal: took = 2.113189ms https://IP:2379 is healthy: successfully committed proposal: took = 2.649963ms https://IP:2379 is healthy: successfully committed proposal: took = 2.451201ms
Comprobar la conectividad en el puerto TCP/2379
Comando:
for endpoint in $(docker exec etcd etcdctl member list | cut -d, -f5); do
echo "Validating connection to ${endpoint}/health"
docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl -s -w "\n" --cacert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CACERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --cert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --key $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_KEY" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) "${endpoint}/health"
done
Resultado de ejemplo:
Validating connection to https://IP:2379/health
{"health": "true"}
Validating connection to https://IP:2379/health
{"health": "true"}
Validating connection to https://IP:2379/health
{"health": "true"}
Comprobar la conectividad en el puerto TCP/2380
Comando:
for endpoint in $(docker exec etcd etcdctl member list | cut -d, -f4); do
echo "Validating connection to ${endpoint}/version";
docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl --http1.1 -s -w "\n" --cacert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CACERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --cert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --key $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_KEY" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) "${endpoint}/version"
done
Resultado de ejemplo:
Validating connection to https://IP:2380/version
{"etcdserver":"3.5.7","etcdcluster":"3.5.0"}
Validating connection to https://IP:2380/version
{"etcdserver":"3.5.7","etcdcluster":"3.5.0"}
Validating connection to https://IP:2380/version
{"etcdserver":"3.5.7","etcdcluster":"3.5.0"}
Alarmas de etcd
etcd activará alarmas, por ejemplo, cuando se quede sin espacio.
Comando:
docker exec etcd etcdctl alarm list
Salida de ejemplo cuando se activa la alarma NOSPACE:
memberID:x alarm:NOSPACE memberID:x alarm:NOSPACE memberID:x alarm:NOSPACE
Errores de espacio de etcd
Los mensajes de error relacionados son etcdserver: mvcc: database space exceeded o applying raft message exceeded backend quota. Se activará la alarma NOSPACE.
Resoluciones:
Compactar el espacio de claves
Comando:
rev=$(docker exec etcd etcdctl endpoint status --write-out json | egrep -o '"revision":[0-9]*' | egrep -o '[0-9]*') docker exec etcd etcdctl compact "$rev"
Resultado de ejemplo:
compacted revision xxx
Desfragmentar todos los miembros de etcd
Comando:
docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl defrag
Resultado de ejemplo:
Finished defragmenting etcd member[https://IP:2379] Finished defragmenting etcd member[https://IP:2379] Finished defragmenting etcd member[https://IP:2379]
Comprobar el estado del endpoint
Comando:
docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl endpoint status --write-out table
Resultado de ejemplo:
+-----------------+------------------+---------+---------+-----------+-----------+------------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | +-----------------+------------------+---------+---------+-----------+-----------+------------+ | https://IP:2379 | e973e4419737125 | 3.5.7 | 553 kB | false | 32 | 2449410 | | https://IP:2379 | 4a509c997b26c206 | 3.5.7 | 553 kB | false | 32 | 2449410 | | https://IP:2379 | b217e736575e9dd3 | 3.5.7 | 553 kB | true | 32 | 2449410 | +-----------------+------------------+---------+---------+-----------+-----------+------------+
Desactivar alarma
Después de verificar que el tamaño de la base de datos ha disminuido tras la compactación y desfragmentación, la alarma debe ser desactivada para que etcd permita escribir de nuevo.
Comando:
docker exec etcd etcdctl alarm list docker exec etcd etcdctl alarm disarm docker exec etcd etcdctl alarm list
Resultado de ejemplo:
docker exec etcd etcdctl alarm list memberID:x alarm:NOSPACE memberID:x alarm:NOSPACE memberID:x alarm:NOSPACE docker exec etcd etcdctl alarm disarm docker exec etcd etcdctl alarm list
Configurar el nivel de registro
|
Ya no se puede cambiar dinámicamente el nivel de registro en etcd v3.5 o posterior. |
etcd v3.5 y posterior
Para configurar el nivel de registro de etcd, edita el YAML del clúster:
services:
etcd:
extra_args:
log-level: "debug"
etcd v3.4 y anterior
En versiones anteriores de etcd, puedes usar la API para cambiar dinámicamente el nivel de registro. Configura el registro de depuración utilizando los comandos a continuación:
docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl -s -XPUT -d '{"Level":"DEBUG"}' --cacert $(docker exec etcd printenv ETCDCTL_CACERT) --cert $(docker exec etcd printenv ETCDCTL_CERT) --key $(docker exec etcd printenv ETCDCTL_KEY) $(docker exec etcd printenv ETCDCTL_ENDPOINTS)/config/local/log
Para restablecer el nivel de registro a su valor predeterminado (INFO), puedes usar el siguiente comando.
Comando:
docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl -s -XPUT -d '{"Level":"INFO"}' --cacert $(docker exec etcd printenv ETCDCTL_CACERT) --cert $(docker exec etcd printenv ETCDCTL_CERT) --key $(docker exec etcd printenv ETCDCTL_KEY) $(docker exec etcd printenv ETCDCTL_ENDPOINTS)/config/local/log
Contenido de etcd
Si deseas investigar el contenido de tu etcd, puedes observar eventos en streaming o puedes consultar etcd directamente, consulta a continuación los ejemplos.
Observar eventos en streaming
Comando:
docker exec etcd etcdctl watch --prefix /registry
Si solo deseas ver las claves afectadas (y no los datos binarios), puedes añadir | grep -a ^/registry al comando para filtrar solo por claves.
Consultar etcd directamente
Comando:
docker exec etcd etcdctl get /registry --prefix=true --keys-only
Puedes procesar los datos para obtener un resumen del conteo por clave, utilizando el comando a continuación:
docker exec etcd etcdctl get /registry --prefix=true --keys-only | grep -v ^$ | awk -F'/' '{ if ($3 ~ /cattle.io/) {h[$3"/"$4]++} else { h[$3]++ }} END { for(k in h) print h[k], k }' | sort -nr