大概其的说一说,不一定对。总之一开始就觉得是个好东西。用到了,自然能体会到好处。
为每一个需要存储的资源编写pv,pvc很繁琐。
相同类型的请求有很多,急需快速可控的方案来实现动态申请。pvc申请,自动绑定pv
需要可以精细控制的存储回收重利用。既要保证容量,又要保证数据安全
管理员创建Provisioner(供应者),负责为外部请求提供pv(持久化存储卷)实例
StorageClass代替pvc(持久存储卷请求)向绑定的Provistioner发出pv(持久化存储卷)实例的请求
Pod绑定的pvc通过pvc获取pv实例进行存储
物料 | 内容 | 备注 |
---|---|---|
nfs服务 | 192.168.56.4 | 一台 |
存储目录 | /data/nfs/db-svc-dynamic-volume | 用于存放数据 |
k8s集群 | 无脑系列有介绍 | 版本1.16.4 |
名称 | 解释 | 备注 |
---|---|---|
StorageClass | k8s API Doc | |
ServiceAccount | 服务账户 | |
Role/ClusterRole | 角色/集群角色 | |
RoleBinding/ClusterRoleBinding | 角色与账户绑定 |
定义一个服务账户,该账户负责向集群申请资源。
定义“集群角色”,“角色”并与服务账户绑定。所以,yaml中才会分五部分。分别是
nfs-storage-rbac.yaml
apiVersion: v1
# 定义服务账户
kind: ServiceAccount
metadata:
# 名字要知命达意,这个账户专门为数据库服务
# {用途}-svc-{卷类型}-account
name: db-svc-nfs-account
namespace: default
---
# 定义集群角色声明该角色的权限列表,可以看出全是存储相关
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# 与 db-svc-nfs-account 相呼应
name: db-svc-nfs-cluster-role
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"]
---
# 定义完角色后,就要将ServiceAccount与ClusterRole来绑定
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: db-svc-nfs-account-cluster-role-bind
subjects: # 这里用的数组结构,那么可以认为这一个“角色”可以被多个账户绑定
- kind: ServiceAccount
# 账户名字,见ServiceAccount的name
name: db-svc-nfs-account
namespace: default
roleRef:
kind: ClusterRole
# 角色的名字,见ClusterRole的name
name: db-svc-nfs-cluster-role
apiGroup: rbac.authorization.k8s.io
---
# 专门用来操作pvc与pv绑定时,ServiceAccount可以使用的权限
kind: Role # 角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: db-svc-nfs-role
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
# 与角色绑定的ServiceAccount
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: db-svc-nfs-account-role-bind
subjects:
- kind: ServiceAccount
# 账户名字,见ServiceAccount的name
name: db-svc-nfs-account
namespace: default
roleRef:
kind: Role
# 角色名字,见role
name: db-svc-nfs-role
apiGroup: rbac.authorization.k8s.io
$kubectl create -f nfs-storage-rbac.yaml
serviceaccount/db-svc-nfs-account created
clusterrole.rbac.authorization.k8s.io/db-svc-nfs-cluster-role created
clusterrolebinding.rbac.authorization.k8s.io/db-svc-nfs-account-cluster-role-bind created
role.rbac.authorization.k8s.io/db-svc-nfs-role created
rolebinding.rbac.authorization.k8s.io/db-svc-nfs-account-role-bind created
nfs-storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: db-svc-nfs-storage-class
# 这个名字要记住
provisioner: db-svc-nfs-provistioner
parameters:
archiveOnDelete: "false"
reclaimPolicy: Retain
nfs-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: db-svc-nfs-provisioner
labels:
app: db-svc-nfs-provisioner
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: db-svc-nfs-provisioner
template:
metadata:
labels:
app: db-svc-nfs-provisioner
spec:
# 这里说明,用上面创建的service account来创建pv
serviceAccountName: db-svc-nfs-account
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env: #------ 这里是有学问的,见3.7
- name: PROVISIONER_NAME
value: db-svc-nfs-provistioner
- name: NFS_SERVER
value: 192.168.56.4
- name: NFS_PATH
value: /data/nfs/db-svc-dynamic-volume
volumes:
- name: db-svc-dynamic-volume
nfs: #----- 这里是有学问的,见3.7
server: 192.168.56.4
path: /data/nfs/db-svc-dynamic-volume
$kubectl create -f nfs-provisioner.yaml
nfs-dynamic-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: db-svc-nfs-storage-class
$kubectl create -f nfs-dynamic-pvc.yaml
*注意:如果系统报告下面的错误,说明您看过了无脑系列其它部分内容
Error from server (AlreadyExists): error when creating "nfs-dynamic-pvc.yaml": persistentvolumeclaims "mysql-pvc" already exists
请调用如下命令删除
$kubectl delete pvc mysql-pvc
$kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-e95e6bfb-aeba-4a96-b8eb-90c0db607ad9 1Gi RWO Retain Bound default/mysql-pvc db-svc-nfs-storage-class 17m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mysql-pvc Bound pvc-e95e6bfb-aeba-4a96-b8eb-90c0db607ad9 1Gi RWO db-svc-nfs-storage-class 17m
出现了ersistentvolume/pvc-e95e6bfb-aeba-4a96-b8eb-90c0db607ad9 这样的PV
mysql-pvc状态显示‘Bound’
系统正常运行!
为什么Provisioner中出现了重复设定NFS的内容呢?
说一下nfs-client-provisioner这个镜像
这个镜像的代码在Github中,查看代码得出结论
与集群ApiServer联通,并完成PV的创建过程。
在创建PV过程中,需要用到NFS_SERVER与NFS_PATH这两个变量
$kubectl describe pv pvc-e95e6bfb-aeba-4a96-b8eb-90c0db607ad9
Name: pvc-e95e6bfb-aeba-4a96-b8eb-90c0db607ad9
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: db-svc-nfs-provistioner
Finalizers: [kubernetes.io/pv-protection]
StorageClass: db-svc-nfs-storage-class
Status: Bound
Claim: default/mysql-pvc
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: 192.168.56.4 <--------这里
Path: /data/nfs/db-svc-dynamic-volume/default-mysql-pvc-pvc-e95e6bfb-aeba-4a96-b8eb-90c0db607ad9
ReadOnly: false
Events: <none>
之所以还需要给镜像挂载一个volume,是因为需要代码来完成集群给PV下达的reclaimPolicy指令,并完成具体操作