Pods de Cassandra en estado CrashLoopBackOff

Síntoma

Los Pods de Cassandra pueden entrar en un estado CrashLoopBackOff durante la instalación o actualización de Apigee Hybrid.

Mensajes de error

El resultado de kubectl get pods cuando se ejecuta en el espacio de nombres apigee muestra uno o más 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

Causas posibles

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

Causa Descripción
Error en la resolución del nombre de host Se arroja UnknownHostException para la resolución de DNS
Imagen incorrecta Se usó una URL de imagen incorrecta en overrides.yaml
Problema de expansión Problema de conectividad con el host de origen de Cassandra
Conflicto de puertos Los puertos 7000 o 7001 ya están en uso
Misma dirección IP Ya existe un nodo con la dirección /10.10.x.x

Causa 1: Error en la resolución del nombre de host

La resolución del nombre de host para los nodos de Cassandra falla debido a problemas de configuración de DNS en el clúster. Es posible que los registros del Pod de Cassandra muestren una entrada de registro similar a la siguiente:

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

Solución

El nodo trabajador en el que se prevé que se inicie 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. Como solución alternativa, 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 usó una imagen de Cassandra incorrecta.

Diagnóstico

Revisa el archivo overrides.yaml para asegurarte de que la imagen correcta esté configurada para Cassandra. A continuación, se muestra una muestra de la estrofa 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

Solució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 el comando de instalación o actualización. Puedes usar la opción List en el script apigee-pull-push para enumerar todas las imágenes de tu repo. Luego, puedes revisar esas imágenes para asegurarte de que sean todas las imágenes de la versión prevista de Hybrid.

Causa 3: Problema de expansión

Es posible que el Pod de Cassandra no pueda conectarse al nodo semilla mientras se expande a una región nueva.

Diagnóstico

  1. Los registros del Pod 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. Verifica la conectividad entre el nodo con errores actual y el nodo semilla.
  3. Identifica el nodo semilla configurado en overrides.yaml para la región nueva. El nodo semilla se configura en overrides.yaml en el momento de la expansión de la región con el nombre de campo: multiRegionSeedHost.

    Muestra de la sección 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 verificar la conectividad entre el Pod de Cassandra con errores y el nodo semilla siguiendo las instrucciones que aparecen en Crea un contenedor de cliente para la depuración.
  5. Después de que ssh en el contenedor del cliente y tengas un shell de bash, usa telnet para verificar la conectividad del nodo actual al nodo semilla a través de los puertos 7001 y 7199.

    Comando y resultado de telnet de ejemplo que muestran la falla 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

Solución

  1. Trabaja con tu equipo de administradores de clústeres para asegurarte de que haya conectividad de red entre los nodos de Cassandra en todos los clústeres que forman parte de la misma organización.
  2. Asegúrate de que no haya reglas de firewall que bloqueen el tráfico desde el nodo con errores al nodo semilla.

Causa 4: Conflicto de puertos

Conflicto de puerto

Cassandra intentaba activarse para escuchar en los puertos 7000 y 7001, pero algún otro servicio, como ssh, ya estaba escuchando en ese puerto.

Diagnóstico

Es posible que los registros del Pod de Cassandra muestren 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 sugiere que el puerto ya está en uso.

Solución

Detén y quita cualquier servicio que no sea Cassandra y que esté escuchando en los puertos 7000 y 7001. Esto debería permitir que se ejecuten las aplicaciones de Cassandra.

Causa 5: La misma dirección IP

Existe un Pod de Cassandra anterior con la misma IP en el clúster. Esta situación puede surgir después de desinstalar Hybrid o volver a instalarlo.

Diagnóstico

  1. Revisa el archivo system.log de Cassandra para ver si aparece 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 centros de datos que aún estén 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 resultado 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

Solución

  1. Quita el nodo de Cassandra anterior con el comando nodetool remove:
    nodetool removenode HOST_ID

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

  2. Una vez que se quite el nodo de Cassandra anterior, vuelve a intentar la instalación de Hybrid.

Se debe recopilar información de diagnóstico

Si el problema persiste incluso después de seguir las instrucciones anteriores, recopila la siguiente información de diagnóstico y, luego, comunícate con Google Cloud Atención al cliente:

  1. El Google Cloud ID del proyecto.
  2. Organización de Apigee Hybrid.
  3. Los archivos overrides.yaml de las regiones nuevas y de origen, que enmascaran cualquier información sensible.
  4. Los resultados de los comandos en Apigee hybrid must-gather.