故障排除

以下信息可以帮助您诊断和纠正问题。

定位和调查 Neo4j Helm chart 的问题

Neo4j Helm chart 在 Kubernetes 中的部署可以大致分为以下步骤

  1. Neo4j Pod 被创建。

  2. Neo4j Pod 被调度到特定的 Kubernetes 节点上运行。

  3. Neo4j Pod 中的所有 容器 都被创建。

  4. Neo4j Pod 中的 InitContainers 运行。

  5. Neo4j Pod 中的 容器 运行。

  6. StartupReadiness 探针被检查。

成功完成所有这些步骤后,Neo4j StatefulSet、Pod 和 Services 必须处于 ready 状态。您应该能够连接并使用您的 Neo4j 数据库。

如果 Neo4j Helm chart 已成功安装,但 Neo4j 未启动并在 Kubernetes 中达到 ready 状态,则故障排除分为两个步骤

  1. 使用 kubectl get 命令检查 Kubernetes 中资源的状态。这将确定哪个步骤失败了。

  2. 收集与该步骤相关的信息。

根据失败的步骤,您可以从 Kubernetes(例如,使用 kubectl describe)和 Neo4j 进程(例如,检查 Neo4j 调试日志)收集信息。

下表提供了简单的步骤,可帮助您开始调查 Neo4j Helm chart 部署中的问题。有关如何在 Kubernetes 中调试应用程序的更多信息,请参阅 Kubernetes 文档

表 1. 调查 Neo4j Helm chart 部署中的问题

步骤

诊断

进一步调查

Neo4j Pod 已创建

如果 kubectl get pod <release-name>-0 未返回单个 Pod 结果,则 Pod 创建存在问题。

描述 Neo4j StatefulSet — 检查 kubectl describe statefulset <release-name> 的输出。

Neo4j Pod 已调度

如果 kubectl get pod <release-name>-0 中显示的状态卡在 Pending,则 Pod 调度存在问题。

描述 Neo4j Pod kubectl describe pod <release-name>-0 并检查输出。

Neo4j Pod 中的容器已创建

如果 kubectl get pod <release-name>-0 中显示的状态卡在 Waiting,则创建或启动容器存在问题。

描述 Neo4j Pod — 检查 kubectl describe pod <release-name>-0 的输出,特别注意 Events

Neo4j Pod 中的 InitContainers

如果 kubectl get pod <release-name>-0 中显示的状态卡在 Init:(例如,Init:CrashLoopBackOffInit:Error 等),则 InitContainers 存在问题。
请注意,如果 Pod StatusPodInitializingRunning,则 InitContainers 已成功完成。

描述 Neo4j Pod — 检查 kubectl describe pod <release-name>-0 的输出,特别注意 InitContainer(注意 InitContainer 名称)和 Events。使用 kubectl logs <pod-name> -c <init-container-name> 获取 InitContainer 日志。

Neo4j Pod 中的容器正在运行

如果 kubectl get pod <release-name>-0 中显示的状态与上述任何状态都不匹配,但 Pod 仍未达到 Running 状态,则 Neo4j Pod 中运行容器存在问题。

描述 Neo4j Pod — 检查 kubectl describe pod <release-name>-0 的输出,特别注意 Container 状态(注意 Container 名称)和 Events。使用 kubectl logs <pod-name> -c <init-container-name> 获取 Container 日志。如果 Neo4j Container 正在启动但意外退出(例如,状态为 CrashLoopBackOff),请按照 Neo4j 崩溃或意外重启 的说明进行操作。

启动和就绪探针

如果 kubectl get pod <release-name>-0 中显示的状态为 Running,但 Pod 未变为 ready,则 StartupReadiness 探针存在问题。

描述 Neo4j Pod — 检查 kubectl describe pod <release-name>-0 的输出,特别注意 Events 和探针。检查 Pod 日志 kubectl logs <release-name>-0、Neo4j 日志 kubectl exec <release-name>-0 -- tail -n 100 /logs/neo4j.log 和 Neo4j 调试日志 kubectl exec <release-name>-0 -- tail -n 500 /logs/debug.log

Neo4j 崩溃或意外重启

如果 Neo4j Pod 启动后意外崩溃或重启,可能的原因有很多。已知原因包括

  • Neo4j 配置无效或不正确,导致容器启动后不久关闭。

  • Neo4j Java 进程内存不足,并以 OutOfMemoryException 退出。

  • 调度 Neo4j Pod 的 Kubernetes 节点受到干扰,例如,它正在被排空或已关闭。

  • Neo4j Pod 中的容器因使用内存超出为容器配置的资源限制而被操作系统关闭 (OOMKilled)。

  • 非常长的垃圾回收暂停导致 Neo4j Pod LivenessProbe 失败,从而导致 Kubernetes 重启 Neo4j。

OOMKILLEDOutOfMemoryException 看起来非常相似,但它们出现在不同的地方并有不同的修复方法。重要的是要意识到这一点并确保您正在处理的是什么。

以下是一些有助于排查崩溃和意外重启的检查

描述 Neo4j Pod

使用 kubectl 描述 Neo4j Pod

kubectl describe pod <release-name>-0

检查 Neo4j 容器状态

检查容器的 StateLast State。这显示了在被 OOMKilled 后重启的容器的 Last State 是如何显示的

$ kubectl describe pod neo4j-0
State:          Running
  Started:      Mon, 1 Jan 2021 00:02:00 +0000
Last State:     Terminated
  Reason:       OOMKilled
  Exit Code:    137
  Started:      Mon, 1 Jan 2021 00:00:00 +0000
  Finished:     Mon, 1 Jan 2021 00:01:00 +0000

如果 Exit Code: 137 出现在此处或其他日志中,即使不存在 "OOMKilled" 字符串,也表明是 OOMKilled

检查最近的 Events

kubectl describe 输出显示旧事件在顶部,新事件在底部。通常,您可以忽略旧事件。

一个 Killing 事件,表明 Neo4j 容器被 Kubernetes kubelet 杀死
$ kubectl describe pod neo4j-0
Events:
Type    Reason       Age      From                  Message
----    ------       ----     ----                  -------
Normal  Scheduled    6m30s    default-scheduler     Successfully assigned default/neo4j-0 to k8s-node-a
...
Normal  Killing        56s    kubelet, k8s-node-a   Killing container with id docker://neo4j-0-neo4j:Need to kill Pod

仅凭此事件日志尚不清楚 Kubernetes 为何 决定杀死 Neo4j 容器。

此示例中的下一步可能是检查

  • 容器是否被 OOMKilled

  • 容器是否未通过 LivenessStartup 探针。

  • 调查节点以查看是否存在可能导致其杀死容器的原因,例如 kubectl describe node <k8s node>

检查 Neo4j 日志和指标

Neo4j Helm chart 配置 Neo4j 以将日志和指标持久化到提供的卷上。如果没有为日志或指标显式配置卷,它们将持久化存储在 Neo4j 数据 卷上。这确保了崩溃或意外关闭的 Neo4j 实例的日志和指标输出得到保留。

从正在运行的 Neo4j Pod 收集数据

  • 使用 kubectl cp 命令从 Pod 下载所有 Neo4j 日志

    kubectl cp <neo4j-pod-name>:/logs neo4j-logs/
  • 如果为 Neo4j 启用了 CSV 指标收集(默认),则使用以下命令从 Pod 下载所有 Neo4j 指标

    kubectl cp <neo4j-pod-name>:/metrics neo4j-metrics/

从未运行的 Neo4j Pod 收集数据

如果 Neo4j Pod 未运行或崩溃过于频繁导致 kubectl cp 不可行,则应将 Neo4j 部署置于离线维护模式以收集日志和指标。

检查容器日志

主 Neo4j DBMS 进程的日志会持久化到磁盘,并可按照检查 Neo4j 日志和指标中的描述进行访问。但是,Neo4j 启动日志和 Neo4j Pod 中其他容器的日志会发送到容器的 stdoutstderr 流。这些容器日志可以使用 kubectl logs <pod name> -c <container name> 查看。

不幸的是,如果容器在崩溃或意外关闭后重启,通常 kubectl logs 显示的是新容器实例(重启后)的日志,而前一个容器实例(意外关闭的实例)的日志无法通过 kubectl logs 获取。

要捕获崩溃容器的日志,您可以尝试

  • 在连接到 Kubernetes 集群的日志收集器/聚合器(例如 Stackdriver、Cloudwatch Logs、Logstash 等)中查看容器日志。如果您使用的是托管 Kubernetes 平台,这通常默认启用。

  • 使用 kubectl logs --follow 流式传输正在运行的容器的日志,直到它再次崩溃。

© . All rights reserved.