openstack部署经验

作者 Billy 日期 2017-07-26
openstack部署经验

openstack部署经验

背景

使用kvm虚拟化

与vmware不同的是,每台宿主机都是一个计算节点,计算节点使用其上的libvirt虚拟出若干虚拟机。因此计算节点数量规模庞大,需要批量部署,我们本次使用了ansible脚本进行批量操作。

高可用

在云计算产品日常使用中,服务器宕机的情况一定是要首先考虑的。我们对openstack采用的高可用方案进本与官网推荐无异,只不过提供负载均衡的软件采用的是keepalived + haproxy

性能测试要求

测试区为性能测试的主要区域,每台机器配置DELL 730 CPU(2.4GHz/6-core/15MB/85W)*2;内存16GB*8;SSD硬盘480GB*2,SATA硬盘4TB*16;万兆双口网卡*2,4*千兆网口。

共有计算节点宿主机80台,控制节点2台,网络节点2台。(后续又增加了1个控制节点)

压力要求:在第一秒内发送200台虚拟机创建请求,并一直保持200台虚拟机处于运行中状态,一直发送虚拟机创建、删除和查询接口,持续半小时,不允许有失败,每个控制节点cpu利用率不允许超过70%。

裸金属

裸金属在测试区、核心区和DMZ区都有部署,但是DMZ区的机型和其他2区不同,是hp DL380。
给部署带来了极大的阻碍。ubuntu镜像在部署时也出现了问题,玉峰远程协助解决的,也花费了不少精力。

解决方案

kvm虚拟化功能测试

  1. kvm虚拟化,虚拟机冷迁移需要计算节点间nova用户做ssh互信。由于openstack默认安装nova组件时并没有开通nova用户的登录权限,因此步骤比较繁琐。况且计算节点众多,只好采用批量执行脚本的模式。

    • 选择一台不是计算节点但管理网络都通的机器
    • 使用root用户登录每一台计算节点,修改/etc/passwd文件,将nova用户设置为可以登录
    • 再切换到nova用户,生成互信公钥,将每个公钥拷到本机的互信文件中,这样本机就被所有计算节点信任了
    • 上述循环结束后,再次开启循环,将本机的互信文件拷贝到所有计算节点上,这样所有计算节点互相就是信任的了,必要的话可以删除对本机的信任再拷贝。
  2. 创建裸金属节点,配置过于繁琐,需要配置之处有:程序配置文件、数据库、ks模板,希望能简化配置,集中在程序配置中。

  3. 运营管理平台在获取token上的策略是始终使用token,直到发生未鉴权错误时再去重新获取token。这样是有问题的,尤其是本次测试要求极其严格,不允许有类似异常。在openstack的horizon项目中我们可以获取经验:管理系统不应该具有状态,所有请求都去调用底层的api,平台只做页面渲染和内容展示。如果做的足够好,可以极大缩短响应时间,并且平台性能压力基本上全部推给后台。

高可用

  1. 从流程来讲,请求进入openstack第一个组件就是各种api,它们都在控制节点上,由于api组件就是做请求分发,没有状态,因此在多个控制节点上采用多活负载均衡来做高可用。由haproxy提供虚ip,使用rr算法均匀分配每个请求到各个控制节点上。
  2. 其次就是调度组件,如nova-scheduler等,它们几乎都是无状态的,与api交互的方式都是mq消息传递,因此负载方式与api一样,使用多活模式。
  3. 网络节点高可用也是采用多活,但它们提供服务高可用的模式不同:多个网络节点提供多个网络服务如dhcp,多个dhcp服务会同时收发广播报文分配ip,如果其中一个宕了,其他服务会继续提供相同的服务。但有个缺陷是dhcp服务越多,每个网段占用的ip个数就越多。
  4. 计算节点高可用暂时无法提供,因为就连官方也没有一个确定的解决方案。
  5. rabbitmq的高可用使用rabbitmq提供的集群。每个集群需要至少存在一个存储节点,存储节点需要将消息写入磁盘,存在IO操作,非常有可能成为性能瓶颈,因此我们采用2个内存节点作为openstack各个组件连接的mq节点,另外存在一个存储节点放在其他位置。
  6. 数据库高可用我们采用了mariadb galera集群,虽是多活多主,但haproxy在虚ip上做了主次之分,目前读写都只在3个节点中的其中一个上做。经过实际测试,压力瓶颈不是数据库。
  7. memcached本身也提供高可用,在每个组件上配置多个节点即可。在keystone组件上,使用memcached的几率最大。由于压力测试需要不断获取/验证token,如果使用数据库作为后端,那么会给数据库带来巨大的压力,因此采用memcached池作为后端。这样就满足了memcached的高可用。

性能测试

  1. openstack各个组件默认识别cpu核数作为运行服务的进程数,非常智能,目前不需要再优化。只是keystone的进程数配置在httpd的组件里,默认为5,可以修改为cpu核数。
  2. 高并发的请求最大瓶颈其实是token,因为所有请求都带着token,每次请求都会向keystone请求验证token。起初我们采用数据库作为keystone后端,后来发现数据库出现瓶颈,就换采用memcached池作为token后端。注意,一定要采用memcached池,否则多个keystone组件的token会对不上,出现鉴权几率性失败的现象。
  3. 原规划中,rabbitmq和各种控制组件都在控制节点上,但在加压过程中,发现rabbitmqcpu使用率趋近400%,总cpu占用率在90%左右。然后我们就把rabbitmq迁到别的机器,后来发现控制节点cpu总利用率有波动,从10%+到80%+,原因不明。
  4. 测试过程中,由于neutron的组件负载过高,出现了虚拟机由于没有分配到网络创建失败的现象。nova配置中修改一个参数Fail instance boot if vif plugging fails.改为false即可避免。
  5. rabbitmq在生产者生产消息速率远大于消费者消费速率时,性能会大幅下降。在openstack使用消息队列时,连接正确的情况下,绝大多数队列消息都会瞬间被消费。只有通知队列会有堆积,在加压时,虚拟机创建、删除速度极快,通知队列生产者速率很大,消费者也就是我们自己的程序却是单线程的,并且高可用采用AP模式,单点消费,消费速度小于生产速度,造成队列消息不减反增的现象。考虑到消费速度慢,尝试将2个节点的消费程序都启动,在加压过程中发现通知队列并不会无限增长下去,消费速率赶上了生产速率。
  6. openstack在生产通知消息时,有版本化的通知队列和非版本化的通知队列之分。目前二者消息数量基本一致,但我们消费程序只消费了其中一个,就会造成消息大量积压,影响rabbitmq性能。通知消息的格式或内容一成不变,是跟不上openstack版本的变迁的,老版本的通知消息已经满足不了系统。但openstack组件使用的通知版本也需要配置,因此出现了versioned_notifications.info等队列,官方推荐使用版本化队列。但由于我们消费程序在开发时并没有考虑此因素,我们关闭了版本化的通知消息,保留了非版本化消息。

出现问题

  1. 由于网络不稳定的原因,rabbitmq集群出现了网络分区,之前一直认为网络分区是虚拟化环境才会出现,没有做应对的措施。以后环境都必须做应对网络分区的措施。

总结

部署要求很高,可用时间很短,任务艰巨,期间趟过很多坑,需要一点一点记录。

未完待续。