为什么要进行OpenStack容器化?
有哪些使用场景和实现参考?
为何要进行OpenStack容器化?
在对OpenStack进行升级或降级时,通常有两种方式可供选择:基于Packages的管理方式和基于Images的管理方式。
容器化OpenStack的主要目的,在于优化基于镜像的OpenStack管理方式。容器化OpenStack的管理方案解决了当前主流Openstack部署系统中最令人头疼的Openstack可用性和管理维护难题。
已知问题描述
当前主流的OpenStack部署管理系统,或者使用基于Package的升级方式,或者使用基于Images的升级方式。
TripleO采用的便是基于镜像的升级管理方式,TripleO在升级OpenStack时,其会构建整个磁盘系统镜像并重新对其进行部署,而不是仅对组成OpenStack的部分服务进行镜像构建,TripleO的这种升级方式显得过于臃肿,并在可用性上存在很大缺陷。
此外,在TripleO的镜像处理过程中,还需关闭运行中的虚拟机。不过,基于镜像的管理方式却是提供了管理维护的原子性,因为通过系统镜像的重新制作,所有与服务相关的软件更新和升级只需一个完整的步骤即可实现(即升级操作的原子性),而无需针对各个软件包进行单独升级。
对于其他基于Package的部署管理系统而言,由于各种零散软件包的存在,OpenStack的升级过程通常需要针对一个或多个软件包分别实现,这是一个极为痛苦的过程。基于Package的升级过程通常会因为各种各样的原因失败,但是又没法取消已失败的变更。
在OpenStack的部署和管理维护中,通常我们希望一次性便可升级全部与服务相关的软件,如果升级不成功,则再通过一次性的操作即可回退到升级前的状态,但是基于Package的方式显然不能满足这种原子性的操作。
要解决基于Package的非原子性操作和类似TripleO基于全镜像方式所带来的问题,容器可用来实现基于镜像的管理方式,采用容器化的OpenStack部署方式,不仅可以实现实际操作的原子性,还可将升级过程对OpenStack服务的影响降至最低。
粗略的Nova计算节点升级测试表明[1],在基于容器化的镜像管理方式升级过程中,服务仅有接近10s的不可用时间,而且在升级过程中无需关闭虚拟机。
使用场景
原子性升级或回退整个OpenStack集群。终端用户可以通过这种方式将当前运行的软件版本升级为上游社区最新发行的版本,而在升级过程中服务不会终止较长时间,如果升级失败,则可一次性回退至升级前状态。
基于服务组件的OpenStack升级。用户可通过这种方式对OpenStack进行细粒度服务组件级别的升级,从而限制全局升级失败可能造成的影响。
基于服务组件的OpenStack回退。用户在经历了组件升级失败之后,通过这种方式可以很方便的回退到已知的升级前正常运行版本。
容器化OpenStack实现参考
基于容器的OpenStack部署方式可通过树形结构来呈现,树形结构中的节点代表容器集,而每个叶子节点代表一个容器。在容器化过程中,容器集和容器应分别具备各自的属性。关于OpenStack容器化的注意事项和参考实现可参考如下:
容器集属性参考
容器集有一个或多个容器子集构成,后者由一个或多个独立容器构成;
每个容器集提供一个独立的逻辑服务,如Nova服务、Neutron服务等;
容器集被当成统一的单元进行管理,如startup、shutdown等操作时容器集被看成一个Unit进行处理;
每个容器集都被看成一个Unit进行Launch;
每个包含多个容器子集的容器集仍然被当成一个Unit进行处理;
对某个容器集的管理不是原子性的;
每个容器集均为服务高可用监控提供接口。
容器属性参考
可对单个容器进行原子性的升级和回退;
每个容器都包含有单向递增的版本号以便在与其他容器比较时识别出容器的年龄;
每个容器应该独立实现单一任务;
每个容器应该能够对自身健康情况进行检查;
容器存在一个能回收已退出子进程的PID 1;
无需对主机进行访问的容器可能不会存在任何权限;
对于需要访问主机的容器,可能存在超级权限。需要使用超级权限才能访问的主机对象如下:
主机网络命名空间;
主机UUID命名空间;
主机IPC命名空间;
主机持久性共享文件系统。
顶层容器集设计参考
database control。涉及服务有:galera/mariadb/mongodb
messaging control。涉及服务有:rabbitmq
high availability control。涉及服务有:HAProxy/keepalived
OpenStack interface。涉及服务有:keystone/glance-api/nova-api/ceilometer-api/heat-api
OpenStack control。涉及服务有:glance-controller(glance-registry)/nova-controller(nova-conductor/nova-scheduler/metadata-service)/cinder-controller/ neutron-controller(neutron-server)/ceilometer-controller(ceilometer-alarm/ceilometer-base/ceilometer-central/ ceilometer-collector/ceilometer-notification)/heat-controller(heat-engine)
OpenStack compute operation。涉及服务有:nova-compute/nova-libvirt/neutron-agents-linux-bridge/neutron-agents-ovs
OpenStack network operation。涉及服务有:dhcp-agent/l3-agent/metadata-agent/lbaas-agent/fwaas-agent
OpenStack storage operation。涉及服务有:Cinder/Swift(swift-account/swift-base/swift-container/swift-object/swift-proxy-server)
容器设计参考
为了实现预期的目标,需要允许超级权限容器的存在,在docker中使用–privileged=true创建的容器被定义为超级权限容器,超级权限容器在launch时使用-v参数挂载主机文件系统,并通过–ipc=host, –pid=host, or –net=host标志共享主机全部命名空间。
由于使用了–net=host来共享主机网络命名空间,因此在Dockerfile中不会使用到EXPOSE操作。使用–net=host的主要动机在于这种方法的简单性,而不使用EXPOSE操作的原因,在于docker-proxy在转发或返回每个数据包时都有20ms的延时。如果期望使用EXPOSE功能,则可以参考Openstack的默认端口列表[2]将其添加会回每个Dockerfile文件中。
在launch容器时,–restart=always标志的使用可为每个容器提供某些高可用功能的测量,并确保容器按当前设计正常运转。
主机上应该可以运行特定的工具并监控容器健康状况,如果容器未能通过健康检查,则主机工具将重启容器。
Docker容器编排引擎需要被实现,除了在单节点上进行简单的容器编排之外,因为容器被设计为可在多节点上运行,因此编排工具也应该能够应对多节点情况。
部署工具应能够利用key-value键值对集合作为输入,并将其转化到输入环境中以传递给Docker,key-value对可以是文件,也可以是环境变量。
独立容器中的日志可通过某些一致方法进行提取。
本文转移K8S技术社区-何处下手?OpenStack容器化实现参考