容器内部存储的生命周期是短暂的,会随着容器环境的销毁而销毁,具有不稳定性。如果多个容器希望共享同一份存储,则仅仅依赖容器本身是很难实现的。Kubernetes 系统中,将对容器应用所需的存储资源抽象为存储卷(Volume)概念来解决这些问题。 Volume 是与 Pod 绑定的(独立于容器)与 Pod 具有相同生命周期的资源对象。我们可以将 Volume 的内容理解为目录或文件,容器如需使用某个 Volume, 则仅需设置 volumeMounts 将一个或多个 Volume 挂载为容器中的目录或文件,即可访问 Volume 中的数据。Volume 具体是什么类型,以及由哪个系统提供,对容器应用来说是透明的。
一、将资源对象映射为存储卷
在 Kubernetes 中有一些资源对象可以以存储卷的形式挂载为容器内的目录或文件,目前有以下几种类型: (1)ConfigMap:一般用于存储容器应用需要的一些配置信息。 (2)Downward API:用于将 Pod 和容器的某些元数据信息注入容器环境内,供容器应用方便地使用。 (3)Secret:主要用于存储一些敏感认证信息。 (4)ServiceAccountToken:用于 Pod 与 API Server 之间的认证。 (5)Projected Volume:用于将一个或多个上述资源对象一次性挂载到容器内的同一个目录下。 这些资源对象以存储卷的形式挂载到 Pod 以后,在 Pod 上看到的目录或文件都是只读的。1. ConfigMap
ConfigMap 以一个或多个 key:value 的形式保存在 Kubernetes 系统中供应用使用,既可以用于表示一个变量的值(例如 apploglevel=info) ,也可以用于表示一个完整配置文件的内容(例如 server.xml=... )。(1)ConfigMap 资源对象的创建
<1>通过 YAML 文件方式创建 YAML 文件: 创建: <2>通过 kubectl 命令行方式创建 通过 --from-file 参数从文件中创建,可以指定 key 的名称,也可以在一个命令行中创建包含多个 key 的 ConfigMap,value 则是指定的文件中的内容: 通过 --from-file 参数在目录下进行创建,该目录下每个文件的名称都将被设置为 key,文件的内容则被设置为 value: (注意:子目录下的文件不会被设置为 configmap 中的配置项) 使用 --from-literal 时会从文本中进行创建,直接将指定的 key=value 创建为 ConfigMap 的内容:(2)ConfigMap 资源对象在 Pod 中的使用
<1>通过环境变量方式使用 ConfigMap 或者直接使用字段 envFrom,在 Pod 环境中自动将 ConfigMap 中所有定义的 key=value 自动生成为环境变量: <2>通过 volumeMount 使用 ConfigMap 首先在字段 volumes 中声明要使用的 ConfigMap,ConfigMap 中一个 key=value 将成为 volume 中的一个文件: 文件名称:使用 items 字段时,可以在 path 字段设置每个 key 对应的文件名称,还可以设置子目录;不使用 items 字段时,将直接使用 key 作为文件名称。 文件内容:ConfigMap 中 key 对应的 value 则成为文件的内容。 然后使用 volumeMounts 字段在容器中挂载卷,指定 volumes 中声明的卷名称和挂载的目录。(3)使用 ConfigMap 的限制条件
<1>ConfigMap 必须在 Pod 之间创建, Pod 才能引用它。 <2>如果 Pod 使用 envFrom 基于 ConfigMap 定义环境变量 ,则无效的环境变量名称(例如名称以数字开头)将被忽略,在事件中被记录为 InvalidVariableNames。 <3>ConfigMap 受命名空间限制, 只有处于相同命名空间中的 Pod 才可以引用它。 <4>ConfigMap 无法用于静态 Pod。2. Downward API
在某些应用场景中,容器内的应用需要获取 Pod 的信息。为了在容器内获取 Pod 信息, Kubernetes 提供了 Downward API 机制来将 Pod 和容器的某些元数据信息注入容器环境内,供容器应用方便地使用。 Downward API 可以通过以下两种方式将 Pod 和容器的元数据信息注人容器内部: (1)环境变量方式:将 Pod 或 Container 信息设置为容器内的环境变量。 (2)Volume 挂载方式:将 Pod 或 Container 信息以文件的形式挂载到容器内部。 实践示例如下:3. Secret
Secret 是用来存储敏感认证信息的一种重要资源,例如密码、token、密钥等。Secret 中的数据是以 base64 编码的,Secret 作为 volume 挂载到 Pod 以后,可在 Pod 上看到 base64 解码后的明文。(1)创建 Secret
(2)在 Pod 中使用 Secret
4. Projected Volume
Projected Volume 是一种特殊的存储卷类型,用于将一个或多个上述资源对象(ConfigMap、Secret、Downward API)一次性挂载到容器内的同一个目录下。 如果 Pod 希望同时挂载 ConfigMap、Secret、Downward APT,则需要设置多个不同类型的 Volume,再将每个 Volume 都挂载为容器内的目录或文件。如果应用程序希望将配置文件和密钥文件放在容器内的同一个目录下,则通过多个 Volume 就无法实现了。为了支待这种需求, Kubernetes 入了一种新的 Projected Volume 存储卷类型,用于将多种配置类数据通过单个 Volume 挂载到容器内的单个目录下。 实践示例如下:
二、Node 本地存储卷
Kubernetes 管理的 Node 地存储卷(Volume)类型如下: (1)EmptyDir:与 Pod 同生命周期的 Node 临时存储。 (2)HostPath:Node 目录。 (3)Local:基于持久卷(PV)管理的 Node 目录。1. EmptyDir
这种类型的 Volume 将在 Pod 被调度到 Node 时进行创建,在初始状态下目录中是空的,所以命名为“空目录 ”(Empty Directory),它与 Pod 具有相同的生命周期,当 Pod 销毁时, Node 上相应的目录也会被删除。同一个 Pod 中的多个容器都可以挂载这种 Volume。(1)应用场景
由于 EmptyDir 类型存储卷的临时性特点,它通常可以用于以下应用场景中: <1>基于磁盘进行合并排序操作时需要的暂存空间。 <2>长时间计算任务的中间检查点文件。 <3>为某个 Web 服务提供的临时网站内容文件。(2)存储介质
在默认情况下, kubelet 会在 Node 的工作目录下为 Pod 创建 EmptyDir 目录,这个目录的存储介质可能是本地磁盘、 SSD 磁盘或者网络存储设备,取决于环境的配置。 另外, EmptyDir 可以通过 medium 字段设置存储介质为“Memory",表示使用基于内存的文件系统(tmpfs RAM-backed filesystem)。虽然 tmpfs 的读写速度非常快,但与磁盘中的目录不同,在主机重启之后, tmpfs 的内容就会被清空。此外,写入 tmpfs 的数据将被统计为容器的内存使用量,受到容器级别内存资源上限(Memory Resource Limit)的限制(3)使用实践
创建一个挂载 EmptyDir 的 Pod: 登录 Pod,在 EmptyDir 挂载目录下写入一个文件: 在 Node 上查找这个文件,可以找到 EmptyDir 临时存储的文件位置: 删除 Pod 后,Node 上对应的 EmptyDir 临时存储也被删除:2. HostPath
HostPath 类型的存储卷用于将 Node 文件系统的目录或文件挂载到容器内部使用。(1)应用场景
对于大多数容器应用来说,都不需要使用宿主机的文件系统。适合使用 HostPath 存储卷的一些应用场景如下: <1>容器应用的关键数据需要被持久化到宿主机上。 <2>需要使用 Docker 的某些内部数据,可以将主机的 var/Iib/docker 目录挂载到容器内。 <3>监控系统,例如 cAdvisor 需要采集宿主机 /sys 目录下的内容。 <4>Pod 的启动依赖于宿主机上的某个目录或文件就绪的场景。(2)宿主机路径类型
HostPath 存储卷的主要配置参数为 path,设置为宿主机的目录或文件路径;还可以设置一个可选的参数 type,表示宿主机路径的类型。目前支待的 type 配置参数和校验规则如下:(3)使用实践
创建一个挂载 HostPath 的 Pod: 登录 Pod,在 HostPath 挂载目录下写入一个文件: 在 Node 上可以找到这个文件,且 Pod 删除后,HostPath 对应的目录和文件都还存在:
参考: 《Kubernetes 权威指南第 5 版》 标签:Node,容器,存储,Kubernetes,ConfigMap,Volume,挂载,Pod,目录 From: https://www.cnblogs.com/wujuntian/p/18100420