0%

学习 Kubernetes 的 PV 和 PVC

其实我个人觉得Kubernetes下的Network和PV是最难理解的,前者是因为我不熟悉网络,后者则是因为资料不足。

这一篇是记录PV的学习的,也把一些知识点记录下来。

一、前置条件

  1. 已安装配置好NFS Server,用于远程文件系统服务。
  2. 已了解Kubernetes中关于RBAC、Service、Deployment相关的知识。

二、概念

PV:存储卷。其实没接触过存储相关领域的人压根就不知道什么叫卷。如果类比的话,它可以和Windows下的一个磁盘分区类比,和Unix下的挂载分区类比。我们可以认为,它就是一个放在远端的可以随时挂载到容器里的一个分区。

PVCPV只是申明了一个分区,但是并不是直接可用的,它必须通过申请使用方可使用。举个例子,电影院里有很多座位(PV),如果我们要看电影,肯定不能直接进去看,那得买票,而PVC就是票,所以,在看电影之前(使用PV之前),我们需要买票(申请PVC)。

StorageClass:存储类别。可以简单的认为是存储类型,因为分布式的存储方案有很多,根据不同的方案就会衍生出不同的存储类别。

其实StorageClass在这里我还是不怎么懂,只是知道大概的意思,它是按照CNI协议实现的具体存储方案的实现。比方说NFS方案和GCLUSTER方案。

三、准备配置

环境参数:

1
2
NFS SERVER: 192.168.55.55
NFS 数据目录:/deploy/nfs

建立namespace monitoring

1
$ kubectl create namespace monitoring

配置RBAC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: monitoring
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
namespace: monitoring
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: ["watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: monitoring
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io

上面配置为:

  1. 建立了一个 ServiceAccount:nfs-provisioner
  2. 建立一个ClusterRole,用于绑定相关的权限:nfs-provisioner-runner
  3. 将ClusterRole nfs-provisioner-runner 绑定到 ServiceAccount nfs-provisioner

这里准备的东西是为了将来准备PV时使用的。

配置NFS Provisioner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
namespace: monitoring
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-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: sanlea/nfs
- name: NFS_SERVER
value: 192.168.55.55
- name: NFS_PATH
value: /deploy/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.55.55
path: /deploy/nfs

这里provisioner主要是对sanlea/nfs的PROVISIONER_NAME的StorageClass提供支持,并且配置了NFS相关的信息,如IP和布署目录等。

这一步很重要,这里做的是为StorageClass提供技术实现,也就是说,后面绑定的StoreClass的操作,都是通过这里布署的provisioner去实际操作的。

配置StorageClass

1
2
3
4
5
6
7
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs
namespace: monitoring
provisioner: sanlea/nfs
reclaimPolicy: Delete

这里配置了一个名为nfsStorageClass,这里把这个StorageClass的provisioner设置成我们之前配置好的sanlea/nfs,这样,后面所有使用了nfs作为StorageClassPVPVC都会调用provisioner为sanlea/nfs服务来实现存储。

四、使用

上面的配置了StorageClass,但是一直没出现之前说的PVPVC,一直觉得很奇怪。

在这里,我们利用了provisioner的特性,我们只要配置好PVC,而PV则由provisioner自动创建,也就是说,每一个PVC会自动创建一个PV与之对应,也得出一个结论,PV在这里是一次性的,只要PVC被删除了,PV也随之被删除了。

其实PV里的数据并没有随着PVC的删除而删除,provisioner通过更改目录名的方式备份了这些数据,这些数据是需要人为删除方可真正删除的。

定义PVC

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: helm-server-claim
namespace: infra
spec:
storageClassName: nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi

定义一下使用这个PVC的Pod,挂载到自己的数据目录中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
kind: Pod
apiVersion: v1
metadata:
name: helm-server
namespace: infra
spec:
containers:
- name: helm-server
image: chartmuseum/chartmuseum:latest
args:
- "--storage=local"
- "--storage-local-rootdir=/data"
- "--port=8080"
volumeMounts:
- name: nfs-pvc
mountPath: "/data"
restartPolicy: "Never"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: helm-server-claim

五、总结

我知道,这只是PV里很小的一部分,其实大多数资料都说的不清楚,没办法。

其实实现了上述的配置已经基本满足的我憋大招的需求了。