随着金融行业的信息化建设深入,云技术在银行应用日益普及,继虚拟机替代传统裸机大规模应用之后,容器作为一种新兴操作系统级虚拟化技术应运而生,而基于容器技术所构建的应用开发、应用托管和应用运维平台则可以称为PaaS容器云平台,容器结合日志、监控、认证、权限等基础能力可以构建企业级的平台和可复用服务,支撑企业业务敏捷研发和模式转型,采用微服务架构实现企业技术服务中台能力,容器云主要用于运行无状态应用,但在某些特殊场景下,我们也需要容器去保存其状态。本文主要从银行实际应用出发,阐述容器云特性及持久化存储方案实践。
一、 云平台以及容器
IaaS/PaaS 是云平台中建设中目前应用相对较广的两部分能力,其中PaaS在IaaS的基础上,提供中间件,数据库,以及容器云等便捷部署和运维能力,中间件和数据库可以提供虚拟机部署形态,也可以提供容器资源部署。从容器自身来说,其提供的是 IaaS 层基础计算能力,且常用于无状态应用,容器消亡后无法保存消亡时的状态。容器技术除了Docker以外,还有Coreos或者Podman等其他容器。相对来说,目前Docker 是一种最为常见容器引擎,金融行业通常使用 Docker 来运行操作容器,采用Kubernetes进行容器的编排管理,使用Kubernetes 实现容器调度和管理的能力,容器技术的应用为 PaaS 平台的实现提供了一种新的资源形态,在金融私有云中,通常采用租户进行IaaS资源的隔离,一个租户可以配置一个或者多个Kubernetes集群,用于运行不同的应用系统,容器加上云计算租户功能,则可以实现容器云平台功能。
二、容器特点如何满足中小银行应用场景
可以结合微服务架构的思想构建容器化 PaaS 平台,每个容器其实就是云操作系统的一个组件 / 进程, Kubernetes 相当于内核实现管理和调度这些组件 / 进程,而容器化 PaaS 平台则是多集群多类型资源多类型应用的企业级云操作系统。提供应用开发、应用托管、应用运维的 PaaS 平台能力。基于容器所构建的容器云平台的优势也来源于容器的特点,适合轻量、变化快、弹性扩缩容、容器云平台要使用基础设施资源。通常我们基于虚拟化来构建容器云平台节点,这样可以实不提供中间件等服务,云管只管云基础设施资源。
容器云平台支撑微服务架构的应用则具备天生的优势。而通过微服务化在企业内部构建可重用的技术服务、数据服务、业务服务等来构建服务中台则能支撑企业业务应用的敏捷迭代,这才是比较好的匹配。容器作为一种开源技术,在不断的发展完善中。由于其技术的快速迭代和变化,使很多对稳定性要求高的企业在应用容器技术时都采用小步快走的模式,在金融行业则是更甚。容器云平台因它对于开发者具备便捷的调试、开发、部署、运维、迁移、扩容特性,并且伴随着企业数字化转型的加快,企业需要具有资源统一管理能力、系统弹性伸缩能力、运维成本低的平台并结合 DevOps 和智能运维,实现开发、测试到系统运维、软件交付的全生命周期一体化管理平台,容器技术越来越热。
众所周知,银行业属于对IT科技要求很高的行业,银行业在以往的IT建设中并不追求用最前沿最新的技术,而主要追求系统的可靠性与稳定性,因此相对互联网公司,容器在银行业的应用会相对步骤偏慢。但是,随着容器在多个行业的深入应用,金融行业对于容器云也逐步深化应用,在金融领域银行是容器云平台典型的应用场景。由于互联网技术的飞速发展,新兴的金融类服务模式对银行业务带来了冲击,近年来,银行持续在对业务模式进行创新,也催生了对于传统IT 流程、基础架构和运维模式的升级,容器技术的成熟为传统金融企业的数字化转型提供了新思路。
银行应用容器的主要场景:第一类是有敏态业务场景、内部的规范化管理。其中业务场景主要指银行正在从传统柜台办理业务向新应用转型,在设计互联网区域一些响应快速需求的敏态区域,则需要加快应用的部署能力,提升持续交付的能力,通过容器云平台一方面可以标准化应用的部署和交付,另一方面更好地与 CI/CD 技术进行融合,可快速响应敏态业务的需求。第二类是内部规范化管理需要,主要是指银行系统分支机构众多、组织架构繁杂,通过云平台中容器云管理能力,能规范化的管理容器镜像、实现基础安全和性能配置基线统一,更高效地管理 IT 基础设施,满足系统的合规性要求。
三、容器的存储与配置
3.1 城商容器云持久化存储应用场景及容器的持久化存储类型
目前在城商行使用了容器云的,更多是用于部署应用层的一些组件,在涉及一些需要进行弹性伸缩的业务场景,例如秒杀、活动优惠等敏捷态业务,则采用容器部署应用app层的一些纯Java程序、中间件、无状态的Redis集群等,此外也会逐步碰到一些场景,需要我们的容器平台能保存状态,我们部署 MySQL、Redis 等数据库,需要对这些数据库产生的数据做备份。在容器云中,我们对Kubernetes中部署的应用都是以 Pod 容器的形式运行的,因为Pod是有生命周期的,如果 Pod 不挂载数据卷,那 Pod 被删除或重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到 Pod 数据持久化存储。
除了希望数据不在Pod重启后丢失,有时候也需要在Pod间共享文件。因此,衍生了Pod存储持久化的话题。在云平台的容器云中,都提供了一些方案来解决容器挂载持久化存储的问题,但是主要都是通过Kubernetes提出的Volume对象方案进行封装来解决该问题。
容器云支持的卷类型比较丰富,包括NFS文件系统,或者ISCSI/FC等映射存储,Cephfs等分布式存储系统,AWS等公有云存储服务,还有EmptyDir,HostPath 等Kubernetes内置存储类型。其中目前常见的主要是NFS映射文件系统,以及Hostpath内置存储。Cephfs等分布式对象存储系统,因其灵活扩容能力和海量存储特性,目前有部分用户用于进行容器备份。
其中 HostPath Volume 是指Pod挂载宿主机上的目录或文件。HostPath Volume 使得容器可以使用宿主机的文件系统进行存储,Hostpath(宿主机路径)是节点级存储卷,在Pod被删除后存储卷仍然存在Pod运行worknode上不会被删除,只要同一个Pod 被调度到该节点上,在 Pod 被删除重新被调度到这个节点之后,对应的数据依然是存在的。Hostpath 存储卷缺点在于 Pod 删除之后重新创建必须调度到同一个 node 节点,数据才不会丢失,对于多个Node的场景,是不合适采用的。
EmptyDir 类型的 Volume 是在 Pod 分配到 Node 上时被创建,Kubernetes 会在 Node 上自动分配一个目录,因此无需指定宿主机 Node 上对应的目录文件。这个目录的初始内容为空,当 Pod 从 Node 上移除时, EmptyDir 中的数据会被永久删除。EmptyDir Volume 主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等,但是如果是需要进行持久化存储,则不合适采用。下面我们主要还是针对NFS方式配置持久化存储进行阐述。
3.2 容器持久化存储配置
容器在使用Volume时不需要关心后端存储是什么系统,对它来说,所有类型的Volume都只是一个目录。我们想要使用存储卷,需要经历如下步骤:
1、定义 PersistentVolume,并定义pvc指明这个 volume 要关联到哪个存储上的;2、在容器中要使用 Volumemounts 挂载对应的存储,经过两步才能正确的使用存储卷。
PersistentVolume(PV)是群集中的一块存储,由管理员配置或使用存储类动态配置,就像pod 是k8s 集群资源以及一个Lun的存储单元可以类比于集中式存储的最小逻辑单元一样, PV被定义为集群中的基础资源, PV 可以认为是一个存储插件,其生命周期独立于使用 PV 的任何单个pod。
PersistentVolumeClaim(PVC)则是一个持久化存储卷,我们在创建 Pod 时可以定义这个类型的存储卷。 它类似于一个Pod。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。PVC 在申请 PV 的时候也可以请求特定的大小和访问模式(例如,可以一次读写或多次只读)。
三种PV的访问模式:
(1)ReadWriteOnce:是最基本的方式,可读可写,但只支持被单个Pod挂载。
(2)ReadOnlyMany:可以以只读的方式被多个Pod挂载。
(3)ReadWriteMany:这种存储可以以读写的方式被多个Pod共享。
不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。PV在设计时可以按照业务系统进行挂载,一个业务系统多个pod都共享同一个PV存储,按照目录进行区分,采用ReadWriteOnce模式;也可以精细化管理,每个pod对应一个PV,采用ReadWriteMany模式。
三个重声明策略(reclaim policy):
(1)Retain手动重新使用,生产系统中,因通常存储上都是需要保留的数据、日志等,最为常用。
(2)Recycle基本的数据擦除 (“rm -rf /thevolume/*”)。
(3)Delete相关联的后端存储卷删除, 后端存储比如AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder。
只有本地盘和NFS支持数据盘Recycle 擦除回收, 而AWS云盘或者Cinder存储卷支持Delete策略。
PV卷包含四个阶段状态,其中Available状态表示资源尚未被claim使用;Bound状态表示卷已经被绑定到一个claim声明;Released状态表示声明使用已经被删除,卷处于释放状态,但未被集群回收。Failed状态表示卷自动回收失败。
PV是群集中的资源,PVC是对这些资源的请求,并且还充当对资源的检查。PV和PVC之间的相互作用遵循以下生命周期:Provisioning,Binding,Using,Releasing,Recycling。
(1)供应准备Provisioning。Provisioning分为静态和动态两种,静态提供Static:集群管理员创建多个PV。它们携带可供集群用户使用的真实存储的详细信息。它们存在于Kubernetes API中,可用于消费,在生产系统中,推荐使用静态,便于管理员在存储段进行规范化的管理,并且静态分配的存储的数据是可以由管理员决定是否保存的,PV的命名也可以通过不同业务进行区分。NFS不支持动态存储,动态通常需要借助第三方插件,当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷,动态分配的存储总是会被删除掉的。动态方式实际使用较少,可以考虑用于开发测试等非生产场景。
(2)绑定Binding。PVC根据请求的条件筛选并绑定对应的PV,一定PVC绑定PV后, 就会排斥其它绑定,即其它PVC无法再绑定同一个PV,即使这个PV设定的access mode允许多个node读写。此外 ,PVC 如何匹配不到相应条件的PV, 那么就会显示unbound保持未绑定状态,直到匹配为止。
(3)使用Using。Pods 挂载存储, 即在Pod的template文件中定义Volumn使用某个PVC,用户可在Pod中像volume一样使用PVC。
(4)释放Releasing。用户删除PVC来回收存储资源,PV将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他PVC使用。见PersistentVolumeReclaimPolicy。
(5)重声明Reclaiming。到这个阶段会告诉cluster如何处理释放的PV。数据可能被保留(需要手工清除),回收和删除。
(6)回收Recycling---PV可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。保留策略:允许人工处理保留的数据。删除策略:将删除PV和外部关联的存储资源,需要插件支持。回收策略:将执行清除操作,之后可以被新的PVC使用,需要插件支持。
3.3 NFS配置持久化存储经验分享
在实际生产环境中,针对有状态的容器进行存储设计时,需要考虑高可用、灵活扩容能力、便捷管理几个方面。目前在城商行已有的案例中,较为常见的方案是采用集中式或者分布式NAS存储提供持久化存储服务,划分文件系统给容器云挂载PV卷。目前采用集中式或分布式存储提供持久化存储服务,能较好的满足在高可用、灵活扩容能力、便捷管理几个方面的要求。
1、稳定性及性能:容器在进行弹性伸缩或者进行故障恢复时,同时将频繁的发生存储卷的挂载和卸载,为了保证整个生产环境的稳定性,在进行卷的挂载和卸载操作中需要保证足够的稳定性,同时也需要PV卷服务端能保证较高的性能,避免应用延迟。采用专用的集中式存储NFS可以提供较为稳定、高性能的存储服务。集中式存储设备通过Raid、冗余存储机头、分布式集群多节点等能力,保证了硬件故障情况下的高稳定性;当NFS表现出性能不足的情况下,集中式存储可采用增加端口绑定的方式提升带宽,分布式存储也同样可以采用增加绑定端口提升带宽,扩容分布式节点提升整体集群存储性能。
2、容灾能力需求:通常银行业会要求重要业务进行两地三中心部署,通过集中式存储和分布式存储本身的双中心双活能力,也可以构建双中心架构的容器集群。
3、运维管理需求:随着容器有状态应用的增长,对传统存储运维工作也会带来挑战,整体方案需要兼顾运维敏捷和安全。集中式和分布式NAS存储产品,均具备界面化、便捷的管理手段。
4、容量扩容需求:随着容器应用数据的增长,存储卷容量需要考虑扩容的能力,最大程度避免对应用运行的影响。分布式集群更为灵活的扩容能力,集中式存储在最大可配置硬盘柜范围内,也可以较为方便的进行扩容。
下面分享从已有的集中式和分布式存储划分NAS成功实现备持久化存储能力的容器集群实践案例。本案例属于城商行某风控相关系统,目前运行有多个业务系统,多个业务系统采用独立的K8S容器集群运行承载,其中较大业务系统一个Kubernetes集群中部署有12个Pod,主要是运行业务系统的Java应用以及Web应用,该持久化存储场景主要是为了保存业务运行日志,容器集群的持久化存储通过两套配备双中心复制的存储集群提供,一套为华为OceanStor 5500系列中端存储,通过配置双活NAS存储发布服务至容器云集群,作为PV映射给Pod使用,另一套采用同样具有双中心目录同步复制的SDS分布式集群配置,数据中心可以将复制卷发布至灾备中心的Kubernetes灾备集群,备中心的Kubernetes集群作为冷备集群,当主中心故障时进行切换。
在容器云中,我们会定义一个PV挂载nfs路径:XX.XX.XX.XX:/nfsshare,并将该Pv-admin关联PVS映射给某应用命名空间spacegs12zr9a使用。如果是作为持久化日志存储使用,某个应用多个 Pod需要同时写入,则访问模式通常采用ReadWriteMany,而为了保证生产日志不会被删除persistentVolumeReclaimPolicy的PV回收策略建议采用 Retain,这样只有在PV被手工重定义的时候,PV里的数据才会擦除。
PVC配置中大多数属性是从PV定义中继承而来,在PVC中,主要是定义PV和应用之间的关联关系,PV与应用的关联关系通过配置命名空间namespace来完成。
四、总结
早期由于Kubernetes的存储接口演进方向不明确,有状态容器不成熟,加上受接口协议限制与Kubernetes配合比较好的主要是“分布式”开源存储,早期那些与Kubernetes兼容适配较好的存储产品,往往在性能和可靠性等方面满足不了业务的需求,现在CSI插件的官方手册Driver一节,对于国内外一些主流的如华为等存储厂家均有推荐,集中式存储提供服务作为容器持久化存储已经较为成熟。总体来说,容器云的持久化存储的选型,要根据承载的工作负载进行具体分析。譬如在容器云上部署关系型数据库,且数据库的数据是重要的业务系统数据,则选择集中式存储为宜。如果是业务应用系统的日志,或者是配置文件,则建议优先选择分布式存储,在扩展性和成本收益上更佳。