前面的文章介绍过:什么是云原生以及云原生应用的定义及编排,今天主要介绍云原生所依赖的运行时环境。云原生—编排及管理
目录
前面已经介绍了云原生环境应用部署和编排的上层部分,今天将了解应用运行时所依赖环境—即运行时层。
运行时层整体划分为三大部分:
用于启动容器的代码,称为容器运行时;
容器所依赖的持久层存储工具;
管理容器所依赖的网络环境。
运行时环境保障了应用在运行时,能够得以平稳可靠运行、数据安全以及资源隔离等。可以说,运行时层包含了容器在云原生环境中运行时所需的一切。
这里我们不要将这些与实际的存储容器和网络容器相混淆。这里只专注于保障器平台运行的正常启动和停止、如何协助容器平台存储数据、并允许相互通信所依赖的环境,也是属于运行环境的一层抽象概念。
云原生存储,主要是存储应用程序的持久数据,通常也被称为持久卷或持久层。
为了保障应用能够可靠地运行,应用程序需要能够轻松访问存储。
我们知道持久数据时,一般都用数据库、消息中间件等。主要是确保在应用程序重新启动时数据不会丢失。
通常,对容器进行扩容或缩容等操作时,那么容器化的应用程序也会被不断地创建和删除,甚至会改变应用程序部署的物理位置。另外,云原生架构本身的动态性、灵活性和可伸缩性等特点。
这也为在应用程序重启过程中能够保证数据不丢失而带来了很大挑战。这也是为什么要求云原生存储必须独立于服务节点的原因。
问题一:可移植性
我们知道,通常数据存储,都会基于一定的硬件环境。比如磁盘、内存。而这些硬件本身是受基础设施环境所约束的。
而实际的存储接口中,可能不同的数据中心所依赖的存储环境截然不同,比如有的平台用容器,有的平台用物理机;有的平台要求环境配置高、有的却要求低配置等等,这些差异性使得可移植变得非常困难。
问题二:自动化配置
由于云环境具有弹性化的特点,所以手动配置自然不能满足这种动态化扩展不需求。因此,为了从云的弹性中受益,必须实现自动配置存储。那么云原生存储就是针对这种新的云原生特性实现了量身定制。
1)动态化:为容器提供云原生存储可动态配置化选项。
2)标准化:容器和存储提供者之间的接口标准化。
3)安全化:通过自动备份和恢复等操作,提供了很好的数据自我保护机制。
前者意味着使用与云原生兼容的容器存储接口,并且可以存储的自动化配置,消除手动瓶颈,进而来实现存储的自动扩展和自我修复。
云原生存储很大程度上是通过容器存储接口 (CSI) 实现的,它提供了一个标准 API,用于为容器提供文件和块存储。此类别中有许多工具,包括开源工具和供应商提供的工具,它们利用 CSI 为容器提供按需存储。
容器存储接口(Container Storage Interface),简称 CSI,CSI 试图建立一个行业标准接口的规范,借助 CSI 容器编排系统(CO)可以将任意存储系统暴露给自己的容器工作负载。
此外,还有旨在解决其他云原生存储挑战的技术。Minio 是一个流行的项目,它为对象存储提供了与 S3 兼容的 API。Velero 之类的工具有助于简化备份和恢复 K8S 集群本身以及应用程序使用的持久数据的过程。
Minio是Apache License v2.0开源的一个分布式的存储系统,它支持S3云存储的服务接口,非常适合支持大量非结构化的数据,而一个文件可以是任意大小,从几十K到最大的5TB,同时它也是一个非常轻量的服务,可以结合其他的应用进行使用。
容器本身是一组用于执行或启动应用程序的计算约束流程。容器化应用程序认为它们在自己的专用计算机上运行,而并且没有意识到它们正在与其他应用进程共享资源。
而容器运行时,是执行容器化应用程序的一种软件。如果没有运行时软件支持,仅有容器镜像,即指定容器化应用程序的静态文件。那依然需要运行时所提供的资源,来保证应用程序能够在容器中顺利启动或停止等。
我们知道,容器镜像是一种具有应用程序规范的文件。所以容器镜像启动需要具备标准化、安全化和隔离化这三大特点。
问题一:标准化
无论你的容器镜像在哪儿运行,都需要有一套标准的操作规则流程。
问题二:安全化
安全化方面,首先要保证容器镜像的安全性,比如限制访问权限、操作权限等。
问题三:隔离化
如果你不希望某个应用程序不影响其他应用程序或不受其应用影响。比如,一个位于同一位置的应用程序崩溃而不影响其他应用正常运行。那这时就需要对应用进行有效隔离。当然,也需要为应用程序提供独立的资源,例如 CPU、存储和内存等。
容器运行时,以标准化方式在所有环境中启动应用程序并设置相应的安全边界。比如CRI-O 或 gVisor 等运行时强化了它们的安全边界。运行时还为容器设置资源限制。如果不进行资源限制,应用程序可能会根据需要消耗资源,可能会占用其他应用程序的资源。所以,我们需要始终对各自应用进行资源设置,来保证服务之间互不影响。
Containerd是属于Docker 产品的一部分。它和 CRI-O 都是标准的容器运行时实现环境。Containerd是从Docker中分离出来的底层容器运行时,使用起来和Docker并没有啥区别。它强调简单性、健壮性和可移植性。containerd可以在宿主机中管理完整的容器生命周期,包括容器镜像的传输和存储、容器的执行和管理、存储和网络等。
还有一些工具可以将容器的使用扩展到其他技术方向,比如 Kata,它允许您将容器作为 VM 运行。其他的技术旨在解决特定的容器相关问题,比如 gVisor,它在容器和操作系统之间提供了一个额外的安全层。
我们知道,容器之间是通过云原生网络机进行相互通信,当然也包括与基础设施层通信部分。
在分布式应用程序中,通常具有多个应用组件,它们需要借助网络来实现不同的目的。因此,需要在现有网络基础之上,创建出一个虚拟网络,专门用于应用程序之间的进行通信。
比如,我们日常为了完成某一项任务时,往往需要多个应用程序组合才能实现。需要办公软件Office来编写文档,演示时需要借助演示软件或远程视频,甚至需要借助聊天工具进行沟通等。
如果上面的每个组件都在自己的容器中运行。那为了让所有这些独立的部分能够作为一个有凝聚力的应用程序,容器需要提供专用通信网络。
我们知道,在容器之间流动的数据和消息可能包含敏感数据或私有数据,由于云原生网络使用软件来控制、检查和修改数据流。
因此对容器之间的管理、保护和隔离相对容易很多。而在某些情况下,您可能希望通过扩展容器网络和网络策略,比如防火墙和访问规则等,来允许应用连接到在容器网络之外运行的虚拟机或服务。而云原生网络的可编程且通常是声明性的特性使这些成为可能。
其中,容器网络接口 (CNI) 为容器化应用程序提供网络功能。如 Flannel,比较简约,提供与容器的基本连接。还有其他比如 NSX-T 提供了一个完整的软件定义的网络层,为每个 K8S命名空间创建了一个隔离的虚拟网络。
容器网络至少需要为 Pod(容器化应用在K8S中运行的地方)分配 IP 地址,以允许其他进程访问。
容器网络接口(CNI),类似于前面提到的存储和容器存储接口, 在很大程度上使这个领域的多样性和创新成为可能。
CNI 标准化了网络层向 Pod 提供功能的方式。为您的 K8S 环境选择正确的容器网络至关重要,这里有许多工具可供选择。比如Weave Net、Antrea、Calico 和 Flannel 都提供了有效的开源网络层。它们的功能差异比较大,需要结合实际场景有针对性的选择。
此外,许多供应商使用软件定义网络 (SDN) 工具支持和扩展 K8S 网络,提供对网络流量的更多检查以及实施不同网络策略,甚至已经将容器网络和策略扩展到了更广泛的数据中心。
因此,云原生网络也在逐步趋于完善,来很好地解决容器之间的网络管理和数据安全等问题。
本节内容主要介绍了云原生环境下,应用所依赖的运行时环境。通过上面的分析,我们知道了运行时环境,主要专注于保障器平台运行的正常启动和停止、如何协助容器平台存储数据、并允许相互网络通信。
另外,众多新技术的不断出现,也形成了云原生环境逐步趋于完善的一个势态。未来可期,相信云原生应用会为我们带来前所有为的业务价值和使用体验。