怎么给一个网站做seo,津坤科技天津网站建设,淘宝搜索关键词技巧,网址域名注册多少钱一、PV和PVC详解 当前#xff0c;存储的方式和种类有很多#xff0c;并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中#xff0c;放了方便我们的使用和管理#xff0c;Kubernetes提出了PV和PVC的概念#xff0c;这样Kubernetes集群的管理人员就…一、PV和PVC详解 当前存储的方式和种类有很多并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中放了方便我们的使用和管理Kubernetes提出了PV和PVC的概念这样Kubernetes集群的管理人员就可以将注意力集中到Kubernetes集群中来而无需操心后端的存储设备。 pv : 相当于磁盘分区 pvc: 相当于磁盘请求 PersistentVolumeClaimPVC是用户存储的请求 PVC的使用逻辑在pod中定义一个存储卷该存储卷类型为PVC 定义的时候直接指定大小pvc必须与对应的pv建立关系 pvc会根据定义去pv申请而pv是由存储空间创建出来的。 pv和pvc是kubernetes抽象出来的一种存储资源。 PV : 持久化卷的意思是对底层的共享存储的一种抽象PVCPersistent Volume Claim是持久卷请求于存储需求的一种声明(PVC其实就是用户向kubernetes系统发出的一种资源需求申请。) 从上图可以看出底层的存储可以使各种类型包括NFS、Ceph、CIFS等等而Kubernetes会把这些存储统一抽象为PV。PV即Persistent Volume是集群中配置的存储资源。PVC即Persistent Volume Claim是用户存储的请求通常我们在一个Pod中定义一个存储卷定义的时候会指定该存储卷的相关信息比如空间大小、可读可写等属性。但是PVC并不是真正的存储空间Pod的PVC和PV之间必须建立某种联系这样才能使得Pod可以调用实际存储空间。 apiVersion: v1 kind: PersistentVolume metadata: name: pv2 spec: nfs: # 存储类型与底层真正存储对应 capacity: # 存储能力目前只支持存储空间的设置 storage: 2Gi accessModes: # 访问模式 storageClassName: # 存储类别 persistentVolumeReclaimPolicy: # 回收策略 使用了PV和PVC之后工作可以得到进一步的细分
存储存储工程师维护PV kubernetes管理员维护PVCkubernetes用户维护
二、PV和PVC生命周期
实际上不管是PV还是PVC都遵循以下生命周期
Provisioning配置--- Binding绑定--- Using使用--- Releasing释放 --- Recycling回收
2.1 Provisioning 配置 Provisioning即配置阶段。一般而言PV的提供方式有两种——静态和动态。 所谓静态提供就是Kubernetes管理员创建多个PV这些PV的存储空间等属性已经确定并且已经和真实的存储设备进行了关联。Pod中的PVC可以根据需要请求这些PV。 所谓动态提供需要依托与StorageClass的支持这时Kubernetes会尝试为PVC来动态的创建PV。这样做的好处是避免出现这种情况部分PVC被分配给了远远超出其资源需求的PV、或者说系统存在很多资源较少的PV但是一个资源需求很高的PVC缺无法被满足的情况。
2.2 Binding 结合 在动态配置的情况下用户创建或者已经创建了具有特定数量的PVC后PVC与PV绑定的过程。 如果没有满足PVC请求需求的PV那么PVC将无法被创建因此造成的结果就是相应的Pod也不会被创建。
2.3 Using 使用 即PVC与PC绑定后Pod对存储空间的使用过程。
2.4 Releasing 释放 当Pod被删除或者对该PV的资源使用结束后Kubernetes就会删除该PVC对象相应的也会回收PV资源这时的PV就会处于这种状态。但是此时的PV还需要处理完毕之前的Pod在该存储卷上存储信息后才能够被使用。
2.5 Reclaiming 处理中 PV的回收策略对被释放的PV的处理过程。
2.6 Recycling 循环 根据配置有时PV会被执行擦除操作删除掉该存储空间上的所有信息并且该存储资源也可以被再次使用。
三、访问模式
3.1 PV的访问模式accessmodes 模式翻译 ReadWriteOnce RWO 可读可写但只支持被单个节点挂载。 ReadOnlyMany (ROX) 只读可以被多个节点挂载。 ReadWriteMany (RWX) 多路可读可写。这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式像共享方式目前支持的还比较少比较常用的是 NFS。在PVC绑定PV时通常根据两个条件来绑定一个是存储的大小另一个就是访问模式。
3.2 PV的回收策略persistentVolumeReclaimPolicy 策略解释retain不清理,保留Volume (需要手动清理)Recycle删除数据即rm -rf /thevolumel*(只有NFS和HostPath支持)Delete删除存储资源比如删除AWS EBS卷(只有AWS EBS,GCE PD,Azure Disk和Cinder支持)
3.3 pv的状态
状态解释Available可用Bound已经分配给PVCReleasedPVC解绑但还未执行回收策略Failed发生错误
四、实验验证
4.1 安装nfs # 1、创建目录 [rootk8s ~]# mkdir /root/data/{pv1,pv2,pv3} -pv chmod 777 /data/volumes # 2、暴露服务 [rootk8s ~]# vim /etc/exports /root/data/pv1 192.168.223.0/24(rw,sync,no_root_squash) /root/data/pv2 192.168.223.0/24(rw,sync,no_root_squash) /root/data/pv3 192.168.223.0/24(rw,sync,no_root_squash) # 3、重启服务 [rootk8s ~]# systemctl restart nfs //master节点操作 vim pod-nfs-vol.yaml apiVersion: v1 kind: Pod metadata: name: pod-vol-nfs namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html nfs: path: /data/volumes server: stor01主机名 4.2 验证nfs持久化存储 //在nfs服务器上创建index.html cd /data/volumes vim index.html h1 nfs stor01/h1 //master节点操作 curl 10.244.2.38 h1 nfs stor01/h1 kubectl delete -f pod-nfs-vol.yaml #删除nfs相关pod再重新创建可以得到数据的持久化存储 kubectl apply -f pod-nfs-vol.yaml nas gfs ceph san 可以实现持久化存储使用nfs将存储设别空间挂载到容器中pod可以跨node节点共享数据
4.3 NFS使用PV和PVC
PVC是资源的申请用来声明对存储空间、访问模式、存储类别需求信息。下面是资源清单文件
4.3.1、配置nfs存储 //NFS使用PV和PVC 1、配置nfs存储 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) exportfs -arv showmount -e 4.3.2 定义PV //这里定义5个PV并且定义挂载的路径以及访问模式还有PV划分的大小。 vim pv-demo.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv001 labels: name: pv001 spec: nfs: path: /data/volumes/v1 server: stor01 accessModes: [ReadWriteMany,ReadWriteOnce] 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 kubectl apply -f pv-demo.yaml kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv001 1Gi RWO,RWX Retain Available 7s pv002 2Gi RWO Retain Available 7s pv003 2Gi RWO,RWX Retain Available 7s pv004 4Gi RWO,RWX Retain Available 7s pv005 5Gi RWO,RWX Retain Available 7s 4.3.3 定义PVC //这里定义了pvc的访问模式为多路读写该访问模式必须在前面pv定义的访问模式之中。定义PVC申请的大小为2Gi此时PVC会自动去匹配多路读写且大小为2Gi的PV匹配成功获取PVC的状态即为Bound vim 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: soscscs/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc kubectl apply -f pod-vol-pvc.yaml kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv001 1Gi RWO,RWX Retain Available 19m pv002 2Gi RWO Retain Available 19m pv003 2Gi RWO,RWX Retain Bound default/mypvc 19m pv004 4Gi RWO,RWX Retain Available 19m pv005 5Gi RWO,RWX Retain Available 19m kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mypvc Bound pv003 2Gi RWO,RWX 22s 4.3.4 测试访问 //在存储服务器上创建index.html并写入数据通过访问Pod进行查看可以获取到相应的页面。 cd /data/volumes/v3/ echo welcome to use pv3 index.html kubectl get pods -o wide pod-vol-pvc 1/1 Running 0 3m 10.244.2.39 k8s-node02 curl 10.244.2.39 welcome to use pv3 4.4 搭建 StorageClass NFS实现 NFS 的动态 PV 创建
4.4.1 在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 nfs 4.4.2 创建 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.io kubectl apply -f nfs-client-rbac.yaml 4.4.3 3、使用 Deployment 来创建 NFS Provisioner NFS 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 Provisioner vim nfs-client-provisioner.yaml kind: Deployment apiVersion: apps/v1 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/k8s kubectl apply -f nfs-client-provisioner.yaml kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-cd6ff67-sp8qd 1/1 Running 0 14s 4.4.4 创建 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时不会对数据进行存档即删除数据 kubectl apply -f nfs-client-storageclass.yaml kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE nfs-client-storageclass nfs-storage Delete Immediate false 43s 4.4.5 创建 PVC 和 Pod 测试 vim test-pvc-pod.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-nfs-pvc-1 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-1 #与PVC名称保持一致 4.4.6 验证结果 kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE myapp01 1/1 Running 0 24h 10.244.1.6 node01 none myapp04 1/1 Running 0 24h 10.244.2.4 node02 none nfs-client-provisioner-d9dcdf4c4-f57d4 1/1 Running 0 144m 10.244.2.6 node02 none nginx-6799fc88d8-9vhpk 1/1 Running 0 24h 10.244.1.7 node01 none pod-vol-nfs 1/1 Running 0 19h 10.244.2.5 node02 none pod-vol-pvc 1/1 Running 1 18h 10.244.1.8 node01 none test-storageclass-pod 1/1 Running 0 78s 10.244.1.9 node01 none kubectl exec -it test-storageclass-pod sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # / # cd /mnt/ /mnt # ls /mnt # /mnt # echo wang shi kang sb index.html /mnt # 五、总结
5.1 Volume
①emptyDir可以实现Pod中的容器之间共享数据但是存储卷不能持久化数据且会随着Pod生命周期结束而一起删除
②hostpath可以实现持久化存储使用node节点的目录或文件挂载到容器但是存储空间会收到node节点单机限制node节点故障数据会丢失Pod会跨节点不能共享数据
③NFS可以实现持久化存储使用NFS将存储设备空间挂载到容器中Pod可以跨Node节点共享数据
5.2 PV和PVC
①PV 持久卷Persistent Volumes是集群中的一块存储资源由管理员事先创建或由动态供应机制如StorageClass自动创建。
②PVC持久卷声明Persistent Volume Claims是用户对存储的请求或声明Pod通过挂载PVC来使用PV。这种方式提供了存储的抽象和解耦使得应用无需关心具体的存储细节。
③当Pod销毁或重建时与之关联的PVC仍然保留保证了数据的持久性。
5.3 StorageClass——动态存储
①存储类定义了存储的“类”用于动态供应PV。管理员可以根据不同的需求如性能、成本定义多个存储类。
②用户在创建PVC时可以选择一个存储类Kubernetes会自动匹配并创建合适的PV。
③对于存储资源虽然不像CPU和内存那样频繁地设置请求和限制但在使用PV/PVC时可以通过设置存储容量的大小来间接限制使用量。
④在Pod的YAML定义中可以通过volumeMounts来指定容器如何挂载卷以及是否需要设置读写权限等。
⑤Pod中的存储卷可以配置访问模式如只读、读写来确保数据的安全性。 对于敏感数据推荐使用Secrets或ConfigMaps并注意权限控制。
六、存储卷 容器磁盘上的文件的生命周期是短暂的这就使得在容器中运行重要应用时会出现一些问题。首先当容器崩溃时kubelet 会重启它但是容器中的文件将丢失——容器以干净的状态镜像最初的状态重新启动。其次在Pod中同时运行多个容器时这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。
6.1 emptyDir存储卷 当Pod被分配给节点时首先创建emptyDir卷并且只要该Pod在该节点上运行该卷就会存在。正如卷的名字所述它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时emptyDir中的数据将被永久删除。 mkdir /opt/volumes cd /opt/volumes vim pod-emptydir.yaml apiVersion: v1 kind: Pod metadata: name: pod-emptydir namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 #定义容器挂载内容 volumeMounts: #使用的存储卷名称如果跟下面volume字段name值相同则表示使用volume的这个存储卷 - name: html #挂载至容器中哪个目录 mountPath: /usr/share/nginx/html/ - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent volumeMounts: - name: html #在容器内定义挂载存储名称和挂载路径 mountPath: /data/ command: [/bin/sh,-c,while true;do echo $(date) /data/index.html;sleep 2;done] #定义存储卷 volumes: #定义存储卷名称 - name: html #定义存储卷类型 emptyDir: {} [rootmaster01 volumes]]#kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-797d747cf6-6mkc9 1/1 Running 0 12d 10.244.1.12 node02 none none nginx-deployment-797d747cf6-hzn8m 1/1 Running 0 12d 10.244.2.13 node01 none none nginx-deployment-797d747cf6-rk8hr 1/1 Running 0 12d 10.244.2.12 node01 none none pod-emptydir 2/2 Running 0 96s 10.244.2.14 node01 none none 在上面定义了2个容器其中一个容器是输入日期到index.html中然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。 6.2 hastPath存储卷
hostPath卷将 node 节点的文件系统中的文件或目录挂载到集群中。 hostPath可以实现持久存储但是在node节点故障时也会导致数据的丢失。 //在 node01 节点上创建挂载目录 mkdir -p /data/pod/volume1 echo node01.kgc.com /data/pod/volume1/index.html //在 node02 节点上创建挂载目录 mkdir -p /data/pod/volume1 echo node02.kgc.com /data/pod/volume1/index.html //创建 Pod 资源 vim pod-hostpath.yaml apiVersion: v1 kind: Pod metadata: name: pod-hostpath namespace: default spec: containers: - name: myapp image: soscscs/myapp:v1 #定义容器挂载内容 volumeMounts: #使用的存储卷名称如果跟下面volume字段name值相同则表示使用volume的这个存储卷 - name: html #挂载至容器中哪个目录 mountPath: /usr/share/nginx/html #读写挂载方式默认为读写模式false readOnly: false #volumes字段定义了paues容器关联的宿主机或分布式文件系统存储卷 volumes: #存储卷名称 - name: html #路径为宿主机存储路径 hostPath: #在宿主机上目录的路径 path: /data/pod/volume1 #定义类型这表示如果宿主机没有此目录则会自动创建 type: DirectoryOrCreate kubectl apply -f pod-hostpath.yaml NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-797d747cf6-6mkc9 1/1 Running 0 12d 10.244.1.12 node02 none none nginx-deployment-797d747cf6-hzn8m 1/1 Running 0 12d 10.244.2.13 node01 none none nginx-deployment-797d747cf6-rk8hr 1/1 Running 0 12d 10.244.2.12 node01 none none pod-emptydir 2/2 Running 0 30m 10.244.2.14 node01 none none pod-hostpath 1/1 Running 0 2m3s 10.244.1.13 node02 none none [rootmaster01 volumes]]#curl 10.244.1.13 node02.rmh.com