安装NFS服务器
# nfs主机
yum install -y nfs-common nfs-utils rpcbind
mkdir /nfsdata
chmod 777 /nfsdata
chown nfsnobody /nfsdata
cat /etc/exports
/nfsdata *(rw,no_root_squash.no_all_squash,sync)
systemctl start rpcbind
systemctl start nfs
# 所有节点安装nfs客户端
yum install -y nfs-utils rpcbind
# 测试
showmount -e 192.168.1.1
mount -t nfs 192.168.1.1:/nfs /test/
部署PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv1
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /data/nfsdata
server: 127.0.0.1
创建服务并使用PVC
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "nfs"
resources:
requests:
storage: 1Gi
PV从Release状态变为Available
在PV变成Available过程中,最关键的是PV的spec.claimRef字段,该字段记录着原来PVC的绑定信息,删除绑定信息,即可重新释放PV从而达到Available。
PV和PVC的处理流程
csi 是什么?csi 的全称是 container storage interface,它是K8s社区后面对存储插件实现(out of tree)的官方推荐方式。csi 的实现大体可以分为两部分:
- 第一部分是由k8s社区驱动实现的通用的部分,像我们这张图中的 csi-provisioner和 csi-attacher controller;
- 另外一种是由云存储厂商实践的,对接云存储厂商的 OpenApi,主要是实现真正的 create/delete/mount/unmount 存储的相关操作,对应到上图中的csi-controller-server和csi-node-server。
接下来看一下,当用户提交 yaml 之后,k8s内部的处理流程。用户在提交 PVCyaml 的时候,首先会在集群中生成一个 PVC 对象,然后 PVC 对象会被 csi-provisioner controller watch到,csi-provisioner 会结合 PVC 对象以及 PVC 对象中声明的 storageClass,通过 GRPC 调用 csi-controller-server,然后,到云存储服务这边去创建真正的存储,并最终创建出来 PV 对象。最后,由集群中的 PV controller 将 PVC 和 PV 对象做 bound 之后,这个 PV 就可以被使用了。
用户在提交 pod 之后,首先会被调度器调度选中某一个合适的node,之后该 node 上面的 kubelet 在创建 pod 流程中会通过首先 csi-node-server 将我们之前创建的 PV 挂载到我们 pod 可以使用的路径,然后 kubelet 开始 create && start pod 中的所有 container。
PV、PVC 以及通过 csi 使用存储流程
主要分为三个阶段:
- 第一个阶段(Create阶段)是用户提交完 PVC,由 csi-provisioner 创建存储,并生成 PV 对象,之后 PV controller 将 PVC 及生成的 PV 对象做 bound,bound 之后,create 阶段就完成了;
- 之后用户在提交 pod yaml 的时候,首先会被调度选中某一个 合适的node,等 pod 的运行 node 被选出来之后,会被 AD Controller watch 到 pod 选中的 node,它会去查找 pod 中使用了哪些 PV。然后它会生成一个内部的对象叫 VolumeAttachment 对象,从而去触发 csi-attacher去调用csi-controller-server 去做真正的 attache 操作,attach操作调到云存储厂商OpenAPI。这个 attach 操作就是将存储 attach到 pod 将会运行的 node 上面。第二个阶段 —— attach阶段完成;
- 然后我们接下来看第三个阶段。第三个阶段 发生在kubelet 创建 pod的过程中,它在创建 pod 的过程中,首先要去做一个 mount,这里的 mount 操作是为了将已经attach到这个 node 上面那块盘,进一步 mount 到 pod 可以使用的一个具体路径,之后 kubelet 才开始创建并启动容器。这就是 PV 加 PVC 创建存储以及使用存储的第三个阶段 —— mount 阶段。
总的来说,有三个阶段:第一个 create 阶段,主要是创建存储;第二个 attach 阶段,就是将那块存储挂载到 node 上面(通常为将存储load到node的/dev下面);第三个 mount 阶段,将对应的存储进一步挂载到 pod 可以使用的路径。这就是我们的 PVC、PV、已经通过CSI实现的卷从创建到使用的完整流程。