Leer el estado y reparar en 5 minutos

10 min
Público
principiante, laboratorio iniciado al menos una vez
Duración
30 min
Módulo
1/7
Competencia objetivo
diagnosticar un fallo del laboratorio en tres gestos, reconocer los doce mensajes de error clásicos y aplicar el remedio correcto sin romper los datos

En una imagen

Cuando un auto se niega a arrancar, un buen mecánico no cambia el motor: mira el tablero (¿qué luz está encendida?), escucha (¿qué ruido, en qué momento?), y solo como último recurso reinicia todo desde cero. El laboratorio se repara igual. Gesto 1, etat: el tablero, quién está corriendo, quién responde. Gesto 2, journal <service>: el ruido, las últimas cien líneas de lo que cuenta ese servicio, donde casi siempre está la frase que lo explica todo. Gesto 3, reinitialiser: el reinicio total, que borra contenedores y datos y te devuelve un laboratorio nuevo en dos minutos. Entre el gesto 2 y el gesto 3, esta lección te da un catálogo de doce fallos vistos y revistos, cada uno con su mensaje exacto, su causa y su remedio. Nueve de cada diez veces, no llegarás hasta el gesto 3.

Cómo funciona

Lo que cada gesto te dice:

GestoComandoLo que leesCuánto tiempo
1./labo.sh etat · .\labo.ps1 etatcolumna STATUS: Up … (healthy), Up … (unhealthy), Exited (137), o contenedor ausente; luego ✔/✘ por servicio y los contadores10 s
2./labo.sh journal elasticsearch (o kibana, neo4j, opensearch)últimas 100 líneas; busca ERROR, FATAL, bootstrap check, Exception1 min
3./labo.sh reinitialiser luego demarrer, importer, charger-graphepide confirmación (oui); elimina contenedores y volúmenes3 min

El gesto 3 solo toca los contenedores labo-* y los tres volúmenes labo-recherche-graphes_es-data, _neo4j-data, _os-data. Pierdes lo que hayas creado tú mismo (índice de bac à sable, tableros, nodos de prueba); los datos del curso se recargan con importer y charger-graphe.

Un journal sano, para reconocer luego un journal enfermo (tres líneas reales tomadas con journal):

text
labo-elasticsearch  | {"@timestamp":"2026-09-09T13:39:45.630Z","log.level": "INFO", "current.health":"GREEN","message":"Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[cours][0]]])." …}
labo-kibana         | [2026-09-09T13:37:16.402+00:00][INFO ][status] Kibana is now available
labo-neo4j          | 2026-09-09 13:38:32.401+0000 INFO  Started.

Elasticsearch habla en JSON (una línea por evento, campo message), Kibana en corchetes [fecha][NIVEL][módulo], Neo4j en texto. Las tres frases anteriores son las que queremos ver. Kibana también emite WARN sin gravedad (Error initializing AI assistant resources: Platinum, Enterprise or trial license needed, Error while trying to load prerelease flag): ignóralas.

Paso a paso

Los doce fallos, en orden de frecuencia en el aula. Los mensajes marcados «tomado» se reprodujeron en el laboratorio del curso; los demás se citan tal como los emiten los motores.

  1. Puerto ya en uso (tomado). demarrer falla de inmediato con:

    text
    Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint labo-elasticsearch (…): Bind for 0.0.0.0:9200 failed: port is already allocated

    Causa: otro programa ya escucha en 9200 (un Elasticsearch instalado «a mano», otro proyecto Docker), o 5601, 7474, 7687. Remedio: prerequis te dice qué puerto; encuentra al culpable (Get-NetTCPConnection -LocalPort 9200 en PowerShell, sudo ss -ltnp | grep 9200 en Linux/macOS), deténlo o, si debes conservarlo, cambia el puerto del lado del host en docker-compose.yml ("9202:9200") y adapta las direcciones del curso.

  2. Contenedor Exited (137). etat muestra labo-elasticsearch Exited (137) 2 minutes ago, y el journal se detiene sin mensaje de error. Causa: código 137 = matado por la señal 9, casi siempre el OOM killer: Docker no tiene suficiente memoria para tres JVM (Elasticsearch y Neo4j reclaman hasta 1 GB de heap cada uno, más Kibana). docker inspect labo-elasticsearch --format '{{.State.OOMKilled}}' responde true. Remedio: lección 02, paso 1 o 2: sube la memoria de Docker a 6 GB (.wslconfig luego wsl --shutdown en Windows), luego demarrer. No actives el perfil OpenSearch con menos de 6 GB.

  3. Linux: vm.max_map_count demasiado bajo. Elasticsearch (u OpenSearch) sale a los pocos segundos y su journal termina con:

    text
    bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/labo.log

    Causa: límite del kernel Linux del host, que el contenedor no puede cambiar por sí mismo. Remedio: sudo sysctl -w vm.max_map_count=262144, hazlo permanente en /etc/sysctl.conf (lección 02, paso 3), luego demarrer. En Docker Desktop (Windows, macOS), el valor ya es 262144.

  4. «Kibana server is not ready yet». La página http://localhost:5601 solo muestra esta frase. Causa: Kibana espera a Elasticsearch. O es demasiado pronto (los primeros 40 segundos), o Elasticsearch se cayó (fallo 2 o 3), y journal kibana repite Unable to retrieve version information from Elasticsearch nodes. connect ECONNREFUSED 172.x.x.x:9200. Remedio: etat. Si Elasticsearch está healthy, espera un minuto y recarga; si no, repara Elasticsearch primero, Kibana seguirá solo (restart: unless-stopped).

  5. Disco casi lleno: índices en solo lectura. Al 95 % de disco lleno, un Elasticsearch estándar registra flood stage disk watermark [95%] exceeded on […] all indices on this node will be marked read-only y cualquier escritura responde 429: cluster_block_exception … blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block]. En el laboratorio, no verás este mensaje: el compose fija cluster.routing.allocation.disk.threshold_enabled=false (verificable con GET _nodes/settings?filter_path=nodes.*.settings.cluster.routing). El riesgo que queda es no space left on device en el journal durante importer. Remedio: docker system df para medir, docker image prune para liberar, luego relanza importer.

  6. Neo4j rechaza la contraseña (tomado). En Neo4j Browser: Connection to instance failed — The client is unauthorized due to authentication failure. (detalles: Neo.ClientError.Security.Unauthorized). En etat: ✘ Neo4j ne répond pas, y en línea de comandos cypher-shell dice The client is unauthorized due to authentication failure. Causa A: error de tipeo, la contraseña es aiopsatlas2026. Causa B, más sutil: el volumen neo4j-data se creó en un inicio anterior con otra contraseña; NEO4J_AUTH solo se aplica en la primera inicialización, y el journal lo dice claramente (línea tomada): Changed password for user 'neo4j'. IMPORTANT: this change will only take effect if performed before the database is started for the first time. Remedio A: vuelve a escribirla. Remedio B: reinitialiser luego demarrer y charger-graphe.

  7. Conflicto de nombre de contenedor (tomado). demarrer falla con:

    text
    Error response from daemon: Conflict. The container name "/labo-elasticsearch" is already in use by container "a26fe0358d63…". You have to remove (or rename) that container to be able to reuse that name.

    Causa: ya existe un contenedor labo-elasticsearch que no pertenece a este proyecto Compose, típicamente porque clonaste el kit en una segunda carpeta, o lanzaste un docker run --name labo-elasticsearch a mano. Remedio: docker rm -f labo-elasticsearch (solo el contenedor, los datos del volumen permanecen), luego demarrer. Si el conflicto afecta a los cinco nombres, docker rm -f $(docker ps -aq --filter name=labo-).

  8. Git Bash reescribe las rutas /labo (tomado). En Windows, en Git Bash, un comando escrito a mano como docker compose exec -T neo4j ls /labo/cypher responde:

    text
    ls: cannot access 'C:/Program Files/Git/labo/cypher': No such file or directory

    Causa: la emulación MSYS de Git Bash convierte cualquier argumento que empiece con / en una ruta de Windows antes de pasarlo a docker. Remedio: labo.sh exporta MSYS_NO_PATHCONV=1 y MSYS2_ARG_CONV_EXCL='*' desde su segunda línea, así que todos los comandos del script están protegidos. Para tus propios comandos en Git Bash, agrégales el prefijo: MSYS_NO_PATHCONV=1 docker compose exec -T neo4j ls /labo/cypher (tomado: aparece la lista de archivos .cypher).

  9. PowerShell 5.1 e Invoke-RestMethod rompen los acentos (tomado). Envías una consulta con una palabra acentuada desde PowerShell:

    powershell
    $corps = '{"analyzer":"french","text":"déployés en production"}'
    Invoke-RestMethod -Uri http://localhost:9200/cours/_analyze -Method Post -ContentType 'application/json' -Body $corps

    PowerShell 5.1 responde Le serveur distant a retourné une erreur : (400) Demande incorrecte.; del lado de Elasticsearch la razón es x_content_parse_exception … Invalid UTF-8 middle byte 0x70. Causa: PowerShell 5.1 codifica el cuerpo en Latin-1 mientras que Elasticsearch espera UTF-8; el mismo comando en PowerShell 7 funciona. Remedio: usa Kibana Dev Tools para todas las consultas del curso (UTF-8 garantizado); el propio labo.ps1 usa curl dentro de los contenedores. Para escribir scripts de todos modos: PowerShell 7, o -Body ([System.Text.Encoding]::UTF8.GetBytes($corps)).

  10. Docker Desktop no está iniciado. Cualquier comando docker (por lo tanto prerequis, etat, demarrer) falla con:

    text
    error during connect: Get "http://%2F%2F.%2Fpipe%2FdockerDesktopLinuxEngine/v1.51/info": open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.

    (Cannot connect to the Docker daemon at unix:///var/run/docker.sock en macOS/Linux.) prerequis traduce: ✘ le démon Docker ne répond pas — lancez Docker Desktop et attendez l'icône verte. Causa: Docker Desktop cerrado, o todavía iniciando después de una sesión de Windows. Remedio: inicia Docker Desktop, espera a que el icono deje de animarse, relanza el comando. Los contenedores en restart: unless-stopped vuelven a arrancar solos.

  11. Descarga muy lenta o TLS handshake timeout. Durante == Téléchargement des images ==:

    text
    Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: TLS handshake timeout

    o failed to copy: read tcp … connection reset by peer. Causa: red saturada, wifi de escuela, proxy corporativo; las imágenes pesan de 2,5 a 2,8 GB cada una. Remedio: nada que reparar, relanza demarrer: Docker retoma las capas ya descargadas (Already exists). Detrás de un proxy, configúralo en Docker Desktop → Settings → Resources → Proxies.

  12. Volumen lleno o datos corruptos: el reinicio total. Síntomas variados: etat muestra el cluster en red, el journal de Elasticsearch habla de CorruptIndexException o de no space left on device, Neo4j se queda bloqueado en recovery tras un apagado brusco del PC, o simplemente nada tiene sentido después de una manipulación arriesgada. Remedio, el gesto 3:

    bash
    ./labo.sh reinitialiser      # responder: oui
    ./labo.sh demarrer
    ./labo.sh importer
    ./labo.sh charger-graphe
    powershell
    .\labo.ps1 reinitialiser
    .\labo.ps1 demarrer
    .\labo.ps1 importer
    .\labo.ps1 charger-graphe

    Lo que debes ver: reinitialiser ejecuta docker compose --profile opensearch down -v --remove-orphans y confirma ✔ labo remis à zéro. Las imágenes permanecen en caché: sin nueva descarga, y el siguiente trío toma dos a tres minutos. Lo que debes saber: arreter (sin -v) conserva los datos; reinitialiser los borra, es la única diferencia.

Si algo falla

  • etat no lista ningún contenedor y demarrer recrea todo cada vez → Estás lanzando el script desde una segunda copia del repositorio. Conserva una sola copia del kit y lanza siempre los comandos desde su raíz.

  • journal muestra miles de líneas JSON ilegibles → Normal para Elasticsearch. Filtra por palabras clave: en PowerShell .\labo.ps1 journal elasticsearch | Select-String 'ERROR|WARN|bootstrap', en bash ./labo.sh journal elasticsearch | grep -E 'ERROR|WARN|bootstrap'.

  • Después de reinitialiser, Kibana vuelve a mostrar «Vos données ne sont pas sécurisées» → Aviso normal de un Kibana sin seguridad; vuelve porque la configuración de Kibana se borró junto con el volumen. Haz clic en «Rejeter».

Para recordar

  • Tres gestos, siempre en este orden: etat (qué no funciona), journal <service> (por qué), reinitialiser (último recurso, borra los datos del laboratorio pero no las imágenes).
  • Los códigos que debes reconocer: Exited (137) = memoria; port is already allocated = puerto ocupado; vm.max_map_count [65530] is too low = ajuste de Linux pendiente; Neo.ClientError.Security.Unauthorized = contraseña; container name … already in use = docker rm.
  • El kit desactiva de antemano dos trampas: el umbral de disco de Elasticsearch está desactivado, y labo.sh neutraliza la conversión de rutas de Git Bash.
  • En Windows, no dejes pasar acentos por Invoke-RestMethod en PowerShell 5.1: Dev Tools y labo.ps1 se encargan de eso correctamente.
  • arreter conserva los datos, reinitialiser los borra. Los datos del curso siempre se recargan en dos comandos.

Para ir más allá

docker inspect --format '{{.State.Health.Status}}' labo-elasticsearch devuelve starting, healthy o unhealthy: es exactamente lo que lee demarrer cada tres segundos. {{json .State.Health.Log}} muestra los cinco últimos resultados del healthcheck.