2026/2/11 8:35:08
网站建设
项目流程
手机网站欣赏,国外唯美flash个人网站欣赏,佛山网站优化美姿姿seo,wordpress 外贸站主题文章目录 前言一、容器存储短暂性问题二、emptyDir存储卷三、hostPath 存储卷四、NFS网络共享卷1、特点2、创建步骤2.1、在stor01节点上安装nfs#xff0c;并配置nfs服务2.2、master节点操作2.3、在nfs服务器上创建index.html2.4、 master节点操作并且验证2.5、其他跨主机持久…文章目录前言一、容器存储短暂性问题二、emptyDir存储卷三、hostPath 存储卷四、NFS网络共享卷1、特点2、创建步骤2.1、在stor01节点上安装nfs并配置nfs服务2.2、master节点操作2.3、在nfs服务器上创建index.html2.4、 master节点操作并且验证2.5、其他跨主机持久化工具五、PV和PVC持久化机制1、 PV与PVC的概念2、PV和PVC生命周期3、pv的状态4、一个PV从创建到销毁的具体流程如下5、pv示例解析六、NFSPVPVC实战1、配置nfs存储2、定义PV3、定义PVCPod4、测试访问七、StorageClass NFS 动态存储1、为什么要使用动态存储2、在stor01节点上安装nfs并配置nfs服务3、创建 Service Account4、部署 NFS Provisioner5、创建 StorageClass6、测试 PVC Pod7、验证结果总结前言容器存储天生具备短暂性数据易随容器销毁丢失。本文从基础存储卷到动态供给拆解各类容器持久化方案附实操步骤助力落地。一、容器存储短暂性问题容器的文件系统是临时性的1容器崩溃重启后容器内数据会丢失2同一个 Pod 内的多个容器无法直接共享文件。Kubernetes 的 Volume 抽象 解决了这两个问题通过 Pause 容器 让多个容器共享同一个 Volume从而实现文件共享与持久化。二、emptyDir存储卷特点Pod 调度到节点时自动创建Pod 删除后数据也随之销毁仅适合临时缓存或容器间数据共享。创建示例mkdir /opt/volumes cd /opt/volumes vim pod-emptydir.yaml # API版本Pod是K8s的核心资源属于v1版本 apiVersion: v1 # 资源类型这里声明要创建的是Pod kind: Pod # 元数据用于描述Pod的基础信息 metadata: # Pod的名称在命名空间内唯一 name: pod-emptydir # Pod所属的命名空间默认就是default namespace: default # 自定义标签用于筛选、关联其他资源比如Service labels: app: myapp tier: frontend # 规格Pod的核心配置定义容器、存储卷等 spec: # 容器列表一个Pod可以包含多个容器这里定义两个Nginx容器 containers: # 第一个容器的配置 - name: myapp-nginx # 容器名称自定义且在Pod内唯一 # 镜像替换为官方Nginx最新版原镜像ikubernetes/myapp:v1替换 image: nginx:latest # 镜像拉取策略本地有就用本地没有再从仓库拉 imagePullPolicy: IfNotPresent # 端口配置声明容器要暴露的端口Nginx默认80端口 ports: - name: http # 端口名称自定义 containerPort: 80 # 容器内部的端口号 # 容器挂载配置将存储卷挂载到容器内指定目录 volumeMounts: # 要挂载的存储卷名称必须和下方volumes里的name一致 - name: html # 挂载到容器内的目录Nginx默认的网页根目录 mountPath: /usr/share/nginx/html/ # 第二个容器的配置 - name: busybox-nginx # 容器名称自定义且在Pod内唯一 # 镜像替换为官方Nginx最新版原镜像busybox:latest替换 image: nginx:latest # 镜像拉取策略本地有就用本地没有再从仓库拉 imagePullPolicy: IfNotPresent # 同样挂载名为html的存储卷 volumeMounts: # 要挂载的存储卷名称和第一个容器共用同一个 - name: html # 挂载到该容器内的/data目录 mountPath: /data/ # 容器启动命令持续往/data/index.html写入当前时间每2秒一次 command: [/bin/sh,-c,while true;do echo $(date) /data/index.html;sleep 2;done] # 存储卷定义Pod级别的存储供容器挂载使用 volumes: # 存储卷名称和容器volumeMounts里的name对应 - name: html # 存储卷类型emptyDirPod存在时生效Pod删除则数据丢失用于Pod内容器共享数据 emptyDir: {}kubectl apply -f pod-emptydir.yaml验证在上面定义了2个容器其中一个容器是输入日期到index.html中然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。三、hostPath 存储卷特点将节点宿主机上的目录挂载到容器可实现持久化但节点故障会导致数据丢失。创建示例1在 node01 节点上创建挂载目录 mkdir -p /data/pod/volume1 echo node01.benet.com /data/pod/volume1/index.html 2在 node02 节点上创建挂载目录 mkdir -p /data/pod/volume1 echo node02.benet.com /data/pod/volume1/index.html 3) 创建 Pod 资源 vim pod-hostpath.yaml apiVersion: v1 kind: Pod metadata: name: pod-hostpath namespace: default spec: containers: - name: myapp image: nginx # 定义容器挂载内容 volumeMounts: # 使用的存储卷名称需和下方volumes的name一致 - name: html # 挂载至容器中哪个目录 mountPath: /usr/share/nginx/html # 读写挂载方式默认为读写模式false readOnly: false # volumes字段定义Pod关联的存储卷hostPath为宿主机路径 volumes: # 存储卷名称 - name: html # 存储卷类型为hostPath关联宿主机路径 hostPath: # 宿主机上的目录路径 path: /data/pod/volume1 # 类型宿主机无此目录则自动创建 type: DirectoryOrCreatekubectl apply -f pod-hostpath.yaml验证结果如下所示删除重建pod查看效果kubectl delete -f pod-hostpath.yamlkubectl apply -f pod-hostpath.yaml查看结果一致Pod 删除重建后仍能访问相同内容说明数据持久化。四、NFS网络共享卷1、特点多节点共享数据数据集中存放于 NFS 服务端支持 RWX多路读写2、创建步骤2.1、在stor01节点上安装nfs并配置nfs服务# 查看rpcbind nfs-utils是否安装没有则yum 安装 rpm -q rpcbind nfs-utils yum install -y nfs-utils rpcbind # 共享卷路径 mkdir /data/volumes -p chmod 777 /data/volumes # 配置共享卷共享网段 vim /etc/exports #NFS 的配置文件为/etc/exports文件内容默认为空无任何共享 /data/volumes 192.168.10.0/24(rw,no_root_squash) systemctl start rpcbind systemctl start nfs systemctl enable rpcbind systemctl enable nfs # 验证 netstat -antulp | grep rpc # 查看共享卷是否生效 showmount -e2.2、master节点操作vim pod-nfs-vol.yaml apiVersion: v1 kind: Pod metadata: name: pod-vol-nfs namespace: default spec: containers: - name: myapp image: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html nfs: path: /data/volumes server: stor01 # node节点设置stor01解析主机名称 vim /etc/hosts 192.168.10.102 stor01 # node节点安装nfs客户端 yum install -y nfs-utils2.3、在nfs服务器上创建index.htmlecho “nfs stor01” /data/volumes/index.html2.4、 master节点操作并且验证删除nfs相关pod再重新创建可以得到数据的持久化存储kubectl delete -f pod-nfs-vol.yamlkubectl apply -f pod-nfs-vol.yaml2.5、其他跨主机持久化工具NAS、GFS、Ceph、SANCeph 是一款开源的、分布式的统一存储系统它能同时提供文件存储、块存储和对象存储三种接口且具备高可用、高扩展、无中心架构的特点是容器化如 Kubernetes和云计算场景中主流的持久化存储方案之一。五、PV和PVC持久化机制1、 PV与PVC的概念1PV 全称叫做 Persistent Volume持久化存储卷。它是用来描述或者说用来定义一个存储卷的这个通常都是由运维工程师来定义。2PVC 的全称是 Persistent Volume Claim是持久化存储的请求。它是用来描述希望使用什么样的或者说是满足什么条件的 PV 存储。PVC 的使用逻辑在 Pod 中定义一个存储卷该存储卷类型为 PVC定义的时候直接指定大小PVC 必须与对应的 PV 建立关系PVC 会根据配置的定义去 PV 申请而 PV 是由存储空间创建出来的。PV 和 PVC 是 Kubernetes 抽象出来的一种存储资源2、PV和PVC生命周期PV和PVC之间的相互作用遵循这个生命周期Provisioning配置– Binding绑定– Using使用– Releasing释放– Recycling回收Provisioning即 PV 的创建可以直接创建 PV静态方式也可以使用 StorageClass 动态创建Binding将 PV 分配给 PVCUsingPod 通过 PVC 使用该 Volume并可以通过准入控制StorageProtection1.9及以前版本为PVCProtection 阻止删除正在使用的 PVCReleasingPod 释放 Volume 并删除 PVCReclaiming回收 PV可以保留 PV 以便下次使用也可以直接从云存储中删除3、pv的状态根据这 5 个阶段PV 的状态有以下 4 种Available可用表示可用状态还未被任何 PVC 绑定Bound已绑定表示 PV 已经绑定到 PVCReleased已释放表示 PVC 被删掉但是资源尚未被集群回收Failed失败表示该 PV 的自动回收失败4、一个PV从创建到销毁的具体流程如下1一个PV创建完后状态会变成Available等待被PVC绑定。2一旦被PVC邦定PV的状态会变成Bound就可以被定义了相应PVC的Pod使用。3Pod使用完后会释放PVPV的状态变成Released。4变成Released的PV会根据定义的回收策略做相应的回收工作。有三种回收策略Retain、Delete和 Recycle。策略Retain保留数据需手动清理retain就是保留现场K8S集群什么也不做等待用户手动去处理PV里的数据处理完后再手动R删除PV。Delete自动删除存储资源Recycle清空数据重新可用仅 NFS / HostPath 支持。 K8S会将PV里的数据删除然后把PV的状态变成Available又可以被新的PVC绑定使用。5、pv示例解析kubectl explain pv # 查看pv的定义方式 metadata: # 由于 PV 是集群级别的资源即 PV 可以跨 namespace 使用 # 所以 PV 的 metadata 中不用配置 namespace kubectl explain pv.spec #查看pv定义的规格 spce: nfs:定义存储类型 path:定义挂载卷路径 server:定义服定义访问模型务器名称 accessModes:有以下三种访问模型以列表的方式存在也就是说可以定义多个访问模式 * * * - ReadWriteOnce #RWO存储可读可写但只支持被单个 Pod 挂载 - ReadOnlyMany #ROX存储可以以只读的方式被多个 Pod 挂载 - ReadWriteMany #RWX存储可以以读写的方式被多个 Pod 共享 capacity:定义存储能力一般用于设置存储空间 storage: 2Gi 指定大小 storageClassName: 自定义存储类名称此配置用于绑定具有相同类别的PVC和PV persistentVolumeReclaimPolicy: Retain #回收策略Retain/Delete/Recycle ** * #Retain保留当删除与之绑定的PVC时候这个PV被标记为releasedPVC与PV解绑但还没有执行回 收策略且之前的数据依然保存在该PV上但是该PV不可用需要手动来处理这些数据并删除该PV。 #Delete删除删除与PV相连的后端存储资源只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持 #Recycle回收删除数据效果相当于执行了 rm -rf /thevolume/* 只有 NFS 和 HostPath 支持 kubectl explain pvc #查看PVC的定义方式 KIND: PersistentVolumeClaim VERSION: v1 FIELDS: apiVersion string kind string metadata Object spec Object #PV和PVC中的spec关键字段要匹配比如存储storage大小、访问模式accessModes、存储类名 # 称storageClassName spec: accessModes: 定义访问模式必须是PV的访问模式的子集 resources: requests: storage: 定义申请资源的大小 storageClassName: 定义存储类名称此配置用于绑定具有相同类别的PVC和PV六、NFSPVPVC实战1、配置nfs存储cd /data/volumes/ mkdir v{1,2,3,4,5} vim /etc/exports /data/volumes/v1 192.168.10.0/24(rw,no_root_squash) /data/volumes/v2 192.168.10.0/24(rw,no_root_squash) /data/volumes/v3 192.168.10.0/24(rw,no_root_squash) /data/volumes/v4 192.168.10.0/24(rw,no_root_squash) /data/volumes/v5 192.168.10.0/24(rw,no_root_squash) showmount -e2、定义PVvim pv-demo.yaml# 定义5个PV指定NFS挂载路径、访问模式和存储大小 apiVersion: v1 kind: PersistentVolume # 资源类型持久化卷PV metadata: name: pv001 # PV的唯一名称集群内不能重复 labels: name: pv001 # 给PV打标签PVC可通过标签筛选绑定该PV spec: nfs: path: /data/volumes/v1 # NFS服务器上的共享目录路径需提前在NFS服务端创建 server: stor01 # NFS服务器的地址主机名/IP需保证K8s节点能解析/访问 # 访问模式支持的挂载方式数组形式可写多个 # ReadWriteMany(RWX)多Pod可同时读写ReadWriteOnce(RWO)仅单个Pod读写 accessModes: [ReadWriteMany,ReadWriteOnce] # 存储容量配置该PV提供的存储空间大小 capacity: storage: 1Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv002 labels: name: pv002 spec: nfs: path: /data/volumes/v2 server: stor01 accessModes: [ReadWriteOnce] capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv003 labels: name: pv003 spec: nfs: path: /data/volumes/v3 server: stor01 accessModes: [ReadWriteMany,ReadWriteOnce] capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv004 labels: name: pv004 spec: nfs: path: /data/volumes/v4 server: stor01 accessModes: [ReadWriteMany,ReadWriteOnce] capacity: storage: 4Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv005 labels: name: pv005 spec: nfs: path: /data/volumes/v5 server: stor01 accessModes: [ReadWriteMany,ReadWriteOnce] capacity: storage: 5Gi结果如下3、定义PVCPod这里定义了pvc的访问模式为多路读写该访问模式必须在前面pv定义的访问模式之中。定义PVC申请的大小为2Gi此时PVC会自动去匹配多路读写且大小为2Gi的PV匹配成功获取PVC的状态即为Boundvim pod-vol-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc namespace: default spec: accessModes: [ReadWriteMany] resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: name: pod-vol-pvc namespace: default spec: containers: - name: myapp image: ingix volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc结果如下4、测试访问# 在存储服务器上创建index.html并写入数据通过访问Pod进行查看可以获取到相应的页面。 cd /data/volumes/v3/ echo welcome to use pv3 index.html kubectl get pods -o wide curl 10.244.2.101七、StorageClass NFS 动态存储1、为什么要使用动态存储通过 nfs-client-provisioner 实现 自动 PV 创建Kubernetes 本身支持的动态 PV 创建不包括 NFS所以需要使用外部存储卷插件分配PV。详见https://kubernetes.io/zh/docs/concepts/storage/storage-classes/卷插件称为 Provisioner存储分配器NFS 使用的是 nfs-client这个外部PV。Provisioner用于指定 Volume 插件的类型包括内置插件如 kubernetes.io/aws-ebs和外部插件如 exte卷插件会使用已经配置好的 NFS 服务器自动创建 rnal-storage 提供的 ceph.com/cephfs。2、在stor01节点上安装nfs并配置nfs服务mkdir /opt/k8s chmod 777 /opt/k8s/ vim /etc/exports /opt/k8s 192.168.10.0/24(rw,no_root_squash,sync) systemctl restart nfs3、创建 Service Account创建 Service Account用来管理 NFS Provisioner 在 k8s 集群中运行的权限设置 nfs-client 对 PVPVCStorageClass 等的规则vim nfs-client-rbac.yaml #创建 Service Account 账户用来管理 NFS Provisioner 在 k8s 集群中运行的权限 apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner --- # 创建集群角色 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: nfs-client-provisioner-clusterrole 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: [list, watch, create, update, patch] - apiGroups: [] resources: [endpoints] verbs: [create, delete, get, list, watch, patch, update] --- # 集群角色绑定 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nfs-client-provisioner-clusterrolebinding subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-clusterrole apiGroup: rbac.authorization.k8s.iokubectl apply -f nfs-client-rbac.yaml4、部署 NFS ProvisionerNFS Provisione(即 nfs-client)有两个功能一个是在 NFS 共享目录下创建挂载点(volume)另一个则是将 PV 与 NFS 的挂载点建立关联。#由于 1.20 版本启用了 selfLink所以 k8s 1.20 版本通过 nfs provisioner 动态生成pv会报错解决方法如下 vim /etc/kubernetes/manifests/kube-apiserver.yaml spec: containers: - command: - kube-apiserver - --feature-gatesRemoveSelfLinkfalse #添加这一行 - --advertise-address192.168.10.19 ...... kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml kubectl delete pods kube-apiserver -n kube-system kubectl get pods -n kube-system | grep apiserver创建 NFS Provisionervim nfs-client-provisioner.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner # 指定Service Account账户 containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest imagePullPolicy: IfNotPresent volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: nfs-storage # 配置provisioner的Name确保该名称与StorageClass资源中的provisioner名称保持一致 - name: NFS_SERVER value: stor01 # 配置绑定的nfs服务器 - name: NFS_PATH value: /opt/k8s # 配置绑定的nfs服务器目录 volumes: # 申明nfs数据卷 - name: nfs-client-root nfs: server: stor01 path: /opt/k8s5、创建 StorageClass创建 StorageClass负责建立 PVC 并调用 NFS provisioner 进行预定的工作并让 PV 与 PVC 建立关联vim nfs-client-storageclass.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client-storageclass provisioner: nfs-storage # 这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致 parameters: archiveOnDelete: false # false表示在删除PVC时不会对数据进行存档即直接删除NFS上对应的目录和数据kubectl apply -f nfs-client-storageclass.yaml6、测试 PVC Podvim test-pvc-pod.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-nfs-pvc spec: accessModes: - ReadWriteMany storageClassName: nfs-client-storageclass # 关联StorageClass对象修正了原拼写错误 resources: requests: storage: 1Gi --- apiVersion: v1 kind: Pod metadata: name: test-storageclass-pod spec: containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - /bin/sh - -c args: - sleep 3600 volumeMounts: - name: nfs-pvc mountPath: /mnt restartPolicy: Never volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-nfs-pvc # 与PVC名称保持一致pod/test-storageclass-pod created7、验证结果● PVC 自动创建并绑定 PV● NFS 服务端自动生成对应目录● 在 Pod 中写入文件NFS 端可见文件内容PVC 通过 StorageClass 自动申请到空间查看 NFS 服务器上是否生成对应的目录自动创建的 PV 会以n a m e s p a c e − {namespace}-namespace−{pvcName}-${pvName} 的目录格式放到 NFS 服务器上进入 Pod 在挂载目录 /mnt 下写一个文件然后查看 NFS 服务器上是否存在该文件kubectl exec -it test-storageclass-pod shcd /mnt/echo ‘this is test file’ test.txt4)发现 NFS 服务器上存在说明验证成功cat /opt/k8s/test.txt总结本文覆盖容器持久化全流程实操从基础卷到 PV/PVC 及动态存储按需选型即可兼顾数据稳定与运维效率适配不同业务场景。