随着云计算技术的发展,越来越多的应用程序被部署到云环境中。云原生(Cloud Native)是一种在云环境中设计和部署应用程序的理念和技术体系,它充分利用了云的弹性、可伸缩性、高可用性等优势,使得应用程序能够更好地适应于云环境。容器技术是云原生技术的重要组成部分,其中Kubernetes是最为流行的容器编排平台之一。在云原生部署中,存储是不可或缺的组成部分,它可以为应用程序提供数据存储和备份等功能。本文将阐述如何在云环境中使用Kubernetes容器进行云原生部署,并探讨如何与存储相结合。我们将介绍云原生上部署的规范、流程和步骤,并分享一些实践。
一、存储在云原生部署中的重要性和挑战
在云原生部署中,存储是一个关键的组成部分。应用程序需要持久化存储来保存数据,并且需要高效的存储访问。同时,存储的可靠性和性能也对应用程序的稳定性和响应性有重要影响。然而,在云原生环境中,存储的管理和配置面临一些挑战,如数据持久性、数据一致性和存储资源的动态调度等。
二、Kubernetes 部署流程
1. 环境搭建
首先需要准备一台或多台虚拟机,配置网络并安装Kubernetes集群。这里可以使用Kubernetes的官方安装工具kubeadm来进行简化部署。
2. 容器管理
在Kubernetes中,应用被打包成容器镜像,然后通过Pod进行运行和管理。我们可以编写YAML文件来定义Pod的配置,包括镜像、资源、端口等信息。然后使用kubectl命令行工具创建和启动Pod。
3. 资源调度
Kubernetes通过Controller和Scheduler对Pod进行管理和调度。Controller负责监视Pod的状态并根据需要创建或删除Pod,而Scheduler则负责在集群中调度Pod的运行。通过合理配置Controller和Scheduler,可以实现资源的合理分配和应用的负载均衡。
三、Kubernetes 容器与存储的整合
1.本地盘
Kubernetes 支持用户直接将本地盘插到服务器上作为存储设备。由于磁盘和应用系统中间的 I/O 路径最短,本地磁盘可以提供卓越性能。同时 RAID 提供了一定程度的可靠性的保证,可以避免因单个磁盘故障而导致的数据丢失。因此,目前有大量用户采用这种方式为有状态的应用提供存储服务。
但同时,本地磁盘方案也在可用性和扩容方面存在着巨大的缺陷:
1)本地磁盘无法提供节点级别的高可用,当物理节点发生故障时,应用无法被恢复到其他节点。如果业务系统有节点级高可用的要求,则必须由业务系统自己实现数据层面的高可用,这极大地增加了业务系统的复杂度。
2)本地磁盘也无法满足 Kubernetes 环境下的业务敏捷性需求:业务使用的存储空间受限于本地磁盘的大小,达到磁盘空间的上限后,增加磁盘的操作步骤复杂,要想使用新增的硬盘空间,必须手工修改 Pod 中的配置,难以实现敏捷的平滑扩容。此外,要想对物理节点内的硬盘实现高可用,就需要部署 RAID,这也是相当费时、费力、费钱的方案,难以实现在短时间内为大量的应用系统配置足够的存储容量。
由于以上的缺陷,本地磁盘的方案只适合在业务容器化的初期阶段进行小规模试用,或者作为较低重要性的数据存储使用,难以在大规模生产场景下被广泛使用。并不是云原生存储的范围之内。
另一种方式是通过容器存储接口(CSI)将 Kubernetes 平台与底层存储基础设施连接起来,从而允许 Kubernetes 动态调配和配置存储、实现存储操作自动化。按照为虚拟化环境设计和为Kubernetes环境设计,这种外接存储方案进一步划分为商用存储和 Kubernetes 原生存储两个类型。
广义上说CSI都属于云原生存储的范畴内。
2.CSI 外接商用存储
商用存储既包括软件定义式存储(如分布式存储),也包括传统的集中式存储。与专为Kubernetes 环境而设计的 Kubernetes 原生存储不同,商用存储通常情况下主要为裸金属和虚拟化环境服务。
外接集中式存储提供了可远程访问共享存储的能力。和本地磁盘的方案相比,集中式存储解决了应用系统高可用的问题,当业务 Pod所在的服务器发生故障时,可以通过共享存储在其他节点上把应用拉起来,很多基于集中式存储的商用存储方案也提供快照、克隆、容灾等高级功能。此外,由于数据集中存储,也一定程度解决了本地存储对磁盘空间浪费的问题。
但是:
1)当面临大量业务并发访问时,存储控制器则成为了性能瓶颈。如果想要满足大量业务对性能需求,需要采用多套集中式存储系统,存储系统的管理成本也会急剧上升。
2)有碍于盘柜形式,集中式存储扩展能力较差,运维工作量较大,也难以应对短时间内大量 Volume 的并发创建和销毁需求,缺少云原生敏捷性。
外接分布式存储,通过将数据分散存储在网络上的多台独立设备上,分布式存储具有优秀的横向扩展能力和敏捷性,在对接基于分布式计算架构的云原生应用时,性能和高可用方面也远优于集中式存储。不过,市面上可用于Kubernetes 的分布式存储方案鱼龙混杂,一些产品仅基于开源技术简单包装,其性能、稳定性以及对 Kubernetes 环境的支持能力都难以达到生产级别的标准。
3.Kubernetes原生存储
Kubernetes 原生存储是专为支持容器而构建的存储方案。这种存储与 Kubernetes 的集成程度更深,具有容器级别的数据服务粒度和自动化存储资源运维能力,也因此能够为Kubernetes 上的容器应用提供灵活扩展能力与自动化运维能力。
可以选择 Kubernetes 自带的存储方案,如EmptyDir、HostPath、Local、NFS、GlusterFS等,也可以选择外部存储方案,如 Ceph、GlusterFS、Rook 等,如图3所示。
图3 Kubernetes云原生各类存储对比图
四、 结合规范策略
1. 评估存储资源
根据应用程序的需求,为Kubernetes集群分配足够的存储资源,如存储节点、存储卷和存储类等。
存储节点:Kubernetes集群中的节点负责存储容器的数据。确保节点具有足够的存储容量和性能,以满足应用程序的需求。
存储卷:Kubernetes中的Pod可以使用存储卷来访问外部存储系统。根据应用程序的需求,选择合适的存储卷类型,如NFS、GlusterFS、Ceph等。
存储类:Kubernetes提供了一组存储类,可以自动管理存储卷的配置和生命周期。选择合适的存储类可以简化存储管理,并提高应用程序的性能和可用性。
持久卷和持久卷控制器:持久卷是持久化存储的一种形式,可以在Pod重启时保留数据。持久卷控制器可以自动管理和扩展持久卷,以提高应用程序的可用性和可靠性。
2. 选择合适的存储策略
根据应用程序的需求,为Pod定义存储策略。例如,可以根据数据重要性和备份需求选择不同的存储策略。确保Kubernetes集群中的存储组件和Pod受到适当的安全性和访问控制措施的保护。可以使用身份验证、授权和访问控制列表来保护存储资源。并根据应用程序的需求,为Kubernetes集群配置自动扩展和缩减功能。这样可以提高资源利用率,并确保应用程序能够快速响应负载变化。
3. 做好备份与恢复
确保Kubernetes集群中的数据得到备份和恢复。可以使用第三方工具或Kubernetes原生功能来实现备份和恢复。
4. 监控
监控Kubernetes集群中的存储组件和Pod,以确保它们正常运行。可以使用Kubernetes监控工具和日志记录工具来实现这一点。
五、实践策略
1. 选择合适的存储策略
根据应用的需求选择合适的存储策略,如NFS适用于小规模的数据共享,S3适用于大规模的分布式存储,Redis适用于高速缓存和临时数据存储。同时,需要根据应用的特点进行存储的优化,如调整NFS的挂载选项、优化Redis的数据结构等。
2. 配置存储卷
在Kubernetes中,存储抽象是一种机制,用于将底层存储系统与应用程序解耦,使应用程序能够以一致的方式访问不同类型的存储资源。它提供了一种标准化的方法来管理和使用存储,并使开发人员能够在不了解底层存储实现细节的情况下进行操作。
Kubernetes中的存储抽象主要包括以下概念:
存储卷(Volume):存储卷是一个抽象的概念,它表示可供Pod使用的持久化存储资源。存储卷可以映射到底层存储系统的各种类型,如本地磁盘、网络存储、分布式文件系统等。存储卷可以在Pod中被挂载为容器的一个目录,从而使容器能够读写数据。
存储类(StorageClass):存储类是一种用于动态创建存储卷的抽象概念。它定义了存储卷的属性和行为,并将其与具体的存储后端绑定。存储类允许管理员为不同的存储需求定义不同的策略,并根据需要自动创建相应的存储卷。
持久卷声明(PersistentVolumeClaim):持久卷声明是用于请求存储资源的声明,它描述了应用程序对存储的需求。持久卷声明提供了一种标准化的方式来定义存储需求,并使应用程序能够独立于底层存储实现进行操作。管理员可以根据持久卷声明动态创建符合要求的存储卷。
持久卷(PersistentVolume):持久卷是一个集群级别的存储资源,它与具体的存储后端绑定。持久卷由管理员手动创建或由存储类动态创建,并可以被多个Pod共享。持久卷提供了一种持久化存储的机制,使得数据在Pod重新调度、失败恢复或水平扩展时不会丢失。
在Kubernetes配置文件中,通过定义PersistentVolume(PV)和PersistentVolumeClaim(PVC),为容器配置存储卷。这使得容器可以持久化存储数据,并在容器重新调度或重启时保持数据的一致性。
在Kubernetes中,一般通过创建持久卷(表示底层的存储资源)、创建持久卷声明(用于请求存储资源,主要描述应用程序对存储的需求,包括访问模式、容量、存储类等)、挂载存储卷(提高数据存储和读取的效率)等步骤配置存储卷。
3. 使用容器原生存储解决方案
一些容器原生存储解决方案(如Portworx或Rook)可以与Kubernetes无缝集成,提供可靠的存储服务。这些解决方案可以自动管理存储卷、备份和恢复等任务,从而减轻运维人员的负担。
4. 存储插件的选择与配置
Kubernetes允许用户通过存储插件来扩展和定制存储功能选择合适的存储插件是云原生部署中非常重要的一步,它可以影响到应用程序的性能、可靠性和扩展性。以下是一些常见的存储插件以及它们的配置和使用方法:
1) NFS插件:
NFS(Network File System)是一种分布式文件系统,可以通过网络共享文件。NFS插件允许容器直接访问NFS服务器上的文件,并将其挂载为容器内的目录。
2) Ceph插件:
Ceph是一个开源的分布式存储系统,提供了对象存储、块设备和文件系统等多种接口。Ceph插件可以将Ceph集群中的存储资源与Kubernetes集群集成起来。
3) GlusterFS插件:
GlusterFS是一个开源的分布式文件系统,可以将多个存储节点组合成一个逻辑卷。GlusterFS插件允许容器直接访问GlusterFS卷,并将其挂载为容器内的目录。
4) CSI插件:
CSI(Container Storage Interface)是一种标准化的存储接口,可以与多种存储后端进行集成。CSI插件可以通过CSI接口与存储后端通信,并提供存储功能给Kubernetes集群使用。
5. 监控和调整
监控云原生存储的使用情况,确保存储资源的可用性和性能。根据需要,可以调整存储类、持久卷声明等配置参数,以满足应用程序的需求。
一般常见的有采用prometheus-operator来监控Kubernetes集群。
六、 价值和经验教训
信创云原生与存储结合,是容器化环境中的重要的角色,它提供了一种可靠、可扩展的持久化存储解决方案,具有很高的价值,具体体现在:
数据持久化存储,不会丢失:云原生存储可以将应用程序的数据持久保存在存储卷中,即使容器被重新调度或重新启动,数据也不会丢失。这为有状态应用程序(如数据库)提供了必要的持久化支持。我们经常用其使用存储卷来存储日志文件,以便进行故障排除和审计,并且不会因为容器的生命周期而丢失关键的日志信息。
方便的动态卷管理:可以通过声明式方式创建、删除和管理存储卷。它简化了存储资源的管理工作,减少了手动干预的需求。卷的动态可调整,便于根据应用程序的需要,动态调整存储卷的大小,以满足数据增长或缩减的要求,而无需停止或重新部署应用程序。极大的方便了忙闲时候的应用资源缩放,极大的提高了利用率。
多种存储后端支持:提供了对多种存储后端的支持,包括本地存储、网络存储和云存储等。这使得用户可以根据应用程序的需求选择最适合的存储解决方案。
数据共享和多点访问:支持多个Pod之间共享同一个存储卷,这对于需要多点访问数据的应用程序非常有用。我们可以很容易地扩展分布式应用程序或数据库集群。只需增加更多的Pod来处理更多的请求,并且它们都可以访问共享的存储卷,从而实现水平扩展和负载均衡。
但是在使用过程中,有一些注意点:
了解存储后端的性能和限制:不同的存储后端具有不同的性能和限制。在选择存储后端时,需要了解其性能特征以及与应用程序需求的匹配程度。例如:在选择网络存储后端时,了解其IOPS(每秒输入/输出操作数)和吞吐量等性能指标。如果应用程序需要高性能的存储,则可以选择支持更高IOPS的存储后端,如SSD存储。同时了解存储后端的容量限制,确保存储卷不会超出存储后端的可用空间。
注意数据持久化和备份:尽管原生存储提供了数据持久化的功能,但仍建议定期进行数据备份。这可以确保在发生故障或意外情况时能够恢复数据。例如:通过定期创建快照来备份存储卷中的数据,以便在发生数据丢失或损坏时进行恢复。这可以通过使用存储后端提供的快照功能或其他备份工具实现。我们有时也将存储卷的备份复制到不同的区域或存储区域,以防止单个区域的故障导致数据丢失。
考虑安全性:存储卷中的数据可能包含敏感信息,因此在使用原生存储时要注意确保数据的安全性。这包括对存储卷进行加密、访问控制和审计等。例如对存储卷进行加密以保护数据的机密性。可以使用云原生的透明加密功能或存储后端提供的加密选项。
在基础加密之上,做好权限访问控制,比如使用RBAC(基于角色的访问控制)或其他身份验证和授权机制,限制对存储卷的访问权限,并确保只有授权的实体可以读取和修改数据。
定期监控和调整存储资源:随着应用程序的变化,存储需求也可能会发生变化。定期监控存储资源的使用情况,并根据需要进行调整,以避免资源瓶颈或过度分配的问题。常使用Prometheus等监控工具监测存储资源的使用情况,包括存储容量、IOPS和吞吐量等指标。通过设置警报规则,及时发现并解决潜在的资源瓶颈问题。还根据应用程序的需求和存储资源的使用情况,定期调整存储卷的大小或类型,以满足应用程序的性能和容量要求。例如,根据数据增长情况,适时扩展存储卷的容量。
七、结语
随着云计算和容器技术的不断发展,云原生部署将成为未来应用开发和部署的主流方式,存储技术的整合将在其中起到关键作用。