Pods de Cassandra con el estado CrashLoopBackOff

Síntoma

Los pods de Cassandra pueden pasar al estado CrashLoopBackOff durante la instalación o la actualización de Apigee hybrid.

Mensajes de error

kubectl get pods al ejecutarse en el espacio de nombres apigee muestra uno o varios pods de Cassandra en estado CrashLoopBackOff:

kubectl get pods -n apigee

NAME                          READY   STATUS            RESTARTS   AGE
apigee-cassandra-default-0    0/1     CrashLoopBackoff  0          9m

Posibles motivos

Los pods de Cassandra pueden entrar en el estado CrashLoopBackOff por varios motivos.

Causa Descripción
No se ha podido resolver el nombre de host Se ha producido una excepción UnknownHostException en la resolución de DNS.
Imagen incorrecta Se ha usado una URL de imagen incorrecta en overrides.yaml
Problema de expansión Problema de conectividad con el host de semillas de Cassandra
Conflicto de puertos El puerto 7000 o 7001 ya está en uso
Misma dirección IP Ya existe un nodo con la dirección /10.10.x.x

Causa 1: No se ha podido resolver el nombre de host

La resolución del nombre de host de los nodos de Cassandra falla debido a problemas de configuración de DNS en el clúster. Los registros de pods de Cassandra pueden mostrar una entrada de registro similar:

ERROR [main] 2025-01-12 13:23:34,569 CassandraDaemon.java:803 -
Local host name unknown: java.net.UnknownHostException: ip-xx-xx-xx-xx.example.com:
ip-xx-xx-xx-xx.example.com: Name or service not known

Resolución

El nodo de trabajo en el que se va a iniciar el pod de Cassandra debe poder resolver el nombre de host en una dirección IP válida a través del servicio DNS del clúster. Para solucionar este problema, puedes ejecutar el siguiente comando en todos los nodos de trabajo:

echo -e "\\n127.0.1.1 ${HOSTNAME}" >> "/etc/hosts"

Causa 2: Imagen incorrecta

Se ha usado una imagen de Cassandra incorrecta.

Diagnóstico

Comprueba el archivo overrides.yaml para asegurarte de que se ha configurado la imagen correcta para Cassandra. Aquí tienes un ejemplo de stanza en overrides.yaml con la imagen de Cassandra correcta.

cassandra:
  image:
    url: "gcr.io/apigee-release/hybrid/apigee-hybrid-cassandra"
    tag: "1.15.0"
    pullPolicy: IfNotPresent

Resolución

Asegúrate de que la versión y el nombre de la imagen de Cassandra sean correctos en el archivo overrides.yaml y vuelve a intentar ejecutar el comando de instalación o actualización. Puedes usar la opción Lista de la secuencia de comandos apigee-pull-push para enumerar todas las imágenes de tu repositorio. Después, puedes revisar esas imágenes para asegurarte de que son todas las imágenes de la versión de Hybrid que querías.

Causa 3: Problema de expansión

Es posible que el pod de Cassandra no pueda conectarse al nodo de inicialización al expandirse a una nueva región.

Diagnóstico

  1. Los registros de pods de Cassandra pueden mostrar entradas de registro similares a las del siguiente ejemplo:
    INFO  [main] 2024-07-28 05:25:15,662 GossipingPropertyFileSnitch.java:68 - Unable to load cassandra-topology.properties; compatibility mode disabled
    The seed provider lists no seeds.
    WARN  [main] 2024-07-28 05:25:15,703 SimpleSeedProvider.java:60 - Seed provider couldn't lookup host apigee-cassandra-default-0.apigee-cassandra-default.apigee.svc.cluster.local
    Exception (org.apache.cassandra.exceptions.ConfigurationException) encountered during startup: The seed provider lists no seeds.
    ERROR [main] 2024-07-28 05:25:15,703 CassandraDaemon.java:803 - Exception encountered during startup: The seed provider lists no seeds.
    INFO  [ScheduledTasks:1] 2024-07-28 05:25:15,833 StorageService.java:136 - Overriding RING_DELAY to 30000ms
  2. Comprueba la conectividad entre el nodo que falla y el nodo de inicio.
  3. Identifica el nodo de inicio configurado en overrides.yaml para la nueva región. El nodo de inicialización se configura en overrides.yaml en el momento de la expansión de la región en el campo multiRegionSeedHost.

    Ejemplo de stanza de Cassandra de tu overrides.yaml que muestra el multiRegionSeedHost.

    cassandra:
      multiRegionSeedHost: "1.2.X.X"
      datacenter: "dc-1"
      rack: "rc-1"
      hostNetwork: false
      clusterName: QA
  4. Crea un contenedor de cliente para comprobar la conectividad entre el pod de Cassandra que falla y el nodo de inicialización siguiendo las instrucciones de Crear un contenedor de cliente para depurar.
  5. Después de ssh en el contenedor de cliente y tener un shell bash, usa telnet para comprobar la conectividad del nodo actual al nodo de inicialización a través de los puertos 7001 y 7199.

    Ejemplo de comando de telnet y su resultado que muestra un error de conexión

    telnet 10.0.0.0 7001
    Trying 10.0.0.0...
    telnet: Unable to connect to remote host: Connection timed out
    telnet 10.0.0.0 7199
    Trying 10.0.0.0...
    telnet: Unable to connect to remote host: Connection timed out

Resolución

  1. Colabora con el equipo de administración de clústeres para asegurarte de que haya conectividad de red entre los nodos de Cassandra de todos los clústeres que formen parte de la misma organización.
  2. Asegúrate de que no haya reglas de cortafuegos que bloqueen el tráfico del nodo con errores al nodo de inicialización.

Causa 4: Conflicto de puertos

Conflicto de puertos

Cassandra intentaba conectarse para escuchar en los puertos 7000 y 7001, pero otro servicio, como SSH, ya estaba escuchando en ese puerto.

Diagnóstico

Los registros de pods de Cassandra pueden mostrar entradas similares a las del siguiente ejemplo:

Unable to create ssl socket
Fatal configuration error; unable to start server.  See log for stacktrace.
ERROR [main] 2023-02-27 13:01:54,239 CassandraDaemon.java:803 - Fatal configuration error
org.apache.cassandra.exceptions.ConfigurationException: Unable to create ssl socket
       at org.apache.cassandra.net.MessagingService.getServerSockets(MessagingService.java:701) ~[apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.net.MessagingService.listen(MessagingService.java:681) ~[apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.net.MessagingService.listen(MessagingService.java:665) ~[apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.service.StorageService.prepareToJoin(StorageService.java:831) ~[apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.service.StorageService.initServer(StorageService.java:717) ~[apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.service.StorageService.initServer(StorageService.java:666) ~[apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:395) [apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:633) [apache-cassandra-3.11.9.jar:3.11.9]
       at org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:786) [apache-cassandra-3.11.9.jar:3.11.9]
Caused by: java.net.BindException: Address already in use (Bind failed)
Caused by: java.net.BindException: Address already in use (Bind failed)

Esto indica que el puerto ya se está usando.

Resolución

Detén y elimina cualquier servicio que no sea Cassandra y que esté escuchando en los puertos 7000 y 7001. De esta forma, las aplicaciones de Cassandra deberían poder iniciarse.

Causa 5: Misma dirección IP

Hay un pod de Cassandra anterior con la misma IP en el clúster. Esta situación puede darse después de desinstalar o reinstalar Hybrid.

Diagnóstico

  1. Revisa el archivo system.log de Cassandra para comprobar si se ha producido el siguiente error:
    INFO  [HANDSHAKE-/10.106.32.131] 2020-11-30 04:28:51,432 OutboundTcpConnection.java:561 - Handshaking version with /10.10.1.1
    Exception (java.lang.RuntimeException) encountered during startup: A node with address /10.10.1.1 already exists, cancelling join. Use cassandra.replace_address if you want to replace this node.
    java.lang.RuntimeException: A node with address /10.10.1.1 already exists, cancelling join. Use cassandra.replace_address if you want to replace this node.
       at org.apache.cassandra.service.StorageService.checkForEndpointCollision(StorageService.java:558)
       at org.apache.cassandra.service.StorageService.prepareToJoin(StorageService.java:804)
       at org.apache.cassandra.service.StorageService.initServer(StorageService.java:664)
       at org.apache.cassandra.service.StorageService.initServer(StorageService.java:613)
       at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:379)
       at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:602)
       at org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:691)
    ERROR [main] 2020-11-30 04:28:52,287 CassandraDaemon.java:708 - Exception encountered during startup
    java.lang.RuntimeException: A node with address /10.10.1.1 already exists, cancelling join. Use cassandra.replace_address if you want to replace this node.
  2. Revisa el resultado del comando nodetool status de cualquiera de los controladores de dominio que sigan activos para ver si se muestra un nodo de Cassandra con la misma IP que en el mensaje de error (10.10.1.1).

    Ejemplo de salida del comando de estado de nodetool

    kubectl exec apigee-cassandra-default-0 -n  -- nodetool status
    Datacenter dc-1
    ================
    Status=Up/Down
    |/ State=Normal/Leaving/Joining/Moving
    --  Address    Load       Tokens  Owns (effective)  Host ID                               Rack
    UN  10.10.1.1  649.6 KiB  256     100.0%            4d96eaf5-7e75-4aeb-bc47-9e45fdb4b533  ra-1
    UN  10.10.1.2  885.2 KiB  256     100.0%            261a15dd-1b51-4918-a63b-551a64e74a5e  ra-1
    UN  10.10.1.3  693.74 KiB 256     100.0%            91e22ba4-fa53-4340-adaf-db32430bdda9  ra-1

Resolución

  1. Elimina el nodo de Cassandra antiguo con el comando nodetool remove:
    nodetool removenode HOST_ID

    El ID de host se puede encontrar en el resultado de nodetool status. Por ejemplo, 4d96eaf5-7e75-4aeb-bc47-9e45fdb4b533 en la salida de estado de nodetool de ejemplo anterior.

  2. Una vez que se haya eliminado el nodo de Cassandra anterior, vuelve a intentar la instalación híbrida.

Debe recoger información de diagnóstico

Si el problema persiste incluso después de seguir las instrucciones anteriores, reúne la siguiente información de diagnóstico y ponte en contacto con el Google Cloud equipo de Asistencia:

  1. El Google Cloud ID del proyecto.
  2. La organización de Apigee Hybrid.
  3. Los archivos overrides.yaml de las regiones de origen y de destino, en los que se oculta la información sensible.
  4. Los resultados de los comandos de must-gather de Apigee hybrid.