前言
默认情况下容器的数据都是非持久化的, 在容器消亡以后数据也跟着丢失, 所以 Docker 提供了 Volume 机制以便将数据持久化存储。 类似的, Kubernetes 提供了更强大的 Volume 机制和丰富的插件, 解决了容器数据持久化和容器间共享数据的问题。 与 Docker 不同, Kubernetes Volume 的生命周期与 Pod 绑定容器挂掉后 Kubelet 再次重启容器时, Volume 的数据依然还在而 Pod 删除时, Volume 才会清理。 数据是否丢失取决于具体的 Volume 类型, 比如 emptyDir 的数据会丢失, 而 PV 的数据则不会丢 PersistentVolume(pv)和PersistentVolumeClaim(pvc)是k8s提供的两种API资源,用于抽象存储细节。管理员关注于如何通过pv提供存储功能而无需关注用户如何使用,同样的用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现。 pvc和pv的关系与pod和node关系类似,前者消耗后者的资源。pvc可以向pv申请指定大小的存储资源并设置访问模式。
pv pvc相关知识
生命周期
pv和pvc遵循以下生命周期:
- 1.供应准备。管理员在集群中创建多个pv供用户使用。
- 2.绑定。用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态。
- 3.使用。用户可在pod中像volume一样使用pvc。
- 4.释放。用户删除pvc来回收存储资源,pv将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他pvc使用。
- 5.回收。pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。
- 保留策略允许人工处理保留的数据。
- 删除策略将删除pv和外部关联的存储资源,需要插件支持。
- 回收策略将执行清除操作,之后可以被新的pvc使用,需要插件支持。
pv属性
pv拥有以下属性:
- 容量,目前仅支持存储大小,未来可能支持IOPS和吞吐量等。
- 访问模式,ReadWriteOnce:单个节点读写。ReadOnlyMany:多节点只读。ReadWriteMany:多节点读写。挂载时只能使用一种模式。
- 回收策略,目前NFS和HostPath支持回收。 AWS、EBS、GCE、PD和Cinder支持删除。
- 阶段,分为Available(未绑定pvc)、Bound(已绑定)、Released(pvc已删除但资源未回收)、Failed(自动回收失败)
pvc属性
- 访问模式,与pv的语义相同。在请求资源时使用特定模式。
- 资源,申请的存储资源数量
pv类型
- emptyDir
- hostPath
- gcePersistentDisk
- awsElasticBlockStore
- nfs
- iscsi
- flocker
- glusterfs
- rbd
- cephfs
- gitRepo
- secret
- persistentVolumeClaim
- downwardAPI
- azureFileVolume
- ................
- ........(以下省略)
目前常用Volume 类型
emptyDir
如果 Pod 设置了 emptyDir 类型 Volume, Pod 被分配到 Node 上时候, 会创建emptyDir, 只要 Pod 运行在 Node 上, emptyDir 都会存在( 容器挂掉不会导致emptyDir 丢失数据) , 但是如果 Pod 从 Node 上被删除( Pod 被删除, 或者 Pod 发生迁移) , emptyDir 也会被删除, 并且永久丢失。
hostPath
hostPath 允许挂载 Node 上的文件系统到 Pod 里面去。 如果 Pod 需要使用 Node 上的文件, 可以使用 hostPath
NFS
NFS 是 Network File Syste
m 的缩写, 即网络文件系统。 Kubernetes 中通过简单地配置就可以挂载 NFS 到 Pod 中, 而 NFS 中的数据是可以永久保存的, 同时 NFS 支持同时写操作。
gcePersistentDisk
gcePersistentDisk 可以挂载 GCE 上的永久磁盘到容器, 需要 Kubernetes 运行在 GCE的 VM 中
awsElasticBlockStore
awsElasticBlockStore 可以挂载 AWS 上的 EBS 盘到容器, 需要 Kubernetes 运行在AWS 的 EC2 上。
gitRepo
gitRepo volume 将 git 代码下拉到指定的容器路径中
Projected Volume
Projected volume 将多个 Volume 源映射到同一个目录中, 支持 secret、 downwardAPI和 configMap
简单示例
emptyDir (节点级存储,生命周期与pod相同)
pod中有两个container挂载同一个emptyDir,nginx提供web服务,busybox则循环向挂载目录下的index.html文件写入数据
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: myapp containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html - name: busybox image: busybox:latest volumeMounts: - name: html mountPath: /data command: - "/bin/sh" - "-c" - "while true; do echo $(date) >> /data/index.html; sleep 2; done" volumes: - name: html emptyDir: {}