pv和PVC,存储卷:
存储卷:
EmptyDir:容器内部,随着pod销毁,emptyDir也会消失,不能做数据持久化
HostPath:持久化存储数据,可以和节点上目录做挂载,pod被销毁了数据还在
NFS:一台机器,提供pod发起的挂载的请求
PV和PVC:
PVC就是pid发起挂载的反请求:
PV持久化存储的目录,ReadWriteMary
ReadOnlyMany
ReadwriteOnce
Nfs:可以支持三种方式
HostPath ReadwriteOnce
Iscsi不支持ReadwriteMany
pv的回收策略:
Retain released需要人工设置,调整回available
Recyc 回收,自动调整回available
Delete 删除
静态PV和PVC:
运维负责PV:创建好持久化存储卷,声明好读写和挂载类型,以及可以提供存储空间
PVC开发做,要和开发沟通好,你期望的读写和挂载类型,以及存储空间
当我发布PVC之后可以生成PV,还可以在共享服务器上直接生成挂载目录
PVC直接绑定和使用PV
动态PV需要两个组件:
- 卷插件,k8s本身支持的动态PV创建不包括NFS,需要声明和安装一个外部插件,叫做provisioner:存储分配器,可以动态创建PV,然后根据PVC的请求自动绑定和使用
- StorageClass:来定义PV的属性,存储类型,大小回收策略
今天还是用NFS来实现动态PV,NFS支持的方式NFS-Client,provisioner来适配NFS-Client
NFS-Client-provisioner卷插件
架构图:
实验演示:
/opt/k8s 20.0.0.0/24(rw,no_root_squash,sync)
vim /etc/exports
systemctl restart rpcbind
systemctl restart nfs
showmount -e
其他节点查看:
showmount -e 20.0.0.74
、创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限,
设置 nfs-client 对 PV,PVC,StorageClass 等的规则
回到master节点:
创建serviceAccount:
Nfs provisioner:是一个插件,没有权限是无法再集群当中获取k8s的消息,插件要有权限能够监听apiserver,获取Get,list(获取集群的列表资源)创建一个资源账户
Rbac:Role-base ACCESS CONTORL 定义角色在集群当中可以使用的权限
#创建集群角色
kubectl explain ClusterRole
#查看Kubernetes RBAC(Role-Based Access Control)的 ClusterRole 配置,
命名为 nfs-client-provisioner-clusterrole。这个 ClusterRole 定义了一组权限规则,
允许一个特定的服务账户(通常是用于 NFS 客户端 Provisioner 的账户)执行一些与存储相关的操作。
#创建集群角色
kubectl explain ClusterRole
#查看Kubernetes RBAC(Role-Based Access Control)的 ClusterRole 配置,
命名为 nfs-client-provisioner-clusterrole。这个 ClusterRole 定义了一组权限规则,
允许一个特定的服务账户(通常是用于 NFS 客户端 Provisioner 的账户)执行一些与存储相关的操作。
vim nfs-client-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-clusterrole
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: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-clusterrole
apiGroup: rbac.authorization.k8s.io
部署插件:
NFS-privisioner , deployment来创建插件pod
1.20之后有一个新的机制
SelfLink:API的资源对象之一,表示资源对象在集群当中自身的一个连结,self-Link是一个唯一的标识号,可以用于标识k8s集群当中的每个资源的对象
Self Link的值是一个URL,指向该资源对象的k8s API路径
更好的实现资源对象的查找和引用
部署插件之前操作:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --feature-gates=RemoveSelfLink=false
--feature-gates:在不破坏现有规则以及功能基础上引入新功能或者修改现有功能的机制,禁用不影响规则
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl get pods -n kube-system | grep apiserver
#创建 NFS Provisioner
接下来部署NFS-privisioner插件:
NFS的provisionner的客户端以pod的方式运行在集群当中,监听k8s集群当中PV的请求,然后动态的创建于NFS相关的PV
容器里使用的配置,在provisioner当中定义好环境变量,传给容器,storageclass的名称,NFS服务器的地址,NFS的目录
vim nfs-client-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs1
spec:
replicas: 1
selector:
matchLabels:
app: nfs1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs1
spec:
serviceAccountName: nfs-client-provisioner #指定Service Account账户
containers:
- name: nfs1
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-storage #配置provisioner的Name,
- name: NFS_SERVER
value: 20.0.0.74 #配置绑定的nfs服务器
- name: NFS_PATH
value: /opt/k8s #配置绑定的nfs服务器目录
volumes: #申明nfs数据卷
- name: nfs
nfs:
server: 20.0.0.74
path: /opt/k8s
运行脚本
定义存储卷相关的请求数据,创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-storageclass
provisioner: nfs-storage
parameters:
archiveOnDelete: "false"
reclaimPolicy: Retain
allowVolumeExpansion: true
vim nfs-client-storageclass.yaml
解析:
NAME: storageclass的名称
PROVISIONER: 对应的创建PV的provision的插件
RECLAIMPOLICY:回收策略,保留
VOLUMEBINDINGMODE:卷绑定模式,immediate表示PVC请求创建PV时,系统会立即绑定一个可用的PV
WaitForFirstConsumer:第一个使用出现之后再绑定PV
ALLOWVOLUMEEXPANSION:表示可以在运行时对PV进行扩容
创建 PVC 和 Pod 测试
vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-storageclass-deployment
labels:
app: nginx1
spec:
replicas: 1
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc
测试
共享成功
//查看 NFS 服务器上是否生成对应的目录,
自动创建的 PV 会以 ${namespace}-${pvcName}-${pvName} 的目录格式放到 NFS 服务器上
ls /opt/k8s/
再添加一条测试,看是否能够同时绑定多条
共享服务器查看
如何删除恢复
再次使用时数据并没有删除
如何修改回收策略
没有回收策略
动态PV的默认策略是删除,共享目录也会被删除
总结:动态PV
Provisioner插件---支持NFS
Stroageclass:定义PV的属性
动态PV的默认策略是删除,动态策略没有回收
动态PV删除PVC之后的状态,released
总的来说:
- 创建账号,给卷插件能够在集群内部运行,获取资源,监听时间,创建,删除,更新PV
- 创建插件pod,卷插件的pod创建PV
- Storageclass:给PV赋予权限(PVC被删除之后的状态,以及回收策略)
- 创建PVC----完成