运维-12-综合问题记录¶
问题1:SSH 虚拟机,报 Cannot allocate memory 异常¶
问题现象¶
当通过 ssh 登录虚拟机时,会出现 Cannot allocate memory 异常,具体现象如下:
[root@192e168e3e201 ~]# ssh 192.168.9.66
Last failed login: Thu Aug 2 10:12:05 CST 2018 on tty1
There were 2 failed login attempts since the last successful login.
Last login: Thu Aug 2 10:01:46 2018 from 192.168.9.201
-bash: fork: Cannot allocate memory
-bash-4.2#
-bash-4.2# free -h
-bash: fork: Cannot allocate memory
处理过程¶
- 通过 VNC 方式登录虚拟机。
- free 查看内存还比较充足(注意,命令可能要多敲几次才会出来)
-bash-4.2# free
total used free shared buff/cache available
Mem: 528198152 28698836 487266620 151640 12232696 497758644
Swap: 0 0 0
可以看出内存还有不少,应该不是内存使用过多的问题。
- 查看最大进程数
-bash-4.2# sysctl kernel.pid_max
kernel.pid_max = 40960
- 查看现有进程数
-bash-4.2# ps -eLf |wc -l
40827
由此可以看出进程数基本满了
- 修改最大进程数
-bash-4.2# echo "kernel.pid_max=1000000 " >> /etc/sysctl.conf
-bash-4.2# sysctl -p
kernel.pid_max = 1000000
- 最后重新 ssh 登录虚拟机,可以成功登录
[root@192e168e3e201 ~]# ssh 192.168.9.66
Last login: Thu Aug 2 14:39:40 2018 from 192.168.9.201
[root@192e168e9e66 ~]#
问题原因¶
进程数满了,后续 ssh 也会占用一个系统进程,所以 ssh 登录不上去。
问题2:物理机ping其他节点出错,且物理机经常失联¶
问题现象¶
从物理机 ping 其他节点时,ping 报如下错误
而且经常无法 SSH 登录到该机器,ping 也时好时坏。
处理过程¶
- 在物理机查看 arp 表,发现内容不多。
- 在名称空间统计 arp 表,发现有很多统计数值很大。
- 修改下列参数,问题解决
# sysctl -w net.ipv4.neigh.default.gc_thresh1=1024
# sysctl -w net.ipv4.neigh.default.gc_thresh2=2048
# sysctl -w net.ipv4.neigh.default.gc_thresh3=4096
# sysctl -p
问题原因¶
名称空间的 arp 表过于庞大,发生抖动。
问题3:计算节点CPU负载突然过高¶
问题现象¶
一台计算节点 CPU 负载突然过高,并且该计算节点的虚拟机全部无法联网。
处理过程¶
- 跟踪其中一个负载过高虚拟机的进程
# strace -p 19096
发现出现大量文件描述符错误,为进程读取文件的错误。
- 通过 ip a 查看网卡信息,发现 tap 设备消失。
- 通过 ovs-vsctl 命令查看 ovs 网桥上的接口信息,发现网桥上的 tap 设备也消失了。
# ovs-vsctl show
- 重启该计算节点 neutron 相关的服务。
# systemctl restart neutron-openvswitch-agent neutron-l3-agent neutron-dhcp-agent
- 查看 ovs 网桥接口信息发现,tap 设备已经出现。
- 查看物理机网卡信息,发现 tap 设备并没有出现。
- 重启该节点所有虚拟机以后,虚拟机的 tap 设备出现。
- 查看系统负载,发现负载恢复到正常水平。
- 跟踪一个虚拟机进程,发现不再有文件描述符读取错误信息。
- 检查节点虚拟机联网情况,全部正常。
问题原因¶
部署时, neutron-ovs-cleanup 服务设置了开机自启动,在计算节点重启以后 neutron-ovs-cleanup 服务自动启动,清理了所有的tap设备,另外 neutron-ovs-cleanup 服务 stop 的时候也会清理掉所有的 tap 设备。
问题4:Dashboard 报错 “Error: Unable to retrieve the project.”¶
问题现象¶
使用 admin 登陆 Dashboard,进入页面 http://10.0.192.18/dashboard/admin/images 后,页面报错,信息为:Error: Unable to retrieve the project。
处理过程¶
- 首先检查浏览器 API 返回日志。
"Could not find project: 8d8b91fb518b4013ab6d18eb48c1b3d9 (HTTP 404) (Request-ID: req-e393f927-081b-4ca9-9583-69db92781217)"
- 查看所有 Glance images 信息,发现有镜像属于这个项目。
{
"status": "active",
"properties": {
"instance_uuid": "93deca7a-eb74-48c8-a689-47a7693148c6",
"image_location": "snapshot",
"image_state": "available",
"user_id": "c40bb40d36dd426bb43d92140dba252f",
"image_type": "snapshot",
"base_image_ref": "86fed267-c2d2-48c0-a55d-119ad80c8d0f",
"owner_id": "8d8b91fb518b4013ab6d18eb48c1b3d9"
},
"name": "os initial",
"checksum": "5d3552298cf399e74d22fd2f569331fb",
"created_at": "2017-03-24T02:12:58Z",
"disk_format": "raw",
"updated_at": "2017-03-24T02:44:51Z",
"visibility": "private",
"id": "19400cc8-983f-41d2-aec2-58a3f850355a",
"min_disk": 20,
"protected": false,
"architecture": null,
"container_format": "bare",
"owner": "8d8b91fb518b4013ab6d18eb48c1b3d9",
"is_public": false,
"min_ram": 0,
"size": 21474836480
}
- 检查到该项目已经不存在。
# openstack project show 8d8b91fb518b4013ab6d18eb48c1b3d9
No project with a name or ID of '8d8b91fb518b4013ab6d18eb48c1b3d9' exists.
- 检查 keystone log,发现项目删除信息。
2017-04-16 15:30:52.092 1324122 INFO keystone.common.wsgi [req-d2cddac5-8c82-4c2b-b960-4d78b6c060f2 543c04a6caba4b83ad7872f131e0bcee e3d0911c422f4ac2a837bd1b6d7a0d23 - default default] DELETE http://10.0.194.101:10006/v3/projects/8d8b91fb518b4013ab6d18eb48c1b3d9
- 判定为删除了项目,但是项目中的资源保留下来,于是出现这个报错。而目前的 OpenStack 集群,如果删除项目,项目下面的资源不会被删除,所以会出现页面报错的情况。
- 可以创建一个新的项目,然后将新项目的 id 与旧项目的 id 进行替换。
# openstack project create testproj
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | |
| domain_id | default |
| enabled | True |
| id | 69f978beab0e4574a0a1a115ceba66be |
| is_domain | False |
| name | testproj |
| parent_id | default |
+-------------+----------------------------------+
替换项目 id
# update keystone.project set id = '8d8b91fb518b4013ab6d18eb48c1b3d9' where id = '69f978beab0e4574a0a1a115ceba66be';
关联用户与项目
# openstack role add --user c40bb40d36dd426bb43d92140dba252f --project 8d8b91fb518b4013ab6d18eb48c1b3d9 user
- 最后验证问题解决。
问题原因¶
项目已删除,但是所属于该项目的资源并没有提前释放掉。
问题5:计算节点因为内存超配并创建大内存的虚机,导致宿主机内存不足¶
问题现象¶
马驹桥 Bss10 省测试集群,zabbix 自动报警 10e129e170e14 主机空闲内存少于 20%。
处理过程¶
- 登录 10e129e170e14 这台机器,查看机器的内存使用情况,发现其中一个虚拟机的进程占用大部分物理内存。
- 在主机 10e129e170e14 上使用 balloon 技术,挤出部分内存。
# python auto_balloon.py
auto_balloon.py 具体内容如下:
import base64
import json
import re
import subprocess
import sys
import time
def shell(cmd):
sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = sp.communicate()
return out, err
def guest_exec(dom, inside_cmd):
qga_cmd = '{"execute":"guest-exec", "arguments":{"path":"sh", ' \
'"arg": ["-c", \"%s\"],"capture-output":true}}' % inside_cmd
cmd = 'virsh qemu-agent-command %s \'%s\'' % (dom, qga_cmd)
out, err = shell(cmd)
if err:
raise Exception(err)
data = json.loads(out)
time.sleep(1)
pid = data['return']['pid']
qga_cmd = '{"execute":"guest-exec-status","arguments":{"pid":%s}}' % pid
cmd = 'virsh qemu-agent-command %s \'%s\'' % (dom, qga_cmd)
out, err = shell(cmd)
if err:
raise Exception(err)
data = json.loads(out)
out_data = data['return']['out-data']
out_data = base64.b64decode(out_data)
print(out_data)
return out_data
def get_dom_inside_mem(dom):
data = guest_exec(dom, 'free -m')
for line in data.split('\n'):
if line.startswith('Mem:'):
mems = line.split()
out = [mems[1], mems[3], mems[-1]]
return [int(i) for i in out]
def get_dom_mem_stat(dom):
cmd = 'virsh dommemstat %s' % dom
out, err = shell(cmd)
if err:
raise Exception(err)
mem_stat = {}
for line in out.splitlines():
if len(line) == 0:
continue
k, v = line.split()
mem_stat[k] = int(v)
return mem_stat
def _get_current_balloon(dom):
cmd = "virsh qemu-monitor-command %s --hmp --cmd info balloon" % dom
out, err = shell(cmd)
if err:
raise Exception(err)
actual = re.findall("balloon: actual=(\d*)", out)[0]
return int(actual)
def _set_balloon(dom, value):
cmd = "virsh qemu-monitor-command %s --hmp --cmd balloon %s" % (dom, value)
out, err = shell(cmd)
if err:
raise Exception(err)
def reset_dom_balloon(dom, actual, target, max_tries=60):
print('===start reset %s actual:%s target:%s' % (dom, actual, target))
_set_balloon(dom, target)
for i in range(max_tries):
time.sleep(3)
value = _get_current_balloon(dom)
if value <= target:
break
print('\t==%s current balloon:%s' % (dom, value))
_set_balloon(dom, actual)
print('===end reset %s actual:%s target:%s' % (dom, actual, target))
def balloon_dom(dom, threshold=0.2, drop=0, sleep=5):
if 0 < drop <= 3:
guest_exec(dom, 'cat %s > /proc/sys/vm/drop_caches' % drop)
time.sleep(sleep)
total, free, available = get_dom_inside_mem(dom)
mem_stat = get_dom_mem_stat(dom)
rss = mem_stat['rss'] / 1024.0
rate = (rss - (total - free)) / total
if rate > threshold:
actual = _get_current_balloon(dom)
target = int((total - free) * (1 + threshold))
actual03 = int(actual * 0.3)
target = target if target > actual03 else actual03
if actual > target:
reset_dom_balloon(dom, actual, target)
def get_all_dom():
cmd = 'virsh list --state-running --uuid'
out, err = shell(cmd)
if err:
raise Exception(err)
return [i for i in out.splitlines() if len(i) > 0]
if __name__ == '__main__':
domains = []
if len(sys.argv) > 1:
domains.extend(sys.argv[1:])
else:
domains.extend(get_all_dom())
print(domains)
[balloon_dom(i) for i in domains]
- 稍后观察 10e129e170e14 节点内存继续上升,遂决定将其上一台活跃度较低 vm 迁移到其他计算节点。
# openstack server migrate cb064d0d-082b-4a80-acf9-6782030461b7 --live 10e129e170e12 --block-migration --disk-overcommit
注解
上面需要迁移的虚拟机有使用本地盘做存储,所以迁移的时候需要添加 block-migration disk-overcommit 这两个参数,当虚拟机使用全是共享存储的时候,迁移的命令则是 openstack server migrate cb064d0d-082b-4a80-acf9-6782030461b7 –live 10e129e168e74。
- 查看迁移的虚拟机,发现在新的节点正常运行,而原来的节点内存使用也已经降低。
问题原因¶
虚机内存使用上升,导致宿主机内存紧张,当物理机内存超配,而在超配的机器上,开大内存虚拟机的时候,此现象尤为明显。