目录
一、存储卷的作用
二、数据卷概述
三、数据卷emptyDir
四、数据卷hostPath
五、数据卷:NFS
六、持久卷概述
6.1PV静态供给
6.2PV 动态供给(StorageClass)
6.3 PV 生命周期
6.3.1 ACCESS MODES (访问模式)
6.3.2 RECLAIM POLICY (回收策略)
6.3.3 STATUS (状态)
6.3.4PV和PVC生命周期
一、存储卷的作用
容器部署过程中一般有以下三种数据:
• 启动时需要的初始数据,例如配置文件
• 启动过程中产生的临时数据,该临时数据需要多个容器间共享
• 启动过程中产生的持久化数据, 例如MySQL的data目录
二、数据卷概述
• Kubernetes中的Volume提供了在容器中挂载外部存储的能力
• Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后才可以使用相应的Volume
数据卷类型大致分类:
• 本地(hostPath , emptyDir等)
• 网络(NFS , Ceph , GlusterFS等)
• 公有云(AWS EBS等)
• K8S资源(configmap , secret等)
三、数据卷emptyDir
emptyDir卷: 是一个临时存储卷,与Pod生命周期绑定一起,如果 Pod删除了卷也会被删除。
应用场景: Pod中容器之间数据共享
官方示例: 卷 | Kubernetes
创建emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /data
- name: read
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data ## 挂载点
volumes:
- name: data
emptyDir: {} ## 数据卷类型
emptyDir会在 pod 所在的本地创建一个empty-Dir文件夹存放挂载的文件
进入 write容器内, 我们可以看到 /data/hello 文件写入正常
四、数据卷hostPath
hostPath卷:挂载Node文件系统(Pod所在节点)上文件或者目 录到Pod中的容器。
应用场景: Pod中容器需要访问宿主机文件
官方示例:卷 | Kubernetes
创建hostPath.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 36000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
hostPath:
path: /tmp
type: Directory
查看 hostpath-pod所在的节点
五、数据卷:NFS
NFS数据卷: 提供对NFS挂载支持, 可以自动将NFS共享,路径挂载到Pod中
NFS:是一个主流的文件共享服务器。
# 安装包,所有访问共享文件的 服务器
yum install nfs-utils
## 编辑配置
vi /etc/exports
/ifs/kubernetes *(rw,no_root_squash)
## 创建共享文件夹
mkdir -p /ifs/kubernetes
systemctl start nfs
systemctl enable nfs
注:每个Node上都要安装nfs-utils包
把k8s-node1 作为 NFS Server 创建数据存储路径
在 k8s-master1节点手动挂载/mnt 目录到 NFS Server
[root@k8s-master1 ~]# mount -t nfs 192.168.2.118:/ifs/kubernetes /mnt
[root@k8s-master1 ~]# umount /mnt
在 k8s-master1 节点的 /mnt 目录下创建文件 验证 nfs 挂载 是否成功
创建nginx-nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: depployment-nfs
spec:
selector:
matchLabels:
app: nginx-nfs
replicas: 3
template:
metadata:
labels:
app: nginx-nfs
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
nfs:
server: 192.168.2.118
path: /ifs/kubernetes
创建3个nfs pod
我们进入容器 并创建 index.html , 在 k8s-node1 访问 成功
六、持久卷概述
kubernetes支持的存储系统有很多,要求客户全都掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用,kubernetes引入PV和PVC两种资源对象。
- PV全称叫做 Persistent Volume,持久化存储卷。它是用来描述或者说用来定义一个存储卷的,这个通常都是由运维工程师来定义。
- PVC的全称是Persistent Volume claim,是持久化存储的请求。它是用来描述希望使用什么样的或者说是满足什么条件的PⅣ存储。
PVC的使用逻辑:在Pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候直接指定大小,PVC必须与对应的PV建立关系,PVC会根据配置的定义去PV申请,而PV是由存储空间创建出来的。PV和 PVC是Kubernetes 抽象出来的一种存储资源。
PV是存储资源的抽象,PV资源是属于集群资源,跨namespace(不受命名空间隔离)
PV资源清单文件:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
nfs: # 存储类型,与底层真正存储对应
capacity: # 存储能力,目前只支持存储空间的设置
storage: 2Gi
accessModes: #访问模式
storageClassName: #存储类别
persistentVolumeReclaimPolicy: #回收策略PV的关键配置参数说明:
存储类型
底层实际存储的类型,kubernetes支持多种存储类型(nfs、cifs、glusterfs等),每种存储类型的配置都有所差异
存储能力(capacity)
目前只支持存储空间的设置( storage=1Gi ),不过未来可能会加入IOPS、吞吐量等指标的配置
访问模式(accessModes)
用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
ReadWriteOnce (RWO) :读写权限,但是只能被单个节点挂载
ReadOnlyMany (ROX) :只读权限,可以被多个节点挂载
ReadWriteMany (RWX) :读写权限,可以被多个节点挂载
需要注意的是,底层不同的存储类型可能支持的访问模式不同
回收策略(persistentVolumeReclaimPolicy)
当PV不再被使用了之后,对其的处理方式。目前支持三种策略:
Retain (保留) 保留数据,需要管理员手工清理数据
Recycle (回收) 清除PV中的数据,效果相当于执行rm -rf /thevolume/*
Delete (删除) 与PV相连的后端存储完成volume的删除操作,当然这常见于云服务商的存储服务
需要注意的是,底层不同的存储类型可能支持的回收策略不同
存储类别
PV可以通过storageClassName参数指定一个存储类别
具有特定类别的PV只能与请求了该类别的PVC进行绑定
未设定类别的PV则只能与不请求任何类别的PVC进行绑定
状态(status)
一个PV的生命周期中,可能会处于4种不同的阶段:
Available(可用):表示可用状态,还未被任何PVC绑定
Bound(已绑定):表示PV已经被PVC绑定
Released(已释放):表示PVC被删除,但是资源还未被集群重新声明
Failed(失败):表示该PV的自动回收失败
6.1PV静态供给
创建pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/kubernetes
server: 192.168.2.118
创建deployment-pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: depployment-pvc
spec:
selector:
matchLabels:
app: nginx-pvc
replicas: 3
template:
metadata:
labels:
app: nginx-pvc
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-pvc ## 引用PVC
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes: ## 读写权限
- ReadWriteMany
resources:
requests: ## 请求的资源大小
storage: 1Gi
创建my-pv ,资源1G
创建deployment-pvc.yaml 使用的 my-pv ,使用存储1G ,权限为 读写执行
我们 修改nginx 容器 内容的修改,访问成功。说明创建 PV 是 OK的。
6.2PV 动态供给(StorageClass)
现在PV使用方式称为静态供给,需要K8s运维工程师提前创建一堆PV,供开发者使用。
上面介绍的PV和PVC模式是需要运维人员先创建好PV,然后开发人员定义好PVC进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,kubernetes提供一种自动创建PV的机制,叫storageclass,它的作用就是创建PV的模板。
创建StorageClass需要定义PV的属性,比如存储类型、大小等:另外创建这种PV需要用到的存储插件,比如ceph等。
有了这两部分信息,Kubernetes就能够根据用户批交的 PVC,找到对应的 storageClass,然后 Kubernetes就会调用storageClass声明的存储插件,自动创建需要的PV并进行绑定。
因此, K8s开始支持PV动态供给, 使用StorageClass对象实现。存储类 | Kubernetes
基于NFS实现PV动态供给
部署NFS实现自动创建PV插件
# 授权访问apiserver
kubectl apply -f rbac.yaml
# 部署插件,需修改里面NFS服务器地址与共享目录
kubectl apply -f deployment.yaml
# 创建存储类
kubectl apply -f class.yaml
创建 rbac.yaml
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
创建deployment.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 192.168.2.118 ## NFS服务器 k8s-node1
- name: NFS_PATH
value: /ifs/kubernetes
volumes:
- name: nfs-client-root
nfs:
server: 192.168.2.118
path: /ifs/kubernetes ## 数据共享目录
创建 class.yaml 存储类
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
archiveOnDelete: "true"
创建存储类 并查看
kubectl apply -f rbac.yaml deployment.yaml class.yaml
kubectl get sc # 查看存储类
创建deployment-sc.yaml web示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: depployment-sc
spec:
selector:
matchLabels:
app: nginx-sc
replicas: 3
template:
metadata:
labels:
app: nginx-sc
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-pvc3 ## 引用PVC
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc3
spec:
storageClassName: "managed-nfs-storage" ## 通知 storageclass 自动创建 PV
accessModes: ## 读写权限
- ReadWriteMany
resources:
requests: ## 请求的资源大小
storage: 2Gi ## 资源大小 2G
动态创建 pv 绑定请求 my-pvc3 , nginx-sc pod 成功申请到了 2G 的资源
NFS server服务器的路径 /ifs/kubernetes 下会自动创建 my-pvc3 的存储路径
我们可以 成功访问 index.html
删除deployment-sc pod
kubectl delete -f deployment-sc.yaml
使用 Delete (删除) 回收策略, PVC删除后,动态创建的PV 也会删除
小结
动态创建了PV资源,通过PVC申请使用PV资源,将PVC与PV进行绑定,最后Pod通过引用PVC来使用PV资源(也就是pod最后间接的使用到底层的存储资源)
即在pod中声明要使用的PVC,然后将容器的目录挂载到PVC所指定的PV上,最后挂载到PV上的容器内的目录下的所有文件会同时持久化到nfs对应的共享目录中。因为容器内的被挂载目录是通过PVC引用挂载到PV上,而PV又是建立在nfs存储之上,也就是最后的数据会持久化到PV所声明的nfs服务器的对应共享目录下。
6.3 PV 生命周期
6.3.1 ACCESS MODES (访问模式)
AccessModes 是用来对PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
• ReadWriteOnce (RWO):读写权限,但是只能被单个节点挂载
• ReadOnlyMany (ROX):只读权限,可以被多个节点挂载
• ReadWriteMany (RWX):读写权限,可以被多个节点挂载
6.3.2 RECLAIM POLICY (回收策略)
目前PV 支持的策略有三种:
• Retain (保留): 保留数据,需要管理员手工清理数据
• Recycle (回收):清除 PV 中的数据,效果相当于执行rm -rf /ifs/kuberneres/*
• Delete (删除):与 PV 相连的后端存储同时删除
6.3.3 STATUS (状态)
一个PV 的生命周期中,可能会处于4中不同的阶段:
• Available (可用):表示可用状态,还未被任何 PVC 绑定
• Bound (已绑定):表示 PV 已经被PVC 绑定
• Released (已释放): PVC 被删除,但是资源还未被集群重新声明
• Failed (失败): 表示该 PV 的自动回收失败
6.3.4PV和PVC生命周期
PV和PVC的生命周期见下图:
PVC和PV是一 一对应的, PV和PVC之间的相互作用遵循以下生命周期:
- 资源供应:管理员手动创建底层存储和PV,状态处于Available
- 资源绑定:用户创建PVC, kubernetes负责根据PVC的声明去寻找PV,并绑定,状态为Bound
在用户定义好PVC之后,系统将根据PVC对存储资源的请求在已存在的PV中选择一个满足条件的
a. 一旦找到,就将该PV与用户定义的PVC进行绑定,用户的应用就可以使用这个PVC了
b. 如果找不到,PVC则会无限期处于Pending状态, 直到等到系统管理员创建了一个符 合其要求的PV
PV一旦绑定到某个PVC上,就会被这个PVC独占,不能再与其他PVC进行绑定了
- 资源使用:用户可在pod中像volume一样使用pvc
Pod使用Volume的定义,将PVC挂载到容器内的某个路径进行使用。
- 资源释放:用户删除pvc来释放pv
当存储资源使用完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为”已释放 (Released)“,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被 留在存储设备上,只有在清除之后该PV才能再次使用。
- 资源回收:kubernetes根据pv设置的回收策略进行资源的回收
对于PV,管理员可以设定回收策略,用于设置与之绑定的PVC释放资源之后如何处理遗留数据的问题。只有PV的存储空间完成回收(处于Available状态),才能供新的PVC绑定和使用
参考: K8S数据存储(高级存储之 PV、PVC、PV和PVC生命周期K8S数据存储(高级存储之 PV、PVC、
K8S数据存储(高级存储之 PV、PVC、PV和PVC生命周期)_途径日暮不赏丶的博客-CSDN博客_k8s 查看pv