目录
emptyDir
hostPath
存储PV-PVC
emptyDir用法;
- 暂存空间;例如用于基于磁盘的合并排序
- 用作长时间计算崩溃恢复时的检查点
- Web服务器容器需要提供一些固定数据;保存内容管理器的容器提取的文件
例子;
vim emptyVolume-demo-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: empty-volume
spec:
containers:
- image: nginx:1.16
name: nginx-empty-demo
volumeMounts:
- mountPath: /cache # 容器里的挂载地址
name: cache-volume # 指定volume;即通过哪个目录进行挂载的
volumes:
- name: cache-volume
emptyDir: {}
运行并查看
kubectl apply -f emptyVolume-demo-pod.yaml
也可以查看pod的描述进行确认
kubectl describe pod empty-volume
注意;当创建的Pod中存在两个或者多个container的时候;所有的container共享emptyDir;进入一个container在挂载目录下创建一个文件;其他container查看时;都会看到文件变化了。
想做实验的可以copy如下配置文件;直接apply即可。
apiVersion: v1
kind: Pod
metadata:
name: empty-volume2
spec:
containers:
- image: nginx:1.16
name: nginx-empty-demo
volumeMounts:
- mountPath: /cache
name: cache-volume
- image: busybox:latest
name: busybox-empty-demo
imagePullPolicy: IfNotPresent
command: [;/bin/sh;,;-c;,;sleep 6000s;]
volumeMounts:
- mountPath: /test # cahnge mount dir
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
hostPath卷是将主机节点中的文件系统中的文件或者目录挂载到集群中
hostPath用途如下;
- 运行需要访问docker内部的容器;使用/var/lib/docker的hostPath
- 在容器中运行cAdvisor; 使用/dev/cgroups的hostPath
除了所需path之外;用户还可以为hostPath指定type
值行为空空字符串;默认;用于向后兼容;这意味着在挂载hostPath卷之前不会执行任何检查DirectoryOrCreate如果在给定的路径上没有任何东西存在;那么将根据需要在那里创建一个空目录;权限设置为0755;与kubectl具有相同的组合所有权Directory给定的路径下必须存在目录FireOrCreate如果给定的路径没有东西;则创建一个空文件;权限设置为0644;与kubectl 具有相同的组和所有权File给定的路径下必须存在文件socket给定的路径下必须存在 unix套接字charDevice给定的路径下必须存在字符设备BlockDevice给定的路径下必须存在块设备例子;
vim hostpath-demo-01.yaml
apiVersion: v1
kind: Pod
metadata:
# 这里注意;pod name的命名规则是小写
name: hostpath-demo
spec:
containers:
- image: nginx:1.16
name: nginx-container
volumeMounts:
- mountPath: /test-hp
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /opt/data
# this field is optional
type: Directory
运行并查看;在运行起来后;可以进入创建的容器;并在容器中/test-hp挂载目录下创建一个文件;这时候可以看到node物理机的/opt/data目录下也会出现该文件。
试着删除该pod;宿主机上的文件并不会被删除;重启启动pod后;可以继续使用该文件;但是不同的宿主机都在各自的目录下;有一份自己的文件;并没有做到唯一性。如果想要做到统一存储;就要用到PV-PVC。
kubectl apply -f hostpath-demo-01.yaml
PersistentVolume;PV;
是由管理员设置的存储;是集群的一部分;就像 节点是集群的资源一样;pv也是集群的资源。PV是Volume之类的卷插件;但具有独立于使用PV的Pod的声明周期。此API对象包含存储实现的细节;即NFS、iSCSI或特定于云供应商的存储系统。
PersistentVolumeClaim;PVC;
是用户存储的请求;它与Pod相似。Pod消耗节点资源;PVC消耗PV资源。Pod可以请求特定级别的资源;CPU和内存;。声明可以请求特定的大小和访问模式;例如;可以读/写一次或只读多次模式挂载;
静态PV
集群管理员创建一些PV;他们带有可供集群用户使用的实际存储的细节。他们存在于Kubernetes API 中;可用于消费。
动态
当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时;集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses;PVC必须请求;存储类;;并且管理员必须创建并配置该类才能进行动态地创建。声明该类为“”可以有效的禁用其动态配置。
要启动基于存储级别的动态存储配置;集群管理员需要启用API server上的DefaultStorageClass[准入控制器]。例如;通过确保[DefaultStorageClass]位于API server组件的--admission-control标志;使用逗号分隔的有序值列表中;可以完成此操作。
绑定
master中的控制环路监视新的PVC;寻找匹配的PV;并将他们绑定在一起;如果为新的PVC动态调配PV;则该环路将时钟将该PV绑定到PVC。否则;用户总会得到他们所请求的存储;但是容量可能超出要求的数据;一旦PV和PVC绑定后;PersistentVolumeClaim绑定是排他性的;不管他们是如何绑定的;PVC跟PV绑定是一对一的映射。
持久化卷声明的保护
PVC保护的目的是确保由Pod正在使用的PVC不会从系统中移除;因为如果被移除的话可能会导致数据丢失。
当pod状态为pending并且pod已经分配给节点或pod为running状态时;PVC处于活动状态。
当启用PVC保护alpha功能时;如果用户删除了一个pod正在使用的PVC;则该PVC不会被立即删除。PVC的删除将被推迟;直到PVC不再被任何pod所使用。
PV的访问模式
每个pv都有一套自己的用来描述特定功能的访问模式
ReadWriteOnce 该卷可以被单个节点以读写的模式挂载ReadOnlyMany 该卷可以被多个节点以只读模式挂载ReadWriteMany 该卷可以被多个节点以读写模式挂载
回收策略 persistentVolumeReclaimPolicy
retain(保留) 手动回收Recycle ;回收; 基本擦除 ;rm -rf /volume/*;delete;删除; 关联的存储资产将被删除
pv卷支持的多种状态
available 一块空闲资源还没有被任何声明绑定bound 卷已经被绑定了released 声明被删除;但是资源还未被集群重新声明failed 自动回收失败
原理图
示例;
远程的nfs已经创建完成;并且在k8s的node节点可以正常挂载。
vim pv-volume-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv1
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce # only one role can read or write
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /data/syn # 远程nfs创建的目录
server: 188.2.139.31 # 远程nfs的IP地址
创建PV
kubectl create -f pv-volume-demo.yaml
删除PV时;在pod未占用PV的情况下;通过删除PVC可以自动删除PV;注意创建完成PV后;并不会自动创建PVC;只有创建pod时;k8s才会创建PVC绑定pod跟相关的PV
kubectl delete pvc --all
# 也可以指定PVC进行删除
kubectl get pvc
kubectl delete pvc [pvc-name]
查看;
[root;aa /home/k8s_config/volume/pv]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
nfspv1 1Gi RWO Retain Available nfs 4m10s Filesystem
[root;aa /home/k8s_config/volume/pv]# kubectl describe pv nfspv1
Name: nfspv1
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs
Status: Available
Claim:
Reclaim Policy: Retain
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 1Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 188.2.139.31
Path: /data/syn
ReadOnly: false
Events: <none>
创建一个StatefulSet
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: ;nginx;
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [;ReadWriteOnce;] # 前面创建的PV也要时rwo
storageClassName: ;nfs; # 要与前面创建的PV保持一致
resources:
requests:
storage: 1Gi
查看;发现第一个pod已经绑定了;第二个pod状态时pending;第三个pod还未创建;前一个pod运行成功后;才创建下一个pod。
可以创建多个PV来实现同类型的不同pod绑定。
再创建两个PV;可以看到三个pod运行均正常了
再查看PV;可以看到三个PV都绑定到对应的PVC上了
注意;StatefulSet创建的pod删除后;k8s会自动重建;并且创建后的pod name不会变;但是cluster IP会变;并且保存在nfs存储中的文件并不会丢失。这是因为服务间是通过域名来通信的而非Pod IP;当Pod所在Node发生故障时;Pod会漂移到其他的Node上;Pod IP会发生变化;但是Pod域名不会发生变化。
想做上面的实现的话;执行下面的配置文件即可
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: ;nginx;
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
- image: busybox:latest
name: busybox-empty-demo
imagePullPolicy: IfNotPresent
command: [;/bin/sh;,;-c;,;sleep 6000s;]
volumeMounts:
- mountPath: /test # cahnge mount dir
name: www
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [;ReadWriteOnce;]
storageClassName: ;nfs;
resources:
requests:
storage: 1Gi
删除Pod并不会删除其PVC;手动删除PVC将会自动释放PV。删除顺序是;删除StatefulSet-->删除PVC-->系统会自动释放PV。所有的资源需要手动删除。