联 系 我 们
售前咨询
售后咨询
微信关注:星环科技服务号
更多联系方式 >
9.4.2 集群启动异常
更新时间:2/27/2024, 6:51:06 AM

当数据库集群出现启动故障时,可能会影响整个系统的正常运行,因此需要尽快进行故障处理。本文将介绍在面对数据库集群启动故障时,应该如何诊断和解决问题。 本章节主要包含:

  • 服务启动异常:提供服务启动异常排查手段、日志常见故障处理,以及启动异常的处理案例。

  • Pod 启动异常:介绍 Pod 生命周期的流转、Pod 异常的排查方法和排查案例。

故障排查方式
故障定位

集群启动异常,一般的表现形式如下表所示,

表 6.2.1:集群启动异常排查
异常定位 描述

检查网络连接

网络故障或通信质量较差时,会导致集群无法正常运行或启动。

检查设备硬件问题

如果集群无法启动,首先需要检查硬件是否正常工作,包括服务器、磁盘、存储等设备,是否存在故障或者故障节点。

检查配置文件

配置文件可能存在错误或者丢失,需要检查集群的配置文件是否正确,包括配置文件的路径(一般位于 /etc/<服务 ID>/conf/)、格式等是否符合规范。

检查数据库文件

数据库文件包括数据文件、控制文件、日志文件等,需要检查这些文件是否完整,是否存在损坏或者丢失的情况。

数据库版本

如果是 ArgoDB 升级后出现启动故障,需要检查是否存在版本兼容性问题,是否需要进行相关配置更改或者升级等操作。正确的升级方式,请参考《Transwarp ArgoDB 运维指南》的升级 ArgoDB 版本章节。

License 过期

当 ArgoDB 的 License 过期后,会导致集群服务无法正常启动。

数据库服务启动失败

数据库服务可能未启动或者已停止,需要检查数据库服务是否正常运行,并尝试重启数据库服务。

pod 启动失败

pod 状态不健康则会导致该 pod 对应的组件和服务无法运行,从而影响整个 ArgoDB 的可用性。关于 Pod 异常的更多信息,可以参考Pod 异常处理

排查步骤

具体排查操作,可以通过下面步骤大致确定故障原因:

  1. 首先请确认网络是否正常连接,以及集群的硬件设备是否正常。

  2. 登录 Transwarp Manager 平台。

  3. 选择仪表盘 > 集群,进入集群卡片视图。点击您需要启动的服务卡片,进入服务详情界面

  4. 在页面右上角,选择 > 查看依赖关系,查看该服务所依赖的服务名称,然后检查该服务所依赖的服务是否全部属于正常运行状态(绿色)。

    check service dependences
    图 6.2.1:查看依赖服务
  5. 点击进入配置页面,查看该服务的端口设置,然后进入集群节点中测试端口是否已经被占据。如果已被占据,则点击配置项右侧进行修改,之后重启服务。

    sudo lsof -i:<port>  #如果该端口 <port> 被占用,命令会返回正在使用该端口的进程信息。如果该端口没有被占用,命令不会有任何输出。
    复制
  6. 检查是否和 Manager 或 TOS 有关,Manager 的 master 和 agent、TOS 是否正常工作。

  7. 检查 hostname 是否正确,以 Windows 平台为例,hosts 文件的路径为 C:\Windows\System32\drivers\etc\hosts。

  8. 另外我们还可以检查对应服务的 deploy 是否正确:

    kubectl get deploy | grep <service_name>
    复制
    • 如果发现对应服务组件需要要启动的 Pod 是 0,即 k8s 不会去启动任何的 Pod,我们可以执行以下命令删除 deploy:

      kubectl delete deploy <deploy_name>
      复制
    • 若 deploy 的数目低于用户配置的节点数,则删除该服务组件的所有 deploy,再尝试重启服务。

服务启动失败案例

我们向您展示了 ArgoDB 部分服务及组件在某些场景下启动异常的处理案例:

另外,如果集群的统一管理平台 Transwarp Manager 出现无法正常访问或是其他相关异常,请参考Manager 异常章节进行处理。若仍无法解决您的问题,请联系星环技术支持人员。

TOS 启动异常

故障 1:

TOS Registry 无法启动,Docker 分区数据不可用。

排查方法:

  • 查看确保 docker 分区(/var/lib/docker/)被挂载,同时里面的数据是完好的。

  • 如果数据已经损坏,可以使用 Registry 冷备操作,将 TOS Registry 角色迁移到其他节点,具体操作步骤如下。

操作步骤:

  1. 检查环境:

    确认下新的备份的节点之前是否包含 /var/lib/registry_data/etc/tos/conf/config.yml

    确认之前节点的 registry 目录 /var/lib/registry_data 的磁盘大小;

    确认新的节点是否有分区可以挂载 /var/lib/registry_data, 如果没有查看根分区大小是否符合(建议挂载在分区目录下)。

  2. 冷备操作,手动从之前的节点中拷贝 TOS Registry 的相关文件至新的备份节点中的相同目录中

    1. Registry 文件目录: /var/lib/registry_data

    2. Registry 配置文件:/etc/tos/conf/config.yml

    3. Registry Manifest 文件:/opt/kubernetes/manifests-multi/tos-registry.manifest` 和 /opt/kubernetes/manifests-multi/tos-registryui.manifest

  3. 检查备份的 registry 是否正常工作(备份的节点)

    • docker ps -a |grep registry 对应的 container 是否都是健康状态。

    • 查看备份的节点对应的 ip:8081 是否可用。

    • docker pull 查看镜像是否可用。

      如果需要 push 镜像的话,请 push 到 2 个不同的 registry 中。

  4. 切换至冷备 registry 节点的操作如下:

    1. 在 Manager 节点执行以下命令登录 Manager 数据库:

      mysql -h localhost -u transwarp -p$(cat /etc/transwarp-manager/master/db.properties | grep io.transwarp.manager.db.password | awk -F = '{print $2}') -S /var/run/mariadb/transwarp-manager-db.sock -D transwarp_manager
      复制
    2. 查询备份 registry 节点的 id:

      select * from node;
      复制
    3. 修改 registry 角色所在的节点:

      update role set nodeId =$id where type='TOS_REGISTRY';
      复制
  5. 您也可以选择重装集群,并进行数据迁移备份。请参考:

    • 《Transwarp ArgoDB 运维指南》的备份与恢复章节

    • 《Transwarp ArgoDB 安装手册》

故障 2:

docker 服务出现问题,导致 TOS Master 的 etcd,api,controller 等容器无法正常启动

故障说明:

  1. TOS Master 状态为 not running,节点运行以下命令,查看 docker 容器的启动情况:

    docker ps | grep etcd
    docker ps | grep apiserver
    docker ps | grep scheduler
    复制

    以上服务均没有 docker container 启动。

  2. 查看 docker 服务的状态:

    systemctl status docker
    复制
  3. 查看 docker 的日志信息:

    journalctl -u docker
    复制
  4. docker 日志以及服务状态都报错:

    time="2020-01-10T15:59:01.088526607+08:00" level=error msg="Handler for GET /v1.31/images/sha256:128c9e26297acce8f97b36462f2a94042a283821761c915ed07228c815b11861/json returned error: stat /var/lib/docker/overlay2/0b338cc678565baa32fa0c82523d26eea517f0d08de7efa92b454827bfe6ad97: no such file or directory"
    复制

解决方法

docker 创建的容器是无状态的,一些状态信息(例如数据、配置文件等)其实都已经挂载进宿主机或者持久化到其他地方。

依次运行下列命令,k8s 会自动将之前的容器调度起来:

#关闭 docker 相关容器和进程
systemctl stop docker
kill  $(ps -aux|grep docker |awk '{print $2}')
kill $(ps -ef | grep docker-containerd-shim | awk '{ print $2 }')

#删除 `/var/lib/docker/` 下面容器相关的无状态信息
rm -rf /var/lib/docker/*
docker-storage-setup --reset #可跳过
docker-storage-setup #可跳过

#重启 docker 和 kubelet
systemctl restart docker
docker load -i /etc/tos/conf/tos.tar.gz
复制
HDFS 启动异常

故障 1:

在替换了许可证之后,重启 HDFS 时 NameNode 启动失败,查看其角色日志报错:

Cannot start namenode because current license does notcontain the serverkey of this node!
复制

排查方法:

  1. 首先请确定更换的许可证对应的 serverkey 本身没有问题。

  2. 然后根据服务启动失败的通用排查手段进行基础信息排查。

解决步骤:

  1. 查看 Manager 的 sk 包和 HDFS 镜像中的 sk 包版本是否一致

    1. 在 Manager 节点查看 sk 包版本:

      ll /usr/lib/transwarp-manager/common/lib/sk-*.jar
      复制
    2. 进到任意 hdfs journal 的 pod 内查看 sk 包版本

      ll /usr/lib/hadoop/lib/sk*.jar
      复制
    3. 根据上述两步可以看到 Manager 使用的 sk 包和 hdfs 镜像使用的 sk 包两个版本是不一致的。

  2. 在 Manager 节点执行脚本,将 hdfs 镜像的 sk 包版本更新为与 Manager 的一致:

    sh /usr/lib/transwarp-manager/master/scripts/serverkey/update_serverkey_version.sh
    复制
  3. 脚本运行成功之后,重启 HDFS 服务即可。

故障 2:

ArgoDB 集群断电后,有可能会导致 HDFS 服务的 NameNode 角色无法启动,NameNode 日志报错如下:

 java.io.IOException: There appears to be a gap in the edit log. We expected txid xxx, but got txid yyy.
//xxx & yyy为ID,例如 We expected txid 32382052, but got txid 32453703.
复制

故障原因:

上述错误日志一般表示该节点 NameNode 角色的元数据已损坏,需要进行修复。

解决步骤:

  1. 使用 root 用户访问到 HDFS 的 NameNode 角色所在节点。

  2. 若集群开启了 Guardian 安全,则需要进行安全认证:

    #未开启安全的集群,忽略此步骤。
    kinit hdfs:kinit hdfs/$(hostname) -kt /etc/hdfs1/hdfs.keytab
    复制
  3. 执行命令:

    hadoop namenode -recover
    复制
  4. 选择 c 继续修复。

  5. 元数据修复成功之后,再次尝试启动 HDFS 服务,NameNode 启动正常,HFDS 服务启动成功。

YARN 启动异常

故障 1:

启动服务 Yarn 时 timeline 角色启动失败,查看其角色日志报错:

Caused by: org.fusesource.leveldbjni.internal.NativeDB$DBException: Corruption: 1 missing files; e.g.: /tmp/hadoop-yarn/yarn/timeline/leveldb-timeline-store.ldb/000005.sst
复制

问题原因:

Yarn 位于 /tmp/hadoop-yarn/yarn/timeline/leveldb-timeline-store.ldb 中的临时缓存已损坏。

解决步骤:

  1. Manager 页面停止 Yarn 的 timeline 角色。

  2. 删除或备份 Yarn 的临时缓存目录:

    /tmp/hadoop-yarn/yarn/timeline/leveldb-timeline-store.ldb
    复制
  3. Manager 页面启动 Yarn 的 timeline 角色。

    该步骤将会创建一个新的缓存目录,timeline 角色也将启动成功。

故障 2:

Yarn 服务启动失败,查看启动失败角色的日志报错:

java.io.IOException: Packet len9470260 is out of range; org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /rmstore-yarn1/ZKRMStateRoot/application_XXXX
复制

说明:

  • 上述报错信息说明 Yarn 服务在启动的时候会去连接 Zookeeper 中对应 application 的 znode,但是连接失败了,导致服务启动失败。

  • 手动进入到 Zookeeper 节点中,执行 ls 或 rmr 命令的时候报了跟上述日志一样的错。

  • /rmstore-yarn1/ZKRMStateRoot/application_XXXX 是提交任务到 Yarn 上后产生的 znode 信息,任务运行完毕之后就可以删除。

  • 提交到 Yarn 上的任务太大,在 Zookeeper 中创建的 znode 超过默认的 1M 限制,因为 Zookeeper 读取数据时会加载到内存中加快读取速度,所以 znode 数据不宜过大。

解决步骤:

  1. 进入 Zookeeper 的任一 Pod 中。

    1. 首先查看 Zookeeper 的 Pod 的名称:

      kubectl get pod -owide | grep zookeeper1
      复制
    2. 进入任一 Sever 的 Pod 中:

      kubectl exec -it <Pod_name> bash
      复制
  2. 修改 /usr/lib/zookeeper/bin/zkCli.sh/usr/lib/zookeeper/bin/zkServer.sh 两个文件,调大启动命令时的堆内存限制。

    在两个文件的启动命令后面添加参数:"-Djute.maxbuffer=10485760"

  3. 再进入 Zookeeper 中,删除已经运行完毕的 application 的 znode,重启 Yarn 服务。

Zoopkeeper 启动异常

故障 1:

  • Zookeeper 无法启动,日志 /var/log/zookeeper1/zookeeper.log 中有如下报错:

  • 或 License 服务中的 Zookeeper 有角色无法启动,日志 /var/log/transwarp_license_cluster/zookeeper.log/var/log/license/zookeeper.log 中有如下报错:

ERROR org.apache.zookeeper.server.persistence.Util: [myid:35] - [main:Util@239] - Last transaction was partial.
ERROR org.apache.zookeeper.server.quorum.QuorumPeer: [myid:35] - [main:QuorumPeer@453] - Unable to load database on disk
复制

原因说明:

  • 服务器出现过重启,或是掉电重启等;

  • 根目录满导致节点服务异常,恢复文件系统后,Zookeeper 的后台任务由于突然中断进程发生锁死,无法同步数据,无法启动该节点服务。

解决步骤:

前提:Zookeeper 服务的正常节点数超过一半 (大于 N/2),否则不推荐。

  1. 根据日志报错上下文,ssh 到 Zookeeper 角色异常的节点服务器,执行如下命令:

    cd /var/zookeeper1/ && mv version-2{,.bak}
    复制

    /var/zookeeper1” 目录一般可在日志报错上下文看到, 换成实际的目录;若需要,“version-2”也换成实际目录。

  2. 登录 Manager 服务管理台,重新启动有问题的 Zookeeper 角色即可,不需要重启整个 Zookeeper 服务。

Quark 启动异常

故障 1:

JVM 机制 gc 频繁,造成 Quark executor 卡死导致异常重启。

原因说明:

  1. 查看 Quark 服务日志查看 gc 信息,设置日志级别为 INFO

    set inceptor.log.level = INFO; -- 默认为 WARNING
    复制
  2. 查看 /var/log/<quark名称>/quark-server.log 日志如下图所示,可以看见相邻两条记录中的 gcTime 间隔约 80s(正常为 60s),这就说明发生了非常严重的 gc。

    quark excutor log high gc
    图 5.2.2:Quark 服务高 gc 日志

解决步骤:

当 JVM 分配给应用程序的堆内存不足以容纳对象时,会触发频繁的 GC。所以我们需要增加 Quark executor 的内存,具体操作步骤如下:

  1. 登录 Manager,进入服务配置界面。

  2. 配置相关 memory 参数:点击右侧编辑键打开编辑弹窗进行修改。完成后点击右下角保存。

    quark excutor memery configure
    图 5.2.3:配置服务内存
  3. 点击服务菜单右上角配置服务下发配置,然后重启该服务使配置生效。

    configure service and restart
    图 5.2.4:下发配置

故障 2:

在进行 ArgoDB 升级时,executor 启动失败,Pod 报错 MaxDirectMemorySize 参数为负,参数无效。

解决方案:

升级之后的 executor 内存最低配置增加,需要调整相关参数之后,重启 Quark 服务。

Pod 启动异常处理

故障现象:

查看 Pod 状态,发现 Pod 处于 CrashLoopBackOff 多次重启失败的状态。

解决思路:

  1. 然后您可以查看 Pod 的详细信息和事件记录:

    kubectl describe pod <pod_name>
    复制
    • 包括 Pod 的启动时间、重启次数以及容器的运行日志等;

    • 查看容器使用的镜像,确认镜像是否正确、可用,或者是否存在访问权限等问题。

    • 查看 Pod 的配置,确认配置是否正确,比如资源限制是否足够、环境变量是否正确等。

  2. 查看 Pod 容器日志,确定是否在启动过程中出现了异常。

    kubectl logs <pod_name> [<container_name>]
    复制
    • <pod_name>:Pod 名称。

    • <container_name>:当一个 Pod 中存在多个容器时,需要指明具体的容器名称。

  3. 如果 Pod 日志无法定位关键性问题,那您可以查看 Pod 对应的服务日志。具体请参考服务启动异常

  4. 如果您对 Pod 相关信息进行了修改,可以删除该 Pod,然后根据定义文件重新创建一个新的 Pod 并自动重启。

    kubectl delete pod <pod_name>
    复制

    如果 Pod 的定义文件已经更新,则会使用更新后的定义文件创建新的 Pod。