目前以Docker为代表的容器技术取得了快速的发展,在数据中心、公有云、私有云等领域开始被广泛支持。基于容器技术可以做到系统持续部署与测试,消除了线上线下的环境差异,实现了高效的资源隔离和资源控制,简化了系统的管理、调度和运维。而软件定义存储是基于通用的服务器,具有极好的横向扩展能力,已经成为下一代基础设施建设的主流选择。我们知道容器应用需要有持久化存储的支持,但是换个角度来看,存储技术的容器化是否同样有价值?又该如何去考虑、如何去实践?
一、存储是否有必要容器化
我们知道存储系统是直接管理服务器上硬盘相关的资源,通常是直接运行在物理机上。但是,对于软件定义存储系统,如果把相关存储服务封装到容器中,大家最关心的问题就是是否有性能损耗,如果有,这个损耗是否可以承受?存储系统的测试本身是一个复杂的问题,也超出了本文的讨论范围。但是,从我们的验证和测试来看,如果Docker容器采用net=host网络以及privileged的权限,那么由于增加了容器网络层所带来的性能损耗很低,几乎可以忽略(从实际测试来看,属于误差范围内的差别)。而且,业内有关Docker容器本身的相关性能测试也同样验证了这一点。
因此,我们可以认为在一般的应用场景下是可以对分布式存储系统提供容器化运行、调度和管理。这样对于非云平台场景,容器化的存储系统能够带来的是管理和运维的便利性;而对于OpenStack/Kubernetes等平台通过对底层存储的容器化支持,形成一种云原生存储,这样存储服务可以作为云平台的系统服务之一,并具有更好的超融合特性。
二、存储容器化的主要工作
对于通常的软件定义存储,如典型的Ceph系统,直接把相关服务封装到Docker容器中,并下载镜像到相关的服务器节点上,启动实例运行,这样单纯的使用带来的好处和便利性还是比较有限。
容器化的存储系统需要对不同的存储模块,进行合理的服务抽象,还需要提供相关的部署、管理和监控工具等,只有形成完整的产品化过程后,才能给客户带来更大的价值和便利性。
以Ceph系统为例,基于卓盛云科技的技术实践,存储容器化的改造主要结构及相关模块如下:
1. 存储服务的容器镜像制作
Ceph系统是由多个服务组成的,包括mon,mgr,mds,osd,rgw等,考虑到还需要增加监控等多种辅助模块,这样一套完整系统包含的服务类型肯定有多种。那么就需要对各个存储服务进行抽象,建立好相关的依赖性,形成多个独立的最小容器镜像。按照微服务的理念,每个镜像都应该尽量简单,提供一种轻量化的服务,形成瘦的镜像模板。但是瘦镜像必然带来较多的镜像种类和镜像版本,同样镜像及其镜像版本的管理复杂度会有所增加,两方面需要一定的平衡。如下是主要的服务抽象,相关的镜像模板需要支持这些类型服务。
2. 存储服务的镜像仓库系统
在实际使用中,所有的容器镜像一定是放到私有的仓库中,进行统一的仓库管理和软件版本管理。
3. 基础服务与辅助服务
上图中可以看到,Ceph自身的服务,mon,mgr,osd,mds,rgw等是核心,但是单纯的这些服务在生产环境中完全还不够。镜像仓库自身就是一个容器,etcd作为共享配置库解决了所有容器实例之间的配置信息和集群信息的数据传递。时间同步服务、监控服务、负载均衡服务、各种客户端服务都需要容器化才基本完整。而且最核心的管理模块“容器化部署、运维管理系统”自身也可以运行在一个容器实例中,最终可以实现一个完整的全容器化分布式存储系统。
4. 容器化部署、运维管理系统
作为容器化存储系统,管理好各种相关存储服务的容器实例是系统的关键与核心。但是为了管理一套存储系统,再额外采用Kubernetes之类的容器云管理平台显然是不可能,也是不合理的,这将极大增加系统的复杂度。当然在对于本来就需要部署K8S的环境下,可以把上面的存储服务直接部署在K8S平台上,成为一个云原生存储服务。Rook是一款运行在Kubernetes集群中的Ceph存储服务编排工具,但是目前还没有达到成熟可用的阶段。
因此,在通常的容器化存储系统中,需要基于Ceph的特点以及普通用户的使用要求,开发一款有针对性的简单、轻量化的存储容器管理和运维系统。比如存储服务可靠性非常重要,这样大部分服务不应该支持容器的动态迁移,但是在硬件故障和负载过于不均衡时,又需要支持人工迁移;OSD服务需要支持硬盘拔插到不同物理机上的迁移;容器资源的分配上也一般不应该支持动态资源调整,但是需要支持人工调整。但是对于一些辅助服务(如监控服务、NTP服务等)却可以支持容器的动态迁移和资源的动态调整。所以,这种容器管理系统需要根据不同存储服务的特点,考虑好服务的相互依赖性和先后次序,解决升级和回滚、监控的自动关联、容器资源的分配和控制、共享配置的获取方式、以及故障处理等问题。
最终用户的日常管理直接在容器管理系统中进行操作,而不需要单独访问各个服务器和容器,可以明显简化的系统管理和运维的工作量。
5. 平台插件
在超融合场景下,同一台物理机即需要运行存储服务,也需要运行OpenStack/Zstack等云计算平台的服务,同时运行业务应用的虚拟机或应用容器。这几者之间会存在互相影响和抢占资源,虽然可以基于Linux的Cgroups来限制各自的资源。但是Cgroups的管理配置显然不够方便。Ceph天生能够很好的支持OpenStack和Kerbenetes系统。但是容器化后的Ceph存储系统基于Docker的资源配置能够具有更好的实现资源控制以及超融合的支持,避免云平台和存储服务之间的冲突。同时,如果容器化存储运行在Kerbenetes上,使得存储管理可以成为Kerbenetes平台的一个基本服务,能够避免了存储与Kerbenetes的分离。下图给出了一种Ceph运行在Pod中,并通过每个节点上的Ceph Client Pod为应用Pod提供存储卷服务。
6. 存储集群的监控和容器的监控
在正常的Ceph集群监控中,一般通过ceph命令或者相关API获得集群状态,但是在集群负载较高时,这个操作仍然是一个占用资源较多的操作,数据采样的频率不能太快。而基于容器状态的数据采集,却轻量化了很多,可以快速获得容器状态,也能够提供高频采样。因此结合集群状态的监控和容器状态的监控,可以达到高效的监控手段。
三、存储容器化后带来的价值
容器化的存储本身并不能替代Ceph等分布式存储的自身工作,但是我们认为容器化的存储系统给客户带来的主要价值包括以下几点。
1.保证运行环境的一致性,避免软件兼容性问题。实际物理机上的OS很多时候未必能够由软件定义存储的厂商自己提供,比如超融合场景、国产服务器上的移植。但是如果这些系统能够支持Docker容器技术,那么容器化后的存储系统是基于自身镜像内容来运行的,保证了开发环境、测试环境和生产环境的一致性,也就不需要在特别考虑软件兼容性问题。
2.更好的超融合支持。基于Docker容器的资源隔离和资源限制能够更好的满足存储、计算和网络的融合。
3.配置和调优的一致性。采用etcd之类的共享配置库,可以对Ceph的配置内容提供统一的保存点,容器重启后可以自动更新相关配置。这样,系统配置的修改只需要集中处理即可,系统的配置修改或者调优比较简单方便。
4.基于容器领域的生态环境,实现监控及服务功能的多样性。在生产环境下,相关的系统监控、统一的日志查询分析等都是需要,这些功能如果都基于Docker进行构建,一般会更加容易,且一致性较好。同时,通过监控容器的运行状态,很多时候比监控某个服务本身更加简单、高效。
5.满足云原生存储的应用需求。可以实现存储服务与云平台或Kubernetes平台的整合,融合为云原生存储,使得底层存储系统的管理成为OpenStack/Kubernetes平台的基础服务之一,让云平台系统更加完整。
综上所述基于容器技术构建分布式存储系统,并以容器为管理颗粒度进行系统管理、调度和运维,能够使整个系统更容易具有自动化、智能化和简单化的特征,在使用上变得更加简单易用。此外通过与OpenStack或者Kubernetes等平台进行超融合的整合,可以实现把底层存储系统的管理纳入为云平台和容器平台的基础服务之一。