kubernetes系列(十四) - 存储之PersistentVolume
- 1. PersistentVolume(PV)简介
- 2. PersistentVolume(PV)的分类
- 3. PersistentVolumeClaim(PVC)的保护
- 4. PersistentVolume(PV)支持的底层存储类型
- 5. PersistentVolume(PV)的资源清单
- 6. PersistentVolume(PV)的状态
- 7. 实验-持久化演示说明-NFS
- 8. 关于 Statefulset
1. PersistentVolume(PV)简介
1.1 为什么需要Persistent Volume(PV)
在将PersistentVolume(PV)之前,我们需要先讲一下Volume
Volume详情可见上一章: kubernetes系列(十三) - 存储之Volume
Volume是被定义在pod上的(emptyDir或者hostPath),属于计算资源的一部分。所以Volume是有局限性的,因为在实际的运用过程中,我们通常会先定义一个网络存储,然后从中划出一个网盘并挂接到虚拟机上。
为了屏蔽底层存储实现的细节,让用户方便使用,同时让管理员方便管理。Kubernetes从V1.0版本就引入了PersistentVolume(PV)和与之相关联的PersistentVolumeClaim(PVC)两个资源对象来实现对存储的管理
1.2 PersistentVolume(PV)和Volume的区别
PV可以被理解成kubernetes集群中的某个网络存储对应的一块存储,它与Volume类似,但是有如下的区别:
- PV只能是网络存储,不属于任何
Node,但是可以在每个Node上访问 - PV不是被定义在pod上,而是独立在pod之外被定义的。
- 意味着
pod被删除了,PV仍然存在,这点与Volume不同
- 意味着
1.3 PV和PVC更具体的概念和关系
1.3.1 PersistentVolume(PV)
PersistentVolume(PV)是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV也是集群中的资源。PV是Volume之类的卷插件,但具有独立于使用PV的Pod的生命周期。此API对象包含存储实现的细节,即NFS、iSCSl或特定于云供应商的存储系统。
1.3.2 PersistentVolumeClaim(PVC)
PersistentVolumeClaim(PVC)是用户存储的请求。它与Pod相似。Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或只读多次模式挂载)
1.3.3 PV和PVC的关系和图解
pvc是一种pv的请求方案,PVC定义我当前需要什么样类型的PV,然后会自动在当前存在的pv中选取一个匹配度最高的pv
一个PVC只能绑定一个PV!!

2. PersistentVolume(PV)的分类
2.1 静态PV
简单来说
由集群管理员手动创建的一些PV
完整的概念
集群管理员创建一些PV。它们带有可供群集用户使用的实际存储的细节。它们存在于KubernetesAPl中,可用于消费。
2.2 动态PV
简单来说
配置了允许动态PV的策略后,如果当前存在的PV无法满足PVC的要求,则会动态创建PV.
动态PV了解即可
完整的概念
当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses,所以要启用基于存储级别的动态存储配置要求:
- PVC必须请求
StorageClasses - 管理员必须创建并配置
StorageClasses才能进行动态创建 - 声明该类为“”可以有效地禁用其动态配置
- 集群管理员需要启用
API server上的DefaultStorageClass[准入控制器]。例如,通过确保DefaultStorageClass位于API server组件的--admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作
3. PersistentVolumeClaim(PVC)的保护
PVC保护的目的是确保由pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失 当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不再被任何 pod使用
4. PersistentVolume(PV)支持的底层存储类型
PersistentVolume类型以插件形式实现. kubernetes目前支持以下类型(排名不分先后):
跟上一集中的volume支持的类型差不多
GCEPersistentDiskAWSElasticBlockStoreAzureFileAzureDiskFC(Fibre Channel)FlexVolumeFlockerNFSiSCSIRBD(Ceph Block Device)CephFSCinder(OpenStack block storage)GlusterfsVsphereVolumeQuobyteVolumesHostPathVMwarePhotonPortworx VolumesScalelo VolumesStorageOS
5. PersistentVolume(PV)的资源清单
5.1 资源清单示例
apiVersion: v1
kind: PersistentVolume
metadata:
name:pve003
spec:
capacity:
# 卷的大小为5G
storage: 5Gi
# 存储卷的类型为:文件系统
volumeMode: Filesystem
# 访问策略:该卷可以被单个节点以读/写模式挂载
accessModes:
- ReadNriteOnce
# 回收策略:回收
persistentVolumeReclaimPolicy: Recycle
# 对应的具体底层存储的分级
# 比如有些固态或者其他存储类型比较快,就可以定义为strong
storageClassName: slow
# (可选的)挂载选项
mountOptions:
- hard
- nfsvers=4.1
# 具体对应的真实底层存储类型为nfs
# 挂载到172服务器下的/tmp目录
nfs:
path: /tmp
server: 172.17.0.2
5.2 PV的访问模式(spec.accessModes)
5.2.1 三种访问模式
访问模式accessModes一共有三种:
ReadWriteOnce: 该卷可以被单个节点以读/写模式挂载ReadOnlyMany: 该卷可以被多个节点以只读模式挂载ReadWriteMany: 该卷可以被多个节点以读/写模式挂载
在命令行cli中,三种访问模式可以简写为:
RWO-ReadWriteOnceROX-ReadOnlyManyRWX-ReadWriteMany
但不是所有的类型的底层存储都支持以上三种,每种底层存储类型支持的都不一样!!
5.2.2 各种底层存储具体支持的访问模式
| Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
|---|---|---|---|
| AWSElasticBlockStore | ✓ | - | - |
| AzureFile | ✓ | ✓ | ✓ |
| AzureDisk | ✓ | - | - |
| CephFS | ✓ | ✓ | ✓ |
| Cinder | ✓ | - | - |
| FC | ✓ | ✓ | - |
| FlexVolume | ✓ | ✓ | - |
| Flocker | ✓ | - | - |
| GCEPersistentDisk | ✓ | ✓ | - |
| Glusterfs | ✓ | ✓ | ✓ |
| HostPath | ✓ | - | - |
| iSCSI | ✓ | ✓ | - |
| PhotonPersistentDisk | ✓ | - | - |
| Quobyte | ✓ | ✓ | ✓ |
| NFS | ✓ | ✓ | ✓ |
| RBD | ✓ | ✓ | - |
| VsphereVolume | ✓ | - | - |
| PortworxVolume | ✓ | - | ✓ |
| ScaleIO | ✓ | ✓ | - |
5.3 PV的回收策略(spec.persistentVolumeReclaimPolicy)
5.3.1 回收策略的三种策略
Retain(保留): pv被删除后会保留内存,手动回收Recycle(回收): 删除卷下的所有内容(rm-rf /thevolume/*)Delete(删除): 关联的存储资产(例如AWS EBS、GCE PD、Azure Disk 和OpenStack Cinder卷)将被删除。即直接把卷给删除了
5.3.2 回收策略注意事项
- 当前,只有
NFS和HostPath支持Recycle回收策略
最新版本中的
Recycle已被废弃,截图如下
附:具体官网文档详细说明链接点击此处

- AWS EBS、GCE PD、Azure Disk 和Cinder 卷支持
Delete删除策略
6. PersistentVolume(PV)的状态
PV可以处于以下的某种状态:
Available(可用): 块空闲资源还没有被任何声明绑定Bound(已绑定): 卷已经被声明绑定, 注意:但是不一定不能继续被绑定,看accessModes而定Released(已释放): 声明被删除,但是资源还未被集群重新声明Failed(失败): 该卷的自动回收失败
命令行会显示绑定到PV的PVC的名称
7. 实验-持久化演示说明-NFS
注:以下内容笔者没有实际尝试过,仅做记录使用
7.1 安装NFS服务器
yum install -y nfs-common nfs-utils rpcbind
mkdir /nfsdata
chmod 777 /nfsdata
chown nfsnobody /nfsdata
cat /etc/exports /nfsdata *(rw,no_root_squash,no_all_squash,sync)
systemctl start rpcbind
systemctl start nfs
7.2 在其他节点上安装客户端
yum -y install nfs-utils rpcbind
mkdir /test
showmount -e 192.168.66.100
mount -t nfs 192.168.66.100:/nfsdata /test/
cd /test/
ls
umount /test/
7.3 部署PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv1
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata
server: 192.168.66.100
7.4 创建服务并使用PVC
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: k8s.gcr.io/nginx-slim:0.8
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: 1Gi
8. 关于 Statefulset
StatefulSet为每个Pod副本创建了一个DNS域名,这个域名的格式为:S(podname).(headless servername)
也就意味着服务间是通过Pod域名来通信而非PodIP,因为当Pod所在Node发生故障时,Pod会被飘移到其它 Node上,PodIP会发生变化,但是Pod域名不会有变化
StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN为:S(servicename).$(namespace).svc.cluster.local
其中,“cluster.local”指的是集群的域名
- 根据
volumeClaimTemplates,为每个Pod 创建一个pvo,pvc的命名规则匹配模式:
(volumeClaimTemplates.name)-(pod_name)
比如上面的
volumeMounts.name=www,Podname-web-[0-2],因此创建出来的PVC是www-web-0、www-web-1、 www-web-2
- 删除 Pod 不会删除其pvc,手动删除 pvc将自动释放pv
- Statefulset的启停顺序:
- 有序部署:部罢Statefulset时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。
- 有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
- 有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。
- Statefulset使用场景:
- 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC 来实现。
- 稳定的网络标识符,即Pod 重新调度后其iPodName 和 HostName不变。
- 有序部署,有序扩展,基于init containers 来实现。
- 有序收缩。
kubernetes系列(十四) - 存储之PersistentVolume的更多相关文章
- kubernetes系列(十二) - 存储之Secret
1. Secret简介 2. Secret类型 3. Service Account 4. Opaque 4.1 Opaque类型说明 4.2 Opaque创建方式 4.2.1 命令行创建 4.2.2 ...
- struts2官方 中文教程 系列十四:主题Theme
介绍 当您使用一个Struts 2标签时,例如 <s:select ..../> 在您的web页面中,Struts 2框架会生成HTML,它会显示外观并控制select控件的布局.样式和 ...
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 闯祸了,生成环境执行了DDL操作《死磕MySQL系列 十四》
由于业务随着时间不停的改变,起初的表结构设计已经满足不了如今的需求,这时你是不是想那就加字段呗!加字段也是个艺术活,接下来由本文的主人咔咔给你吹. 试想一下这个场景 事务A在执行一个非常大的查询 事务 ...
- MP实战系列(十四)之分页使用
MyBatis Plus的分页,有插件式的,也有其自带了,插件需要配置,说麻烦也不是特别麻烦,不过觉得现有的MyBatis Plus足以解决,就懒得配置插件了. MyBatis Plus的资料不算是太 ...
- Kubernetes 系列(四):使用Traefik访问.net core api
一. 准备 本篇的要求是在前三篇的基础上已经搭建好的本地k8s以及部署了Traefik,我们将会使用Traefik Ingress来访问.net core api,比较简单,做个记录,如果还没有搭建k ...
- Docker系列(十四):Kubernetes API和源码分析
Kubernetes API入门 Ku8 eye开源项目
- kubernetes实战(十四):k8s持久化部署gitlab集成openLDAP登录
1.基本概念 使用k8s安装gitlab-ce,采用GlusterFS实现持久化(注意PG使用的是NFS存储,使用动态存储重启postgresql的pod后无法成功启动pg,待解决),并集成了open ...
- kubernetes系列(十六) - Helm安装和入门
1. helm简介 1.1 为什么需要helm 1.2 helm中几个概念 1.3 helm用途 2. helm安装 3. helm的基本使用 3.1 安装chart仓库里面的chart 3.2 创建 ...
随机推荐
- Nice Jquery Validator 事件
订阅 .on("validation") 描述:每次验证完一个字段,都会触发 validation 事件,通过该事件可以获取到当前验证字段的验证结果. 示例: $('#form') ...
- Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算
前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...
- 别人开发三年30k,而我才12K,看完他面试前狂刷的面试题,我惊了
朋友做Java开发三年多的时间了,在老东家勤勤恳恳工作了三年多,工资也就是从刚开始的8K涨到了12K,天天给我吐槽他的工资低.2019年中下旬开始就一直在各种地方找资源,刷面试题,想要“骑驴找马”,所 ...
- (十一)Maven运行TestNG的testcase 两种方式:testng.xml和testngCase.java
原文:https://blog.csdn.net/wwhrestarting/article/details/46596869?utm_source=copy 1.通过maven-surefire-p ...
- 【01JMeter基础】线程组
线程组 我们存在接口请求的地方,在JMeter中我们使用最多的模块,分为 setUp线程组.线程组.tearDown线程组 setUp线程组:不论如何排序,都会在所有的线程组中被最早执行,如果有多个s ...
- cc28c_demo.cpp,派生类的构造函数和析构函数-代码示范3
cc28c_demo.cpp,派生类的构造函数和析构函数-代码示范3 //派生类的构造函数和析构函数//派生类的构造函数(执行步骤)//--执行基类的构造函数//--执行成员对象的构造函数//--执行 ...
- Centos中使用virtualenvwrapper
Centos中使用virtualenvwrapper python特有的一种软件环境,创建多个python环境,各个环境之间完全隔离,互不影响.它可以用来解决Python项目开发和运行过程中的依赖项和 ...
- debug PostgreSQL 9.6.18 using Eclipse IDE on CentOS7
目录 debug PostgreSQL 9.6.18 using Eclipse IDE on CentOS7 1.概览 2.建立用户 3.编译postgre 4.启动Eclipse 5.设置环境变量 ...
- Linux上的Systemctl命令
LinuxSystemctl是一个系统管理守护进程.工具和库的集合,用于取代System V.service和chkconfig命令,初始进程主要负责控制systemd系统和服务管理器.通过Syste ...
- vue多个项目公共化组件方案
前言 最近项目需求,需要把两个vue项目多个一样的模块抽成公共化.考虑采用的方案 1.把公共部分独立出来一个项目,npm发布私有包,使用的项目npm install下载(目前下载使用出现配置错误) 存 ...