Cassandra pod 处于 CrashLoopBackOff 状态

症状

在安装或升级 Apigee Hybrid 时,Cassandra Pod 可能会进入 CrashLoopBackOff 状态。

错误消息

apigee 命名空间中运行时,kubectl get pods 输出显示一个或多个处于 CrashLoopBackOff 状态的 Cassandra Pod:

kubectl get pods -n apigee

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

可能的原因

Cassandra Pod 可能会因各种原因而进入 CrashLoopBackOff 状态。

原因 说明
主机名解析失败 DNS 解析抛出 UnknownHostException
图片不正确 overrides.yaml 中使用的图片网址不正确
扩展问题 与 Cassandra 种子主机的连接问题
端口冲突 端口 7,000 或 7,001 已在使用中
相同的 IP 地址 地址为 /10.10.x.x 的节点已存在

原因 1:主机名解析失败

由于集群中的 DNS 配置问题,Cassandra 节点的主机名解析失败。Cassandra 的 Pod 日志可能会显示类似的日志条目:

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

解决方法

计划启动 Cassandra Pod 的工作器节点应能够通过集群 DNS 服务将主机名解析为有效的 IP 地址。如需暂时解决此问题,您可以在所有工作器节点上运行以下命令:

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

原因 2:映像不正确

使用的 Cassandra 映像不正确。

诊断

检查 overrides.yaml 文件,确保为 Cassandra 配置了正确的映像。以下是 overrides.yaml 中的一个示例节,其中包含正确的 Cassandra 映像。

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

解决方法

确保 overrides.yaml 文件中 Cassandra 映像的版本和名称准确无误,然后再次尝试安装或升级命令。您可以使用 apigee-pull-push 脚本中的“List”选项列出代码库中的所有映像。然后,您可以查看这些映像,确保它们都是来自预期 Hybrid 版本的映像。

原因 3:扩展问题

在扩展到新区域时,Cassandra Pod 可能无法连接到种子节点。

诊断

  1. Cassandra Pod 日志可能会显示类似于以下示例的日志条目:
    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. 检查当前发生故障的节点与种子节点之间的连接。
  3. 确定为新区域在 overrides.yaml 中配置的种子节点。在区域扩展时,在 overrides.yaml 中配置种子节点,字段名称为:multiRegionSeedHost

    overrides.yaml 中显示 multiRegionSeedHost 的 Cassandra 节示例。

    cassandra:
      multiRegionSeedHost: "1.2.X.X"
      datacenter: "dc-1"
      rack: "rc-1"
      hostNetwork: false
      clusterName: QA
  4. 按照创建用于调试的客户端容器中的说明,创建一个客户端容器,以检查出现故障的 Cassandra Pod 与种子节点之间的连接
  5. 在您 ssh 到客户端容器并拥有 bash shell 后,使用 telnet 通过端口 7,001 和 7,199 检查从当前节点到种子节点的连接

    显示连接失败的 telnet 命令和输出示例

    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

解决方法

  1. 与您的集群管理员团队协作,确保属于同一组织的所有集群中的 Cassandra 节点之间存在网络连接。
  2. 确保没有防火墙规则会阻止从故障节点到种子节点的流量。

原因 4:端口冲突

端口冲突

Cassandra 尝试启动以监听端口 7,000 和 7,001,但其他服务(例如 ssh)已在监听该端口。

诊断

Cassandra 的 Pod 日志可能会显示类似于以下示例的条目:

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)

这表明相应端口已使用。

解决方法

停止并移除监听端口 7,000 和 7,001 的任何服务(Cassandra 除外),这应该能让 Cassandra 应用启动。

原因 5:IP 地址相同

集群中存在具有相同 IP 的旧版 Cassandra Pod。这种情况可能会在卸载或重新安装 Hybrid 后出现。

诊断

  1. 检查 Cassandra 的 system.log 文件是否存在以下错误:
    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. 查看仍处于运行状态的任何 DC 的 nodetool status 命令的输出,看看是否显示了与错误消息中相同的 IP 地址 (10.10.1.1) 的 Cassandra 节点。

    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

解决方法

  1. 使用 nodetool remove 命令移除旧的 Cassandra 节点:
    nodetool removenode HOST_ID

    主机 ID 可以在 nodetool status 的输出中找到。例如:上文示例 nodetool 状态输出中的 4d96eaf5-7e75-4aeb-bc47-9e45fdb4b533

  2. 移除较旧的 Cassandra 节点后,重试 Hybrid 安装。

必须收集的诊断信息

如果按照上述说明操作后问题仍然存在,请收集以下诊断信息,然后与 Google Cloud Customer Care 联系:

  1. Google Cloud 项目 ID。
  2. Apigee Hybrid 组织。
  3. 来自来源和新区域的 overrides.yaml 文件,遮盖了任何敏感信息。
  4. Apigee Hybrid must-gather 中的命令的输出。