跳到主要内容

Cluster Operator 故障排除

使用此信息来排除 RabbitMQ Cluster Kubernetes Operator 的常见问题。

请注意,以下信息可能对 Kubernetes 上的 “自己动手” (DIY) RabbitMQ 部署有所帮助,但这并非其主要关注点。

常见场景和错误

某些错误有专门的章节

RabbitMQ 集群部署失败

创建 RabbitMQ 实例后,几分钟内不可用,并且 RabbitMQ Pod 未运行。

此类失败的常见原因有

  • 集群中 CPU 或内存不足
  • imagePullSecrets 配置不正确。这会阻止从 Docker 注册表拉取镜像。
  • storageClassName 配置不正确。

解决此问题的潜在方案

  • 运行 kubectl describe pod POD-NAME 以查看是否有任何警告(例如 0/1 nodes are available: 1 Insufficient memory.
  • 更正 imagePullSecretsstorageClassName 配置。请参阅 imagePullSecrets持久化,和 更新 RabbitMQ 实例
  • 如果在更新上述配置后问题仍然存在,请按照 检查实例状态 中的步骤查看 RabbitMQ 集群资源的状态

如果部署到资源受限的集群(例如 kindminikube 等本地环境),您可能需要调整集群的 CPU 和/或 内存限制。查看 resource-limits 示例 以了解如何执行此操作。

Pod 未被创建

如下错误

pods POD-NAME is forbidden: unable to validate against any pod security policy: []

作为 Kubernetes Operator 部署的底层 ReplicaSet 的事件,或作为 RabbitmqCluster 的底层 StatefulSet 的事件。

如果为 Kubernetes 集群启用了 Pod 安全策略准入控制,但您尚未创建必要的 PodSecurityPolicy 和相应的基于角色的访问控制 (RBAC) 资源,则会发生这种情况。

潜在的解决方案是按照 Pod 安全策略 中的步骤创建 PodSecurityPolicy 和 RBAC 资源。

Pod 在启动时重启

RabbitMQ 容器可能在 Pod 启动时失败,并记录如下消息

epmd error for host rabbitmq-server-1.rabbitmq-nodes.mynamespace: nxdomain (non-existing domain)

Error during startup: {error,no_epmd_port}

Pod 重启并最终变为 Ready 状态。

由于 RabbitMQ 节点在 启动期间解析自身和对等节点主机名,CoreDNS 缓存超时可能需要从默认的 30 秒减少到 5-10 秒的范围

Pod 处于 CrashLoopBackOff 状态

由于 Kubernetes 会重启失败的 Pod,如果 RabbitMQ 节点无法启动,则很可能会进入 CrashLoopBackOff 状态 - 它尝试启动,失败并再次重启。在这种情况下,如果需要访问 Pod 或其数据才能调试或修复问题,则可能会很困难。

调试这种情况的一种方法是创建一个新的 Pod,该 Pod 不是 StatefulSet 的一部分,但挂载了相同的持久卷。这是一个 Pod 定义示例,它挂载了 RabbitMQ 节点的持久卷

apiVersion: v1
kind: Pod
metadata:
name: debug-rabbitmq
spec:
volumes:
- name: persistence
persistentVolumeClaim:
claimName: persistence-RMQ_NAME-server-2
containers:
- name: debug-rabbitmq
image: ... # you can use any image here, but for some tasks you should use the same image you use in the statefulset
command: ["/bin/sleep", "36000"]
volumeMounts:
- mountPath: /var/lib/rabbitmq/mnesia/
name: persistence

完成后,退出 Pod 并删除它。

重新创建节点

在某些情况下,必须解除节点的授权(从集群中永久删除)并替换为新节点。然后,新节点将从其对等节点同步数据。

使用 Operator 替换节点的过程如下所示

危险

以下步骤将完全删除 Pod(RabbitMQ 节点)及其磁盘。这意味着来自该节点的所有未复制数据都将丢失。请确保您了解后果。

在此示例中,我们假设要重新创建 server-2。如果要删除不同的节点,请调整命令。

  1. kubectl rabbitmq pause-reconciliation RMQ_NAME (或者如果您没有 kubectl-rabbitmq 插件/CLI,则添加标签) - 这意味着 Operator 不会 “修复”(覆盖)对底层对象的手动更改
  2. kubectl delete statefulset --cascade=orphan RMQ_NAME-server - 删除 statefulset,使其不会 “修复” Pod(在我们删除 Pod 后重新创建丢失的 Pod)
  3. kubectl delete pod RMQ_NAME-server-2 (您可以在此处删除任何您想要的 Pod)
  4. kubectl delete pvc persistence-RMQ_NAME-server-2 (如果 persistentVolumeReclaimPolicy 设置为 Delete,这将删除 PV 以及此节点上的所有数据)
  5. kubectl delete pv PV_NAME (仅当 persistentVolumeReclaimPolicy 设置为 Retain 时才需要;这将删除 PV 以及此节点上的所有数据)
  6. rabbitmqctl forget_cluster_node rabbit@RMQ_NAME-server-2.RMQ_NAME-nodes.NAMESPACE (从任何正在运行的节点)- 从集群中删除已删除的节点
  7. kubectl rabbitmq resume-reconciliation RMQ_NAME (或删除标签)- Operator 将重新创建 StatefulSet,StatefulSet 将重新创建丢失的 Pod;节点应加入集群
  8. 将仲裁队列和流扩展到新节点
    • rabbitmq-queues grow rabbit@RMQ_NAME-server-2.RMQ_NAME-nodes.NAMESPACE all
    • rabbitmq-streams add_replica STREAM_NAME rabbit@RMQ_NAME-server-2.RMQ_NAME-nodes.NAMESPACE

Pod 卡在 Terminating 状态

症状: “删除 RabbitmqCluster 实例后,某些 Pod 卡在 terminating 状态。RabbitMQ 仍在受影响的 Pod 中运行。”

原因: “可能的原因是 RabbitMQ 中残留的仲裁队列。”

解决此问题的潜在方案

  • 确保队列中没有消息,或者可以接受删除这些消息。
  • 通过运行以下命令强制删除队列
kubectl delete pod --force --grace-period=0 POD-NAME

此示例使用 Pod 名称

kubectl delete pod --force rabbit-rollout-restart-server-1
# warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
# pod 'rabbit-rollout-restart-server-1' force deleted

要通过运行以下命令查看实例的状态,请使用

kubectl -n NAMESPACE get all

其中 NAMESPACE 是实例的 Kubernetes 命名空间。

例如

kubectl -n rmq-instance-1 get all
# NAME READY STATUS RESTARTS AGE
# pod/example-server-0 1/1 Running 0 2m27s
<br/>
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/example-nodes ClusterIP None None 4369/TCP 2m27s
# service/example ClusterIP 10.111.202.183 None 5672/TCP,15672/TCP,15692/TCP 2m28s
<br/>
# NAME READY AGE
# statefulset.apps/example-server 1/1 2m28s

Cluster Operator 启动失败

部署 RabbitMQ Cluster Operator 后,它在启动期间失败,并且其 Pod 被重启。

此类失败的常见原因有

  • Operator 无法连接到 Kubernetes API。

解决此问题的潜在方案

  • 检查 Operator 是否仍在崩溃。Pod 重启解决了许多临时问题,因此重启是一种症状,而不是问题。
  • 检查 Operator 日志 (kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=rabbitmq-cluster-operator)
  • 您可能会看到如下错误
    • 获取 API Group-Resources 失败
    • Get https://ADDRESS:443/api: connect: connection refused
  • 检查您的 Kubernetes 集群是否健康,特别是 kube-apiserver 组件
  • 检查是否有任何安全网络策略可能会阻止 Operator 连接到 Kubernetes API 服务器

RabbitMQ 集群状态条件

RabbitMQ 实例具有 status.conditions,用于描述 RabbitMQ 集群的当前状态。要获取状态,请运行

kubectl describe rmq RMQ_NAME

示例状态条件可能如下所示

Name:         test-rabbit
Namespace: rabbitmq-system
API Version: rabbitmq.com/v1beta1
Kind: RabbitmqCluster
...
Status:
Binding:
Name: sample-default-user
Conditions:
Last Transition Time: 2023-07-07T11:57:10Z
Reason: AllPodsAreReady
Status: True
Type: AllReplicasReady # true when all RabbitMQ pods are 'ready'
Last Transition Time: 2023-07-07T11:57:10Z
Reason: AtLeastOneEndpointAvailable
Status: True
Type: ClusterAvailable # true when at least one RabbitMQ pod is 'ready'
Last Transition Time: 2023-07-07T11:55:58Z
Reason: NoWarnings
Status: True
Type: NoWarnings
Last Transition Time: 2023-07-07T11:57:11Z
Message: Finish reconciling
Reason: Success
Status: True
Type: ReconcileSuccess
...

如果状态条件 ReconcileSuccess 为 false,则表示上次协调出错,并且 RabbitMQ 集群配置可能已过时。查看 Cluster Operator 日志有助于了解协调失败的原因。

要获取 Operator 日志

kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=rabbitmq-cluster-operator
© . All rights reserved.