
当数据库集群出现启动故障时,可能会影响整个系统的正常运行,因此需要尽快进行故障处理。本文将介绍在面对数据库集群启动故障时,应该如何诊断和解决问题。 本章节主要包含:
故障排查方式
故障定位
集群启动异常,一般的表现形式如下表所示,
异常定位 | 描述 |
---|---|
检查网络连接 |
网络故障或通信质量较差时,会导致集群无法正常运行或启动。 |
检查设备硬件问题 |
如果集群无法启动,首先需要检查硬件是否正常工作,包括服务器、磁盘、存储等设备,是否存在故障或者故障节点。 |
检查配置文件 |
配置文件可能存在错误或者丢失,需要检查集群的配置文件是否正确,包括配置文件的路径(一般位于 /etc/<服务 ID>/conf/)、格式等是否符合规范。 |
检查数据库文件 |
数据库文件包括数据文件、控制文件、日志文件等,需要检查这些文件是否完整,是否存在损坏或者丢失的情况。 |
数据库版本 |
如果是 ArgoDB 升级后出现启动故障,需要检查是否存在版本兼容性问题,是否需要进行相关配置更改或者升级等操作。正确的升级方式,请参考《Transwarp ArgoDB 运维指南》的升级 ArgoDB 版本章节。 |
当 ArgoDB 的 License 过期后,会导致集群服务无法正常启动。 |
|
数据库服务可能未启动或者已停止,需要检查数据库服务是否正常运行,并尝试重启数据库服务。 |
|
pod 状态不健康则会导致该 pod 对应的组件和服务无法运行,从而影响整个 ArgoDB 的可用性。关于 Pod 异常的更多信息,可以参考Pod 异常处理。 |
排查步骤
具体排查操作,可以通过下面步骤大致确定故障原因:
-
登录 Transwarp Manager 平台。
-
选择仪表盘 > 集群,进入集群卡片视图。点击您需要启动的服务卡片,进入服务详情界面
-
在页面右上角,选择 … > 查看依赖关系,查看该服务所依赖的服务名称,然后检查该服务所依赖的服务是否全部属于正常运行状态(绿色)。
图 6.2.1:查看依赖服务 -
点击进入配置页面,查看该服务的端口设置,然后进入集群节点中测试端口是否已经被占据。如果已被占据,则点击配置项右侧进行修改,之后重启服务。
sudo lsof -i:<port> #如果该端口 <port> 被占用,命令会返回正在使用该端口的进程信息。如果该端口没有被占用,命令不会有任何输出。
复制 -
检查是否和 Manager 或 TOS 有关,Manager 的 master 和 agent、TOS 是否正常工作。
-
检查 hostname 是否正确,以 Windows 平台为例,hosts 文件的路径为 C:\Windows\System32\drivers\etc\hosts。
-
另外我们还可以检查对应服务的 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 角色迁移到其他节点,具体操作步骤如下。
操作步骤:
-
检查环境:
确认下新的备份的节点之前是否包含
/var/lib/registry_data
和/etc/tos/conf/config.yml
;确认之前节点的 registry 目录
/var/lib/registry_data
的磁盘大小;确认新的节点是否有分区可以挂载
/var/lib/registry_data
, 如果没有查看根分区大小是否符合(建议挂载在分区目录下)。 -
冷备操作,手动从之前的节点中拷贝 TOS Registry 的相关文件至新的备份节点中的相同目录中
-
Registry 文件目录: /var/lib/registry_data
-
Registry 配置文件:/etc/tos/conf/config.yml
-
Registry Manifest 文件:/opt/kubernetes/manifests-multi/tos-registry.manifest` 和 /opt/kubernetes/manifests-multi/tos-registryui.manifest
-
-
检查备份的 registry 是否正常工作(备份的节点)
-
docker ps -a |grep registry
对应的 container 是否都是健康状态。 -
查看备份的节点对应的 ip:8081 是否可用。
-
docker pull 查看镜像是否可用。
如果需要 push 镜像的话,请 push 到 2 个不同的 registry 中。
-
-
切换至冷备 registry 节点的操作如下:
-
在 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
复制 -
查询备份 registry 节点的 id:
select * from node;
复制 -
修改 registry 角色所在的节点:
update role set nodeId =$id where type='TOS_REGISTRY';
复制
-
-
您也可以选择重装集群,并进行数据迁移备份。请参考:
-
《Transwarp ArgoDB 运维指南》的备份与恢复章节
-
《Transwarp ArgoDB 安装手册》
-
故障 2:
docker 服务出现问题,导致 TOS Master 的 etcd,api,controller 等容器无法正常启动
故障说明:
-
TOS Master 状态为 not running,节点运行以下命令,查看 docker 容器的启动情况:
docker ps | grep etcd docker ps | grep apiserver docker ps | grep scheduler
复制以上服务均没有 docker container 启动。
-
查看 docker 服务的状态:
systemctl status docker
复制 -
查看 docker 的日志信息:
journalctl -u docker
复制 -
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!复制
排查方法:
-
首先请确定更换的许可证对应的 serverkey 本身没有问题。
-
然后根据服务启动失败的通用排查手段进行基础信息排查。
解决步骤:
-
查看 Manager 的 sk 包和 HDFS 镜像中的 sk 包版本是否一致
-
在 Manager 节点查看 sk 包版本:
ll /usr/lib/transwarp-manager/common/lib/sk-*.jar
复制 -
进到任意 hdfs journal 的 pod 内查看 sk 包版本
ll /usr/lib/hadoop/lib/sk*.jar
复制 -
根据上述两步可以看到 Manager 使用的 sk 包和 hdfs 镜像使用的 sk 包两个版本是不一致的。
-
-
在 Manager 节点执行脚本,将 hdfs 镜像的 sk 包版本更新为与 Manager 的一致:
sh /usr/lib/transwarp-manager/master/scripts/serverkey/update_serverkey_version.sh
复制 -
脚本运行成功之后,重启 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 角色的元数据已损坏,需要进行修复。
解决步骤:
-
使用 root 用户访问到 HDFS 的 NameNode 角色所在节点。
-
若集群开启了 Guardian 安全,则需要进行安全认证:
#未开启安全的集群,忽略此步骤。 kinit hdfs:kinit hdfs/$(hostname) -kt /etc/hdfs1/hdfs.keytab
复制 -
执行命令:
hadoop namenode -recover
复制 -
选择
c
继续修复。 -
元数据修复成功之后,再次尝试启动 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
中的临时缓存已损坏。
解决步骤:
-
Manager 页面停止 Yarn 的 timeline 角色。
-
删除或备份 Yarn 的临时缓存目录:
/tmp/hadoop-yarn/yarn/timeline/leveldb-timeline-store.ldb
复制 -
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 数据不宜过大。
解决步骤:
-
进入 Zookeeper 的任一 Pod 中。
-
首先查看 Zookeeper 的 Pod 的名称:
kubectl get pod -owide | grep zookeeper1
复制 -
进入任一 Sever 的 Pod 中:
kubectl exec -it <Pod_name> bash
复制
-
-
修改
/usr/lib/zookeeper/bin/zkCli.sh
和/usr/lib/zookeeper/bin/zkServer.sh
两个文件,调大启动命令时的堆内存限制。在两个文件的启动命令后面添加参数:
"-Djute.maxbuffer=10485760"
-
再进入 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),否则不推荐。
-
根据日志报错上下文,ssh 到 Zookeeper 角色异常的节点服务器,执行如下命令:
cd /var/zookeeper1/ && mv version-2{,.bak}
复制“
/var/zookeeper1
” 目录一般可在日志报错上下文看到, 换成实际的目录;若需要,“version-2
”也换成实际目录。 -
登录 Manager 服务管理台,重新启动有问题的 Zookeeper 角色即可,不需要重启整个 Zookeeper 服务。
Quark 启动异常
故障 1:
JVM 机制 gc 频繁,造成 Quark executor 卡死导致异常重启。
原因说明:
-
查看 Quark 服务日志查看 gc 信息,设置日志级别为 INFO
set inceptor.log.level = INFO; -- 默认为 WARNING
复制 -
查看
/var/log/<quark名称>/quark-server.log
日志如下图所示,可以看见相邻两条记录中的 gcTime 间隔约 80s(正常为 60s),这就说明发生了非常严重的 gc。图 5.2.2:Quark 服务高 gc 日志
解决步骤:
当 JVM 分配给应用程序的堆内存不足以容纳对象时,会触发频繁的 GC。所以我们需要增加 Quark executor 的内存,具体操作步骤如下:
-
登录 Manager,进入服务配置界面。
-
配置相关 memory 参数:点击右侧编辑键打开编辑弹窗进行修改。完成后点击右下角保存。
图 5.2.3:配置服务内存 -
点击服务菜单右上角配置服务下发配置,然后重启该服务使配置生效。
图 5.2.4:下发配置
故障 2:
在进行 ArgoDB 升级时,executor 启动失败,Pod 报错 MaxDirectMemorySize 参数为负,参数无效。
解决方案:
升级之后的 executor 内存最低配置增加,需要调整相关参数之后,重启 Quark 服务。
Pod 启动异常处理
故障现象:
查看 Pod 状态,发现 Pod 处于 CrashLoopBackOff 多次重启失败的状态。
解决思路:
-
然后您可以查看 Pod 的详细信息和事件记录:
kubectl describe pod <pod_name>
复制-
包括 Pod 的启动时间、重启次数以及容器的运行日志等;
-
查看容器使用的镜像,确认镜像是否正确、可用,或者是否存在访问权限等问题。
-
查看 Pod 的配置,确认配置是否正确,比如资源限制是否足够、环境变量是否正确等。
-
-
查看 Pod 容器日志,确定是否在启动过程中出现了异常。
kubectl logs <pod_name> [<container_name>]
复制-
<pod_name>:Pod 名称。
-
<container_name>:当一个 Pod 中存在多个容器时,需要指明具体的容器名称。
-
-
如果 Pod 日志无法定位关键性问题,那您可以查看 Pod 对应的服务日志。具体请参考服务启动异常。
-
如果您对 Pod 相关信息进行了修改,可以删除该 Pod,然后根据定义文件重新创建一个新的 Pod 并自动重启。
kubectl delete pod <pod_name>
复制如果 Pod 的定义文件已经更新,则会使用更新后的定义文件创建新的 Pod。