理想情况下,在Kubernetes上部署应用程序的开发人员不需要知道集群提供了什么存储技术,就像他们不需要知道用于运行pod的物理服务器的特征一样。基础架构的细节应该由运行集群的人员来处理。
由于这个原因,当将应用程序部署到Kubernetes时,通常不会像在上一章中所做的那样,直接引用pod清单中的外部存储。相反,将使用一种间接的方法,这在下一节中解释。
前一章中的一个示例展示了如何在pod中使用NFS文件共享。pod清单中的卷定义包含NFS服务器的IP地址和该服务器文件路径。这将pod定义绑定到特定的集群,导致无法在其他地方使用这个pod。
如下图所示,如果要将这个pod部署到不同的集群,至少需要更改NFS服务器IP。这意味着pod定义不能跨集群移植。每次将其部署到新的Kubernetes集群时,都必须对其进行修改。
图8.1 包含特定于基础设施的卷信息的pod清单不能移植到其他集群
8.1.1 持久卷和持久卷声明简介
为了使pod清单在不同的集群环境中可移植,有关实际存储卷的环境特定信息被移动到PersistentVolume对象,如下图所示。persistentvolumecclaim对象将pod连接到这个PersistentVolume对象。
图8.2使用持久卷和持久卷声明将网络存储附加到pod
下面将解释这两个对象。
持久卷简介
顾名思义,PersistentVolume对象表示用于持久存储应用程序数据的存储卷。如上图所示,PersistentVolume对象存储关于底层存储的信息,并将该信息与pod解耦。
如果pod清单中没有此特定于基础设施的信息,则可以使用相同的清单在不同的集群中部署pod。当然,每个集群必须包含一个包含此信息的PersistentVolume对象。我同意这种方法似乎没有解决任何问题,因为我们只是将信息转移到不同的对象中,但稍后您将看到,这种新方法实现了以前不可能实现的事情。
持久卷声明简介
pod并不直接引用PersistentVolume对象。相反,它指向一个persistentvolumecclaim对象,然后该对象指向PersistentVolume。
顾名思义,PersistentVolumeClaim对象表示用户对持久卷的声明。因为它的生命周期没有绑定到pod的生命周期,所以它允许持久卷的所有权与pod解耦。用户在pod中使用持久卷之前,必须首先通过创建PersistentVolumeClaim对象来声明该卷。在声明了卷后,用户拥有它的独家权利,可以在他们的pod中使用它。他们可以随时删除pod,并且不会失去持久卷的所有权。当不再需要该卷时,用户通过删除PersistentVolumeClaim对象来释放它。
在Pod中使用持续卷声明
要在pod中使用持久卷,只需在其清单中引用卷绑定到的持久卷声明的名称。
例如,如果您创建了一个持久卷声明,它绑定到一个代表NFS文件共享的持久卷,那么可以通过添加指向PersistentVolumeClaim对象的卷定义,将NFS文件共享附加到pod。pod清单中的卷定义只需要包含持久卷声明的名称,不需要包含特定于基础设施的信息,比如NFS服务器的IP地址。
如下图所示,当这个pod被调度到一个工作节点时,Kubernetes找到与pod中引用的声明绑定的持久卷,并使用PersistentVolume对象中的信息将网络存储卷挂载到pod的容器中。
图8.3 将持久卷挂载到容器中
在多个pod中使用一个声明
多个pod可以使用相同的存储卷,如果它们引用相同的持久卷声明,从而传递到相同的持久卷,如下图所示。
图8.4 在多个pod中使用相同的持久卷声明
这些pod是否必须运行在相同的集群节点上,还是可以从不同的节点访问底层存储,取决于提供这种存储的技术。如果底层存储技术支持将存储并发连接到多个节点,那么不同节点上的pod可以使用它。如果不是,则必须首先将pod调度到附加存储卷的节点。
8.1.2 理解使用持久卷和持久卷声明的好处
在一个系统中,必须使用两个额外的对象才能让pod使用存储卷,这比前一章中解释的简单方法要复杂得多,在前一章中,pod只是直接引用存储卷。为什么这种新方法更好?
使用持久卷和声明的最大好处是,特定于基础设施的细节现在与pod所代表的应用程序解耦了。集群管理员比任何人都更了解数据中心,可以创建包含所有与基础设施相关的底层细节的PersistentVolume对象,而软件开发人员只关注通过Pod和PersistentVolumeClaim对象描述应用程序及其需求。
下图显示了两个用户角色及其创建的对象是如何配合在一起的。
图8.5 持久卷由集群管理员提供,pod通过持久卷声明使用。
不是由开发人员向pod中添加特定于技术的卷,而是由集群管理员设置底层存储,然后通过Kubernetes API创建一个PersistentVolume对象将其注册到Kubernetes中。
当集群用户需要在其中一个pod中进行持久存储时,它们首先创建一个PersistentVolumeClaim对象,在该对象中,它们可以通过名称引用特定的持久卷,或者指定应用程序所需的最小卷大小和访问模式,然后让Kubernetes找到满足这些需求的持久卷。在这两种情况下,持久性卷都被绑定到声明,并被授予独占访问权。然后,可以在一个或多个pod的卷定义中引用该声明。当pod运行时,在PersistentVolume对象中配置的存储卷被附加到工作节点并挂载到pod的容器中。
应用程序开发人员可以为Pod和PersistentVolumeClaim对象创建清单,而不需要了解应用程序将在其上运行的基础设施,理解这一点很重要。类似地,集群管理员可以提前提供一组大小不同的存储卷,而不需要了解将使用它们的应用程序。
此外,通过使用持久卷的dynamic provisioning(本章后面将讨论),管理员根本不需要预先提供卷。如果集群中安装了自动卷发放器(automated volume provisioner),则物理存储卷和PersistentVolume对象将根据用户创建的每个PersistentVolumeClaim对象的需要创建。
注:以上内容译自 《Kubernetes In Action,Second Edition》8.1节。阅读完整版请关注gzh 登峰大数据。