其实我个人觉得Kubernetes下的Network和PV是最难理解的,前者是因为我不熟悉网络,后者则是因为资料不足。
这一篇是记录PV的学习的,也把一些知识点记录下来。
一、前置条件
- 已安装配置好NFS Server,用于远程文件系统服务。
- 已了解Kubernetes中关于RBAC、Service、Deployment相关的知识。
二、概念
PV
:存储卷。其实没接触过存储相关领域的人压根就不知道什么叫卷。如果类比的话,它可以和Windows下的一个磁盘分区类比,和Unix下的挂载分区类比。我们可以认为,它就是一个放在远端的可以随时挂载到容器里的一个分区。
PVC
:PV
只是申明了一个分区,但是并不是直接可用的,它必须通过申请使用方可使用。举个例子,电影院里有很多座位(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
|
上面配置为:
- 建立了一个 ServiceAccount:
nfs-provisioner
- 建立一个ClusterRole,用于绑定相关的权限:
nfs-provisioner-runner
- 将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
|
这里配置了一个名为nfs
的StorageClass
,这里把这个StorageClass
的provisioner设置成我们之前配置好的sanlea/nfs
,这样,后面所有使用了nfs
作为StorageClass
的PV
、PVC
都会调用provisioner为sanlea/nfs
服务来实现存储。
四、使用
上面的配置了StorageClass
,但是一直没出现之前说的PV
和PVC
,一直觉得很奇怪。
在这里,我们利用了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里很小的一部分,其实大多数资料都说的不清楚,没办法。
其实实现了上述的配置已经基本满足的我憋大招的需求了。