目录
???????是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是 Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统。
???????是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或 只读多次模式挂载)
静态PV:
? ? 集群管理员创建一些 PV。它们带有可供群集用户使用的实际存储的细节。它们存在于 Kubernetes API 中,可用于消费
动态PV:
????????当管理员创建的静态 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 使用。
PersistentVolume 类型以插件形式实现。Kubernetes 目前支持以下插件类型:
(1)GCEPersistentDisk????? AWSElasticBlockStore????????AzureFile?????????AzureDisk????????FC (Fibre Channel)
(2)FlexVolume????????Flocker????? NFS?????????? iSCSI????????? RBD (Ceph Block Device)???????????? CephFS
(3)Cinder (OpenStack block storage)????? Glusterfs?????????? VsphereVolume???????? Quobyte Volumes
(4)HostPath????????VMware Photon????????ortworx Volumes????????ScaleIO Volumes??????? StorageOS
apiVersion: v1
kind: PersistentVolume #资源对象类别为持久卷
metadata:
name: pv0003 #当前pvc的名字为pv0003
spec:
capacity: #容量
storage: 5Gi #存储空间为5GI
volumeMode: Filesystem #卷的模式,模拟的文件系统类型
accessModes: #返回模式
- ReadWriteOnce #单节点读写
persistentVolumeReclaimPolicy: Recycle #回收的策略
storageClassName: slow #存储类的名字,后面写一个字符串,叫什么没有意义,看公司怎么定义
mountOptions: #挂载的选项
- hard
- nfsvers=4.1 #nfs的版本
nfs: #使用nfs创建的pv
path: /tmp #服务器的共享路径在/tmp下
server: 172.17.0.2 #服务器的地址是172.17.0.2
? ? ? ?PersistentVolume可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个 PV 的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式
???????? ReadWriteOnce——该卷可以被单个节点以读/写模式挂载
???????? ReadOnlyMany——该卷可以被多个节点以只读模式挂载
???????? ReadWriteMany——该卷可以被多个节点以读/写模式挂载
在命令行中,访问模式缩写为:
???????? RWO - ReadWriteOnce
???????? ROX - ReadOnlyMany
???????? RWX - ReadWriteMany
<!--!一个卷一次只能使用一种访问模式挂载,即使它支持很多访问模式。例如,GCEPersistentDisk 可以由单个节点作为 ReadWriteOnce 模式挂载,或由多个节点以 ReadOnlyMany 模式挂载,但不能同时挂载-->
Volume 插件 | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
AWSElasticBlockStoreAWSElasticBlockStore | √ | - | - |
AzureFile | √ | √ | √ |
AzureDisk | √ | - | - |
CephFS | √ | √ | √ |
Cinder | √ | - | - |
FC | √ | √ | - |
FlexVolume | √ | √ | - |
Flocker | √ | - | - |
GCEPersistentDisk | √ | √ | - |
Glusterfs | √ | √ | √ |
HostPath | √ | - | - |
iSCSI | √ | √ | - |
PhotonPersistentDisk | √ | - | - |
Quobyte | √ | √ | √ |
NFS | √ | √ | √ |
RBD | √ | √ | - |
VsphereVolume | √ | - | - (当 pod 并列时有效) |
PortworxVolume | √ | - | √ |
ScaleIO | √ | √ | - |
StorageOS | √ | - | - |
(1)Retain(保留)——手动回收
(2)Recycle(回收)——基本擦除(`rm -rf /thevolume/*`)
(3)Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和 OpenStack Cinder 卷)将被删除.
当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS(持久存储)、GCE PD(持久化存储)、Azure Disk (亚马逊云的块存储)和 Cinder 卷(openstack的卷)支持删除策略。(都是由云服务器提供的)。
卷可以处于以下的某种状态:
(1)Available(可用)——一块空闲资源还没有被任何声明绑定
(2)Bound(已绑定)——卷已经被声明绑定
(3)Released(已释放)——声明被删除,但是资源还未被集群重新声明
(4)Failed(失败)——该卷的自动回收失败
命令行会显示绑定到 PV 的 PVC 的名称。
yum install -y nfs-common nfs-utils rpcbind
#所有K8S节点安装nfs服务
mkdir /nfsdata && cd /nfsdata/ && mkdir {1..10}
#nfs服务端创建共享目录
echo "1" >> 1/index.html
echo "2" >> 2/index.html
echo "3" >> 3/index.html
echo "4" >> 4/index.html
echo "5" >> 5/index.html
echo "6" >> 6/index.html
echo "7" >> 7/index.html
#在共享目录下创建共享文件
chown nfsnobody /nfsdata -R
#将共享目录的所有者改为nfsnobody
vim /etc/exports
#配置nfs允许客户端连接的权限
/nfsdata/1 *(rw,no_root_squash,no_all_squash,sync) #代表所有客户端都可以访问
/nfsdata/2 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/3 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/4 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/5 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/6 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/7 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/8 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/9 *(rw,no_root_squash,no_all_squash,sync)
/nfsdata/10 *(rw,no_root_squash,no_all_squash,sync)
chmod 777 -R /nfsdata/
#实验环境给777权限的原因是为了后面让容器内的用户调用共享目录时有权限连接,真实生产环境这里不应该给777,要么把docker里面的用户改成root,要么在这里映射一个虚拟用户为docker里的用户,两边用的权限得对上,要不然没权限。
systemctl start rpcbind
#先启动rpcbind
systemctl start nfs
#在启动nfs服务
showmount -e 192.168.159.81
#服务端IP,查看nfs服务的共享目录情况。
k8s的master节点配置yaml文件创建PV
vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv1
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/1
server: 192.168.159.81
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv2
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/2
server: 192.168.159.81
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv3
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/3
server: 192.168.159.81
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv4
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/4
server: 192.168.159.81
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv5
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs1
nfs:
path: /nfsdata/5
server: 192.168.159.81
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv6
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/6
server: 192.168.159.81
kubectl apply -f 1.pv.yaml
#基于yaml文件创建pv
kubectl get pv
#查看创建的pv
vim statefulset-pvc.yaml
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:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "nfs"
resources:
requests:
storage: 2Gi
kubectl apply -f statefulset-pvc.yaml
#基于yaml文件创建statefulset
kubectl get pod
kubectl get pvc
kubectl get pod -o wide
#查看pod的IP地址
curl 172.20.0.222
#访问pod的ip测试
kubectl delete pod web-1
#删除pod,删除后statefulset控制器会再拉起一个pod
kubectl get pod -o wide
#查看新pod的ip地址
curl 172.20.0.223
#访问测试,pod重拉后,数据不变。实现持久化存储的功能。
#数据不变,稳定的存储,pod是跟pvc绑定的,pvc是跟pod名绑定的,名字不变,创建一个新的,还是会保持这个pvc,这个pvc后面还是哪个pv,所以数据不变。