1.介绍
希望新的容器可以在之前容器结束的位置继续执行,使文件系统部分被持久化。卷无法单独存在,而是被定义为pod的一部分,并和pod共享生命周期。一个容器重启后,能后识别前一个容器写入卷的所有文件。如果一个pod有多个容器,那么这个卷可以被所有容器使用
- 沿用容器重启前的部分文件数据
- 容器间共享文件
2.EmptyDir卷
最简单的卷类型,用于存储临时数据的简单空目录,生命周期与pod相关联,pod删除时,卷的内容也会丢失。emptyDir的用途主要用于同一个pod中不同容器间的文件共享。卷是在实际磁盘上创建的,所以性能取决于节点磁盘的类型,但也可以通知kubernetes在tmfs文件系统中在内存上创建emptyDir
apiVersion: v1
kind: Pod
metadata:
name: fortune
spec:
containers:
- image: luksa/fortune
name: html-generator
volumeMounts:
- name: html #卷的名称
mountPath: /var/htdocs #挂载在容器的路径
- image: nginx:alpine
name: web-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html #卷的名称
readOnly: true #挂载在容器的路径
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html #卷名
emptyDir: #卷类型
medium: Memory #在内存创建卷
3.gitRepo
- 与emptyDir类似,但是使用Git仓库填充了内容。
- 缺点:pod不被资源托管创建的时候,git仓库的更新并不会与gitRepo同步,需要重新创建pod。所以使用资源管理pod的时候,需要更新gitRepo时只需要将pod删除,由资源自动从git拉取最新的代码并创建pod
apiVersion: v1
kind: Pod
metadata:
name: gitrepo-volume-pod
spec:
containers:
- image: nginx:alpine #镜像名
name: web-server #容器名
volumeMounts:
- name: html #挂载的卷名
mountPath: /usr/share/nginx/html #挂载在容器的目录位置
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html
gitRepo: #已经弃用,用EmptyDir代替。将EmptyDir挂载到使用git克隆repo的InitContainer中,然后将EmptyDir挂载到Pod的容器中。
repository: https://github.com/luksa/kubia-website-example.git #git克隆地址
revision: master #分支版本
directory: . #克隆到卷的根目录
4.HostPath卷
- 使用规范:大多数pod应该忽略主机节点,但是像被daemonSet服务(每个节点运行一个pod)托管的pod,确实有时候会读取节点的文件或者文件系统来访问节点设备。
- 特点:持久性存储,不跟emptyDir卷和gitRepo一样随着pod的销毁而销毁。生命周期大于pod,可用来在同节点上创建pod时沿用之前pod的文件。
- 注意:不建议将hostPath挂载在类似mysql的数据目录,因为pod的重新创建不一定存在于原先的工作节点,会找不到数据,所以也就是为什么说常规的pod应该忽略工作节点。不应该用来持久化跨pod的数据
apiVersion: v1
kind: Pod
metadata:
name: mongodb
spec:
volumes:
- name: mongodb-data
hostPath:
path: /tmp/mongodb #节点目录
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
5.跨界点、跨pod数据共享
5.1 GCE
在kubernetes集群内创建GCE持久磁盘
gcloud compute disks create --size=1GiB --zone=europe-west1-b mongodb
创建一个1GiB的GCE持久磁盘(并非卷),命名为mongodb
apiVersion: v1
kind: Pod
metadata:
name: mongodb
spec:
volumes:
- name: mongodb-data #卷名称
gcePersistentDisk:
pdName: mongodb #持久化磁盘名
fsType: ext4 #linux文件系统的类型
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
5.2 AWS
如果集群运行在亚马逊的AWS EC2,则需要创建aws弹性块存储而不是GCE持久硬盘
apiVersion: v1
kind: Pod
metadata:
name: mongodb-aws
spec:
volumes:
- name: mongodb-data
awsElasticBlockStore:
volumeID: my-volume
fsType: ext4
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
5.3 NFS
前提条件:kubernetes集群运行在自有的服务器上
缺点:耦合度大,需要在pod配置文件中指定nfs服务器ip地址。需要去关心底层的存储卷类型之类的问题。开发人员需要关心的是如何调取接口进行数据存储,不在乎接口底层的实现,即存储位置、存储类型。也就是说,基础设施的引用,不应该直接显示在pod配置文件中,而是像程序的接口一样,只需要明白接口如何调用,底层具体实现类不需要去知道
apiVersion: v1
kind: Pod
metadata:
name: mongodb-nfs
spec:
volumes:
- name: mongodb-data
nfs:
server: 1.2.3.4 #nfs服务器ip
path: /some/path #服务器提供的路径
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
6.底层存储技术解耦
6.1 介绍
- 管理员创建PV持久卷,并且实现了底层的存储技术(GCE、AWS、NFS等)
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodb-pv
spec:
capacity: #定义卷的大小
storage: 1Gi
accessModes: #定义卷的访问模式
- ReadWriteOnce #单节点读写
- ReadOnlyMany #多节点只读
- ReadWriteMany #多节点读写
persistentVolumeReclaimPolicy: Retain #当声明被释放后,pv卷会被保留不会被销毁
gcePersistentDisk:
pdName: mongodb #指定pv卷支持所创建的GCE持久磁盘
fsType: ext4
- 用户创建持久卷声明PVC,kubernetes会找到一个具有足够容量的PV置为访问模式,PV的访问模式必须包含PVC所声明的,然后在PVC绑定到PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-pvc #声明的名称
spec:
resources:
requests:
storage: 1Gi #申请1Gb的存储空间
accessModes:
- ReadWriteOnce #允许单节点进行读写
storageClassName: "" #看后续内容讲解
- 用户创建pod来引用持久卷pvc
apiVersion: v1
kind: Pod
metadata:
name: mongodb
spec:
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: mongodb-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
volumes:
- name: mongodb-data
persistentVolumeClaim:
claimName: mongodb-pvc #通过名称引用持久卷声明
当删除持久卷声明后,然后再创建,如果持久卷(PV)没有被释放,就还存储着之前被删除pod的数据,并且没有其他符合条件的持久卷,那此时的持久卷声明就无法找到持久卷进行绑定,就会处于pending状态,pv处于release(已释放)状态。这时候就需要去回收持久卷,回收持久卷只能删除和重新创建持久卷资源。
持久卷在创建的时候,设置spec.persistentVolumeReclaimPolicy属性可定义释放后的动作:
- Retain:持久卷会被持久化,持久卷释放的时候仍然能保留他的卷和数据,也就是外部基础设施中的存储资产(AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)仍然存在.
Recycle(已废弃,被动态制备取代):删除卷的内容并可再次声明使用卷- Delete:删除底层存储