如何开发微信微网站,铭万网站建设,山东泰安,上海市工程建设协会网站文章目录 1 为什么需要卷(Volume)2 卷的挂载2.1 k8s集群中可以直接使用2.2 需要额外的存储组件2.3 公有云 2 PV(Persistent Volume)3 SC(Storage Class) 和 PVC(Persistent Volume Claim)4 总结 1 为什么需要卷(Volume)
Pod是由一个或者多个容器组成的#xff0c;在启动Pod中… 文章目录 1 为什么需要卷(Volume)2 卷的挂载2.1 k8s集群中可以直接使用2.2 需要额外的存储组件2.3 公有云 2 PV(Persistent Volume)3 SC(Storage Class) 和 PVC(Persistent Volume Claim)4 总结 1 为什么需要卷(Volume)
Pod是由一个或者多个容器组成的在启动Pod中的容器之前会先创建一个pause容器再将其他容器加入到pause容器的网络命名空间因此多个容器的网络是共享的pause容器就像是一个宿主机多个容器就像是宿主机上面的多个进程既然多个容器共享网络命名空间那么多个容器肯定就不能监听同一个端口。多个容器由于都有自己的文件系统因此多个容器的文件系统肯定是相互隔离的如果多个容器之间需要共享数据呢Pod在重建时Pod中的所有容器都会基于镜像重建那么原来的Pod中的容器中的数据都会丢失但是很多场景下都需要对数据进行持久化保存例如mysql的Pod在重建时可不希望保存的数据没有了。
为了解决以上两个问题k8s提供了数据卷的机制可以将同一个数据卷挂载到Pod的多个容器实现多个容器的数据共享也可以将数据卷对接外部的存储实现数据的持久化使得Pod重建或者被删除后数据不丢失。
2 卷的挂载
一个Pod可以在pod.spec.volumes中声明使用命令kubectl explain pod.spec.volumes可以发现里面各种类型的卷看这些卷的类型会发现有些卷是可以直接在k8s集群中使用的有些是需要安装额外组件的还有一些是对接共有云的因此每种类型的卷中的参数是不一样的。
2.1 k8s集群中可以直接使用
卷的类型特点特性状态configMap对接ConfigMap可以将ConfigMap中的多个KV挂载为容器中的多个文件downwardAPI对接DownwardAPI可以将集群的信息挂载为容器中的文件emptyDir用于多个容器之间的数据共享相当于将一个空目录分别挂载到Pod的多个容器它的生命周期与Pod相同只要Pod在运行卷就不会被删除gitRepo从git上clone仓库代码然后挂载到容器已废弃建议在initContainer中在emptyDir下载代码hostPath将宿主机的路径挂载到容器中这种方式有安全风险通常不建议使用persistentVolumeClaim用于将PV挂载到容器中projected投射卷可以将多个卷同时挂载到容器中的一个目录源卷只能是secret、downwardAPI、configMap、serviceAccountTokensercet将Secret挂载为容器中的文件
2.2 需要额外的存储组件
卷的类型特点特性状态cephfs对接CephFS1.28版本中废弃建议使用Ceph CSI第三方存储驱动cinder对接Openstack Cinder1.11版本中废弃1.26版本中移除1.27版本开始可以使用Openstack Cinder第三方驱动程序fc对接FiberChannelglusterfs对接GlusterFS1.25版本中废弃1.26版本中移除iscsi对接iSCSInfs对接NFSportworxVolume对接Portworx1.25版本中废弃rdb对接CephFS的rdb1.28版本中废弃
2.3 公有云
卷的类型特点特性状态awsElasticBlockStore对接AWS EBS1.19版本中废弃1.28版本中移除1.28版本开始可以使用AWS EBS第三方存储驱动azureDisk对接Azure Disk1.19版本中废弃1.28版本中移除1.28版本开始可以使用Azure Disk第三方存储驱动azureFile对接Azure File1.21版本中废弃1.26版本开始可以使用Azure File第三方存储驱动gcePersistentDisk对接GCE PersistentDisk1.17版本中废弃vsphereVolume对接VMWare vsphere VMDK1.28版本可以使用vSphere CSI第三方存储驱动
当在pod.spec.volumes配置使用的卷后就可以在pod.spec.containers.volumeMounts将卷挂载到容器中以下以configMap类型的卷为例将app-config这个ConfigMap挂载到nginx容器的/opt目录
apiVersion: v1
kind: Pod
metadata:name: test
spec:containers:- name: nginximage: nginxvolumeMounts:- name: my-configmountPath: /opt/volumes:- name: my-config configMap:name: app-config2 PV(Persistent Volume)
将pod.spec.volumes中配置的卷挂载到容器中这时候volume是附属于Pod的volume和Pod就构成了一种静态绑定关系这对于hostPath、configMap、secret等类型的volume来说是可以的因为hostPath是对本地目录的挂载configMap和secret是对ConfigMap和Secret的挂载这时候ConfigMap/Secret和Pod是同一个人创建的。
当开发人员用这种方式将NFS挂载到容器中
apiVersion: v1
kind: Pod
metadata:name: test-pd
spec:containers:- image: registry.k8s.io/test-webservername: test-containervolumeMounts:- mountPath: /my-nfs-dataname: test-volumevolumes:- name: test-volumenfs:server: my-nfs-server.example.compath: /my-nfs-volumereadOnly: true此处将my-nfs-server.example.com的/my-nfs-volume目录挂载到test-container容器的/my-nfs-data路径这里的问题是当运维部门的同事部署完NFS后难道还需要将NFS的域名/IP和路径告诉开发人员但是开发人员实际上并不关心这些那有没有一种方式可以让开发人员只是使用NFS而不需要关心NFS的具体配置这就需要使用到PV持久卷。
apiVersion: v1
kind: PersistentVolume
metadata:name: my-nfs
spec:capacity:storage: 5GiaccessModes:- ReadWriteOncenfs:path: /tmpserver: 172.17.0.2上述yaml会创建一个my-nfs的PV需要注意的是PV是集群级别的资源。这里用的pv.spec.nfs字段跟pod.spec.volumes.nfs相同只是多了外层的capacity和accessModes它们分别表示PV的容量和访问模式。当运维人员部署完成NFS文件系统就可以直接创建好PV然后开发人员就可以直接引用该PV。
这样虽然可以解决volume创建和volume使用的问题如果集群中只有少量的PV时是没有问题的运维人员是可以手动创建的。如果PV的数量很多呢当运维人员创建了很多PV后开发人员难道需要自己从中挑选PV使用吗那管理的复杂度会非常大因此k8s提供了SC和PVC。
3 SC(Storage Class) 和 PVC(Persistent Volume Claim)
独立的PV资源分离了卷的创建和使用而PVC资源则进一步将卷的使用分为卷的申请和绑定当用户创建一个PVC表明要申请一个持久卷控制器就会去找到合适的PV然后将PVC的pvc.spec.volumeName设置为PV的名称同时将PVC的信息写入PV的pv.spec.claimRef将PV和PVC进行双向关联这成为动态绑定。
那什么才是合适的PV呢或者说PV满足哪些条件才能被某个PVC进行绑定呢 容量在PVC中是request表明需要多大容量的PV在PV中是capacity表明当前PV的容量访问模式accessModes不同的存储系统有不同的访问特点有的卷可以被多个Pod同时读写有的只能以只读方式挂载存储类storageClassName创建PV的存储类型
当根据PVC去查找PV时就会根据上述三个条件去找到对应的PV完成绑定操作。PVC使得用户选择不用自己去选择PV而是让控制器帮我们选择合适的PV。
还剩下最后一个问题PV应该是谁创建的肯定有一个类似控制器的组件负责创建PV该控制器能够接收创建PV的请求根据请求中的参数创建对应规格的持久卷。
k8s可以对接许多不同的外部存储系统为了区分这些存储系统k8s提供了StorageClass资源每个StorageClass代表一个存储系统为了支持这个存储系统在k8s中还会有一个provisoner的组件它通过CSI接口与外部存储系统进行通信负责PV的管理。 下面数理下整体的工作流程
用户创建PVC说明要申请一个PV此时的PVC的状态是Pendingprovisioner监听到PVC的创建时会根据PVC的参数调用CSI接口创建PV此时PV的状态是Available表明未被绑定控制器监听到PV的创建并发现未被绑定的PVC就会将二者进行绑定将PV挂载到容器中使用
下面的PVC申请2G大小的nfs存储卷
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-pvc
spec:accessModes:- ReadWriteOnceresources:requests:storage: 2GistorageClassName: nfs而在SC中
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfsannotations:storageclass.kubernetes.io/is-default-class: true ## 是否设置为默认的storageclass
provisioner: nfs.csi.k8s.io
parameters:archiveOnDelete: true ## 设置为false时删除PVC不会保留数据,true则保留数据
mountOptions: - hard ## 指定为硬挂载方式- nfsvers4 上面的PVC指定storageClassName为nfs表明要向nfs申请卷下面的SC由于有is-default-class的annotations它就是默认的SC当PVC未指定storageClassName时就会向nfs申请卷。SC中有个参数是provisioner是provisioner的标识字符串通常是csidriver驱动程序的名称可以通过kubectl get csidrivers命令查询。
4 总结
本文介绍了k8s中的PV、PVC、SC等资源以及它们的出现分别解决了什么问题并对资源的yaml文件的一些字段进行了解释。