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 啟動主機
通訊埠衝突 通訊埠 7000 或 7001 已在使用中
相同的 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 可能無法連線至 Seed 節點。

診斷

  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 中的 Cassandra 節範例,顯示 multiRegionSeedHost

    cassandra:
      multiRegionSeedHost: "1.2.X.X"
      datacenter: "dc-1"
      rack: "rc-1"
      hostNetwork: false
      clusterName: QA
  4. 按照「建立用於偵錯的用戶端容器」一文中的操作說明,建立用戶端容器,檢查失敗的 Cassandra Pod 與種子節點之間的連線
  5. ssh進入用戶端容器並取得 Bash Shell 後,請使用 Telnet,透過 7001 和 7199 埠檢查目前節點與種子節點的連線狀態。

    顯示連線失敗的 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 嘗試在通訊埠 7000 和 7001 上監聽,但 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)

這表示該通訊埠已在使用中。

解決方法

停止並移除監聽通訊埠 7000 和 7001 的任何服務 (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 指令的輸出內容,確認 Cassandra 節點是否顯示與錯誤訊息中相同的 IP (10.10.1.1)。

    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 狀態的輸出內容中。例如:先前範例 nodetool 狀態輸出中的 4d96eaf5-7e75-4aeb-bc47-9e45fdb4b533

  2. 移除舊的 Cassandra 節點後,請重試 Hybrid 安裝作業。

必須收集診斷資訊

如果按照上述指示操作後問題仍未解決,請收集下列診斷資訊,然後與Google Cloud 客戶服務團隊聯絡:

  1. 專案 ID。 Google Cloud
  2. Apigee Hybrid 機構。
  3. 來源和新地區的 overrides.yaml 檔案,並遮蓋任何私密資訊。
  4. Apigee Hybrid 必須收集的指令輸出內容。