Volumn 可以理解成一块磁盘,可以被 mount 到 pod 的容器中。
Volumn 存在的目的是:
- Pod 中多容器共享文件
- 即使是单容器,volumn 中的内容也可以在容器重启后保留
- 对容器产生的文件进行持久化
- 预先填充某些文件到容器运行时的某一目录中
Volumn 不是全局资源,而是属于某一 pod 的资源。
Volumn 跟随 pod 的生命周期,在 pod 中容器运行前准备好,在 pod 被销毁时也销毁;这也意味着,pod 中容器重启时,volumn 中的内容仍然存在。
示例
如上所示该 pod 有两个 volumn,三个容器。publicHtml volumn 被 WebServer 和 ContentAgent 分别 mount 到了不同的目录上,即 WebServer 的 /var/htdocs
目录的内容会与 ContentAgent 的 /var/html
一致。
Volumn 的类型
常见的几种,但是它们不是持久化的:
emptyDir
:空目录,该 volumn 初始内容为空hostPath
:volumn 映射到宿主机的某个目录gitRepo
:用 git 仓库提前填充好 volumn 的内容
特殊的:
configMap
,secret
,downwardAPI
将 k8s 集群的资源和信息暴露到 pod 中。persistentVolumeClaim
,后面详谈
此外还有大量基于网络存储的(如 cephfs
),基于云厂商的(如 gcePersistentDisk
)。
持久化存储
使用厂商提供的 volumn type,比如 gcePersistentDisk
;或者在自建机房使用基于网络的 volumn(比如 nfs
),可以实现持久化存储。
但这样存在一个问题,比如你需要在 pod 中描述 NFS volumn 的 server 地址:
volumes:
- name: mongodb-data
nfs:
server: 1.2.3.4
path: /some/path
这会导致:
- Kubernetes 存在的一大目的是使开发者不用关心基础设施,但在 pod 中描述 NFS 地址破坏了这一点
- NFS server 地址在别的集群中可能不一样,使得这份 pod 描述不通用
k8s 定义了 PersistentVolumes 和 PersistentVolumeClaims 来解决这个问题。