1、故障描述
因为维护原因,需要重启Nutanix集群一个节点的CVM,该集群的控制平台(Prism管理平台)也部署在该节点。节点重启后控制平台无法登陆。登陆该cvm节点查看,发现很多服务都没有启动。
2、初步分析
通过登陆集群的其它cvm主机,执行命令查看节点状态:
#cluster status
...
CVM: 10.1.8.148 Down
...
确认该节点没有启动。 再在故障cvm执行命令查看服务状态
gs
2024-03-01 18:34:25.341466: Services running on this node:
acropolis: []
alert_manager: []
aplos: []
aplos_engine: []
arithmos: []
cassandra: []
catalog: []
cerebro: []
chronos: []
cim_service: []
cluster_config: []
cluster_health: []
curator: []
delphi: []
dynamic_ring_changer: []
ergon: []
foundation: []
genesis: [28325, 28338, 28361, 28362]
hera: []
...
发现只有genesis的进程,其它服务的进程都没启动。
尝试通过重启cvm和执行 genesis restart 命令重启,还是一样。
重启大法无效,看来只能分析日志看看。
查看genesis日志,发现出现下面这个报错后就不再输出了:
2024-03-01 17:32:34 ERROR node_manager.py:4791 Failed to set up key based SSH access to hypervisor, most likely because we do not have the correct password cached. Please run fix_host_ssh command manually to fix this problem.
从日志看是ssh认证出了问题,提示我们执行fix_host_ssh去修复。执行这个脚本,提示输入ESX的密码:
$ fix_host_ssh
Enter ESX password:
2024-03-01 17:36:52 INFO hypervisor_ssh.py:44 Trying to access hypervisor with provided password...
2024-03-01 17:36:52 INFO hypervisor_ssh.py:52 Failed
这个时候我其实有疑问的,我只是重启了一下cvm,也没改过啥配置,怎么就突然密码认证不通过呢?输入ESX的密码后还是提示Failed ,我想着是不是这里要求的密码并不是esxi的密码,而是集群的其它什么密码(没安装过集群,也没研究过,没啥知识点)。但是手上的资料没有其它密码了。
没办法,去其它正常的CVM看了下进程,尝试手工启动那些进程,但是没啥效果。
3、深入分析
没办法了,要是管理平台没部署在这个节点,我都想放弃了。但是偏偏管理平台在,打不开整个集群都受影响(无法正常巡检)。决心解决这个问题,我觉得问题的关键点还是在这个ssh的认证上。既然fix_host_ssh提示认证失败,那是否可以看看它怎么做的认证?
还好,fix_host_ssh 是个python脚本,查看后发现关键代码:
import env
import gflags
import sys
from getpass import getpass
from cluster.hypervisor_ssh import fix_hypervisor_ssh
from util.base import log
def main():
while True:
passwd = getpass("Enter ESX password: ")
type(fix_hypervisor_ssh)
if fix_hypervisor_ssh(password=passwd):
break
其认证方法调用了 cluster.hypervisor_ssh 这个模块下的 fix_hypervisor_ssh 方法。
继续查看 cluster.hypervisor_ssh 的所在位置:
$python
>>> import cluster.hypervisor_ssh
>>> print(cluster.hypervisor_ssh.__file__)
/usr/local/nutanix/cluster/lib/py/nutanix_infrastructure_python.egg/cluster/hypervisor_ssh.pyc
可以看到,这个是nutanix提供的一个模块,而且做了编译,是一个pyc文件。pyc文件无法直接打开查看,怎么办? 只能试下能不能反翻译了。
百度了下,发现有个工具可以试下:
$pip install uncompyle6
$uncompyle6 -o . hypervisor_ssh.pyc
hypervisor_ssh.pyc --
# Successfully decompiled file
提示成功,查看目录下多了个hypervisor_ssh.py 文件,这个就是正常的py文件了,看看内容是否正常:
$ more hypervisor_ssh.py
...
def fix_hypervisor_ssh(alternative_key=None, password=None):
"""
Fix up local CVM's key-based access to the hypervisor.
alternate_key: alternative key to try to get into Hypervisor.
password: hypervisor password.
Returns True on Success, False on failure.
"""
ssh_client = None
if alternative_key and os.path.exists(alternative_key):
log.INFO('Trying to access hypervisor with provided key...')
ssh_client = SSHClient(FLAGS.hypervisor_internal_ip, FLAGS.hypervisor_username, private_key=alternative_key)
ret, out, err = ssh_client.execute('true')
if ret == 0:
log.INFO('Success!')
else:
log.INFO('Failed.')
ssh_client = None
if ssh_client is None and password:
log.INFO('Trying to access hypervisor with provided password...')
ssh_client = SSHClient(FLAGS.hypervisor_internal_ip, FLAGS.hypervisor_username, password=password)
ret, out, err = ssh_client.execute('true')
if ret == 0:
log.INFO('Success!')
else:
log.INFO('Failed')
ssh_client = None
...
内容显示正常,上面贴出了关键代码。我们看到,其ssh认证的主要参数 FLAGS.hypervisor_internal_ip, FLAGS.hypervisor_username 应该就是IP和用户。
我们修改 脚本,让它把这两个参数打印出来:
$vi /usr/local/nutanix/cluster/bin/fix_host_ssh
...
def main():
print(FLAGS.hypervisor_internal_ip,FLAGS.hypervisor_username) ##增加这行
...
再次执行这个脚本:
$ fix_host_ssh
('192.168.5.1', 'root')
出现的IP有点懵,查看网络配置没发现这个IP,但是发现一个类似的
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.5.2 netmask 255.255.255.128 broadcast 192.168.5.12
ping这个IP通的,ssh这个IP被拒绝了。去其它集群验证,同样修改脚本后得到ssh的ip也是这个IP,ssh能通,输入esx密码发现能进去,跳到了该cvm所在的ESXI主机!
想到问题的可能了,之前出现了ESXI的一个安全事件,把ESXI的ssh功能都禁用了一遍。去查看故障cvm所在ESXI的服务,发现ssh功能是关闭的,把它开启后重新执行 genesis restart 命令,过了几分钟,查看服务已经正常启动!
4、总结
nutanix的cvm节点重启后,需要验证cvm主机和其所在的ESXI主机的ssh连通性(必须能直接跳转),若验证不通过不会往后执行。修改ESXI的密码和关闭ssh服务都会导致该验证不通过,如果修改了ESXI的密码,需要运行fix_host_ssh脚本来重新生成认证信息。
在看到出现ssh认证失败的时候,我应该尝试去ssh登陆ESXI的。但是因为没做过配置变更,而关闭SSH服务是很久之前的事情了,经验告诉我这块不会有问题所以自动忽略了。有时候真的不能太相信经验,尤其是对于这样这个自己不熟悉的东西。
nutanix的文档太少了,官网上的文档还不给查看,非得用授权注册的账号才能查看下载。所以其实现在nutanix越来越不行是不是也是正常的?
而且,这应该算是一个坑,ssh认证失败的提示太简单了,直接一个Failed,就不能具体点说明是密码错误还是客户端拒绝了?没那么难吧。。。感觉就是想挖坑好让人买服务。
...