Pods do Cassandra no estado CrashLoopBackOff

Sintoma

Os pods do Cassandra podem entrar num estado CrashLoopBackOff durante a instalação ou a atualização do Apigee Hybrid.

Mensagens de erro

O resultado kubectl get pods quando executado no espaço de nomes apigee mostra um ou mais pods do Cassandra no estado CrashLoopBackOff:

kubectl get pods -n apigee

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

Causas possíveis

Os pods do Cassandra podem entrar no estado CrashLoopBackOff por vários motivos.

Causa Descrição
Falha na resolução do nome do anfitrião UnknownHostException lançada para a resolução de DNS
Imagem incorreta URL da imagem incorreto usado em overrides.yaml
Problema de expansão Problema de conetividade com o anfitrião de origem do Cassandra
Conflito de portas A porta 7000 ou 7001 já está a ser usada
O mesmo endereço IP Já existe um nó com o endereço /10.10.x.x

Causa 1: falha na resolução do nome do anfitrião

A resolução do nome do anfitrião para os nós do Cassandra falha devido a problemas de configuração de DNS no cluster. Os registos do pod do Cassandra podem apresentar uma entrada de registo semelhante:

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

Resolução

O nó de trabalho onde o pod do Cassandra está previsto ser iniciado deve conseguir resolver o nome do anfitrião para um endereço IP válido através do serviço DNS do cluster. Para uma solução alternativa, pode executar o seguinte comando em todos os nós de trabalho:

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

Causa 2: imagem incorreta

Foi usada uma imagem do Cassandra incorreta.

Diagnóstico

Verifique o ficheiro overrides.yaml para se certificar de que a imagem correta está configurada para o Cassandra. Segue-se um exemplo de uma estrofe em overrides.yaml com a imagem correta do Cassandra.

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

Resolução

Certifique-se de que a versão e o nome da imagem do Cassandra estão corretos no ficheiro overrides.yaml e tente novamente o comando de instalação ou atualização. Pode usar a opção List no script apigee-pull-push para listar todas as imagens no seu repositório. Em seguida, pode rever essas imagens para garantir que são todas as imagens da versão pretendida do Hybrid.

Causa 3: problema de expansão

O pod do Cassandra pode não conseguir estabelecer ligação ao nó inicial durante a expansão para uma nova região.

Diagnóstico

  1. Os registos do pod do Cassandra podem apresentar entradas de registo semelhantes às do exemplo seguinte:
    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. Verifique a conetividade entre o nó com falhas atual e o nó principal.
  3. Identifique o nó inicial configurado em overrides.yaml para a nova região. O nó inicial é configurado em overrides.yaml no momento da expansão da região sob o nome do campo: multiRegionSeedHost.

    Exemplo de stanza do Cassandra do seu overrides.yaml que mostra o multiRegionSeedHost.

    cassandra:
      multiRegionSeedHost: "1.2.X.X"
      datacenter: "dc-1"
      rack: "rc-1"
      hostNetwork: false
      clusterName: QA
  4. Crie um contentor de cliente para verificar a conetividade entre o pod do Cassandra com falhas e o nó de origem seguindo as instruções em Crie um contentor de cliente para depuração
  5. Depois de ssh no contentor do cliente e ter um shell bash, use o telnet para verificar a conetividade do nó atual ao nó de origem através das portas 7001 e 7199

    Exemplo de comando e saída do telnet a mostrar falha de ligação

    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

Resolução

  1. Colabore com a equipa de administração do cluster para garantir que existe conetividade de rede entre os nós do Cassandra em todos os clusters que fazem parte da mesma organização.
  2. Certifique-se de que não existem regras de firewall que bloqueiem o tráfego do nó com falhas para o nó de origem.

Causa 4: conflito de porta

Conflito de portas

O Cassandra estava a tentar ouvir na porta 7000 e 7001, mas outro serviço, como o ssh, já estava a ouvir nessa porta.

Diagnóstico

Os registos do pod do Cassandra podem apresentar entradas semelhantes às do exemplo seguinte:

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)

Isto sugere que a porta já está a ser usada.

Resolução

Pare e remova qualquer serviço que não seja o Cassandra a ouvir nas portas 7000 e 7001. Isto deve permitir que as aplicações Cassandra sejam apresentadas.

Causa 5: o mesmo endereço IP

Existe um pod do Cassandra mais antigo com o mesmo IP no cluster. Esta situação pode ocorrer após desinstalar o Hybrid ou reinstalar o Hybrid.

Diagnóstico

  1. Reveja o ficheiro system.log do Cassandra para verificar se existe o seguinte erro:
    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. Reveja o resultado do comando nodetool status de qualquer um dos DCs que ainda estejam ativos para ver se é apresentado um nó do Cassandra com o mesmo IP que na mensagem de erro: 10.10.1.1.

    Exemplo de resultado do comando nodetool status

    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

Resolução

  1. Remova o nó do Cassandra antigo com o comando nodetool remove:
    nodetool removenode HOST_ID

    Pode encontrar o ID do anfitrião no resultado do estado da ferramenta de nó. Por exemplo: 4d96eaf5-7e75-4aeb-bc47-9e45fdb4b533 na saída do estado do nodetool de exemplo anterior.

  2. Depois de remover o nó do Cassandra mais antigo, tente novamente a instalação híbrida.

Tem de recolher informações de diagnóstico

Se o problema persistir mesmo depois de seguir as instruções acima, recolha as seguintes informações de diagnóstico e, em seguida, contacte o Google Cloud apoio ao cliente:

  1. O Google Cloud ID do projeto.
  2. A organização do Apigee Hybrid.
  3. Os ficheiros overrides.yaml de ambas as regiões de origem e novas, ocultando todas as informações confidenciais.
  4. Os resultados dos comandos em Apigee hybrid must-gather.