k8s 持久卷使用记录 ( PV + PVC + SC + NFS )
k8s 持久卷使用相关记录,供后续研究参考。。。
组成 PV ( PersistentVolume ) + PVC ( PersistentVolumeClaim ) + SC ( StorageClass ) + NFS
k8s 持久卷挂载方案有多种,我这里使用的是 NFS
k8s 集群为 master + 2 node 自行搭建 使用 flannel 做网络插件,实现k8s集群内部通信
IP:k8s-master: 192.168.1.230
k8s-node01:192.168.1.231
k8s-node02:192.168.1.232
一、NFS 搭建
NFS 搭建很简单,自行百度
需要创建对应网络共享目录,配置相应权限
创建完成后,即可通过k8s StorageClass 来创建存储卷绑定策略及指定相关存储卷插件类型
注:需要在所有工作节点都安装NFS 不然会在 Deployment 中部署 replicas 多实例时报错。 通过命令 kubectl describe pods xxx 中查看 Events 事件中提示报错信息: NFS 服务器文件系统崩坏等信息。未截图
二、创建 SC 配置
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: bxy-storageclass provisioner: kubernetes.io/no-provisioner reclaimPolicy: Retain #回收策略:Retain(保留)、 Recycle(回收)或者Delete(删除) volumeBindingMode: Immediate #volumeBindingMode存储卷绑定策略 allowVolumeExpansion: true #是否允许扩容 #volumeBindingMode存储卷绑定策略 #(控制存储卷绑定和动态供应行为 #- Immediate:创建 PVC 后立即创建后端存储卷,并且立即绑定新创建的 PV 和 PVC。 #- WaitForFirstConsumer:当 PVC 被 Pod 使用时,才触发 PV 和后端存储的创建,同时实现 PVC/PV 的绑定,启用该配置后,Storage Class 中的 Zone 和 Region 将不再生效,而是使用 Pod 调度所在节点的 zone 和 region 创建文件系统,保证文件系统能被 Pod 挂载。) #StorageClass的定义包含四个部分: #provisioner:指定 Volume 插件的类型,包括内置插件(如kubernetes.io/glusterfs、kubernetes.io/aws-ebs)和外部插件(如 external-storage 提供的 ceph.com/cephfs)。 #parameters:指定 provisioner 的选项,比如 glusterfs 支持 resturl、restuser 等参数。 #mountOptions:指定挂载选项,当 PV 不支持指定的选项时会直接失败。比如 NFS 支持 hard 和 nfsvers=4.1 等选项。 #reclaimPolicy:指定回收策略,同 PV 的回收策略。
启动:kubectl create -f bxy-nfs-StorageClass.yaml
框起来的三个字段在上面 yaml 配置文件中有相关注释
三、创建 PV 配置
apiVersion: v1 kind: PersistentVolume metadata: name: bxy-pv labels: name: bxy-pv-labels spec: capacity: #容量 storage: 6Gi volumeMode: Filesystem #存储卷模式(默认值为filesystem,除了支持文件系统外(file system)也支持块设备(raw block devices)) accessModes: #访问模式 - ReadWriteMany #ReadWriteOnce(RWO/该volume只能被单个节点以读写的方式映射),ReadOnlyMany (ROX/该volume可以被多个节点以只读方式映射), Re adWriteMany (RWX/该volume可以被多个节点以读写的方式映射) persistentVolumeReclaimPolicy: Retain #回收策略:Retain(保留)、 Recycle(回收)或者Delete(删除) storageClassName: bxy-storageclass #存储类(通过设置storageClassName字段进行设置。如果设置了存储类,则此PV只能被绑定到也指定了此存储类的PVC) mountOptions: #挂接选项 - hard - nfsvers=4.1 nfs: path: /bxy/nfsdata #我的本地挂载路径为 /bxy/nfsdata server: 192.168.1.231 #NFS 文件系统所在服务器的真实 IP #https://www.cnblogs.com/yanh0606/p/11269142.html
spec.storageClassName 字段对应 StorageClass 配置中的 metedata.name 字段
spec.mountOptions 字段没搞太懂,此为官网中 NFS 相应挂载配置
https://www.cnblogs.com/yanh0606/p/11269142.html 相关资料网站
启动:kubectl create -f bxy-nfs-pv.yaml
注意创建完 PV 后,会看到 Status 类型为 Available ,这是因为 PV 还没有和 PVC 绑定,当绑定成功后会自动改成 Bound
四、创建 PVC 配置
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: bxy-pvc spec: accessModes: - ReadWriteMany volumeMode: Filesystem resources: #注意:我写的是 5G ,但实际绑定成功后会自动改变为 PV 中设置的容量大小 6G requests: storage: 5Gi storageClassName: bxy-storageclass selector: matchLabels: name: bxy-pv-labels #pvc 通过 matchLabels和pv中的label匹配,来关联要使用的存储空间。 #https://my.oschina.net/sskxyz/blog/3130131 #表明此PVC希望使用Label:name: "bxy-pv-labels"的PV。 #https://www.cnblogs.com/yanh0606/p/11269142.html
spec.selector.matchLabels 这个字段与 PV 中的 labels 字段匹配
#pvc 通过 matchLabels和pv中的label匹配,来关联要使用的存储空间。
#https://my.oschina.net/sskxyz/blog/3130131
#表明此PVC希望使用Label:name: "bxy-pv-labels"的PV。
#https://www.cnblogs.com/yanh0606/p/11269142.html
启动:kubectl create -f bxy-nfs-pvc.taml
注意框起来的部分,状态为 Bound 并且容量为 6G,而不是配置文件中请求的 5G 容量
再次回过头来看下我们的 pv 状态
未创建 PVC 之前状态:
创建 PVC 后对比:
在未创建 PVC 之前我的 PV 状态为 Available ,现在状态自动更改为 Bound,说明已经自动绑定成功,并且 CLAIM 中添加了 PVC namespace/name
最后,我们启动一个 NG 来,检验下是否能成功挂载此卷。
五、创建 Deployment 配置
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-nfs-deploy spec: replicas: 2 selector: matchLabels: # spec.selector.matchLabels 要与 spec.template.metadata.labels 匹配!!!!不匹配不能启动 k8s-app: nginx-deploy-selector-labels template: metadata: labels: # Pod副本拥有的标签,对应RC的Selector k8s-app: nginx-deploy-selector-labels spec: containers: - name: my-nginx image: nginx imagePullPolicy: IfNotPresent volumeMounts: - mountPath: "/usr/share/nginx/html" name: bxy-pv # spec.template.spec.containers.name.volumeMounts.name == spec.template.spec.volumes.name volumes: #持久卷相关连部分 - name: bxy-pv #PersistentVolume metadata.name persistentVolumeClaim: claimName: bxy-pvc #PersistentVolumeClaim metadata.name # Claim 必须位于使用它的 Pod 所在的同一名字空间内。
没啥好解释的,注释基本都写了,可能有部分不是很准确,自行在摸索吧。
启动:kubectl create -f nginx-nfs-deploy.taml
挂载很成功,没啥好说的,毕竟已经实验多次了。
对了,这里没有 Port 相关的配置,会在下面写一个 Service 来做端口映射配置
在看下具体的 Pod 吧。
两个 NG 很健康
这个是 Pod 的 Events ,可以看到这个 Pod 被调度到 k8s-node02 上面了,创建启动啥的都和正常,没啥毛病。
下面就是让这个 NG 可以在外网能够访问。
六、创建 Service 配置
apiVersion: v1 kind: Service metadata: labels: k8s-app: nginx-svc-labels name: nginx-nfs namespace: default spec: clusterIP: 10.101.138.35 #集群内部IP externalTrafficPolicy: Cluster #Cluster或者Local(Local 流量不会转发到其他节点) ports: - nodePort: 29606 #NodePort,外部访问的端口 port: 19606 #容器间,服务调用的端口 protocol: TCP targetPort: 80 #容器暴露的端口,与Dockerfile暴露端口保持一致 selector: k8s-app: nginx-deploy-selector-labels #此标签要与deploy中的 spec.selector.matchLabels 匹配 type: LoadBalancer
spec.clusterIP 这个是我手动添加的,只要在 k8s flannel 网段类就可以了
基本上都注释的很详细了,也不再说啥了。
启动看看吧。
没啥问题,访问下看看
嗯,是访问到了,但是没有文件,这个我们在 挂载目录下添加个文件试试效果,顺便也能确认下我们的挂载卷是否生效了
在访问下,看看效果。。。
三台服务器都能访问 NG ,这个就是 Service 中的配置效果。
老铁,没毛病吧。