赞
踩
还有一些其它的特性,如:
安全性:通过使用只读存储卷,可以限制容器对数据的修改权限,从而提高数据的安全性。此外,一些存储卷类型(如加密云存储)还可以提供额外的数据保护功能。
可移植性:存储卷的使用使得应用在不同Kubernetes集群之间的迁移变得更加容易。只要目标集群支持相同的存储卷类型,并且已经配置了相应的存储资源,就可以轻松地将应用及其数据迁移到新的环境中。
日志和监控:存储卷可以用于存储应用的日志和监控数据。通过将日志和监控数据写入存储卷中,可以长期保存这些数据,并使用专门的日志和监控工具进行分析和警报。
生命周期:
emptyDir 提供的存储是临时的,其生命周期与所属的 Pod 相关。
emptyDir的生命周期与Pod相同,即当Pod被删除时,emptyDir也会被删除。
Pod 内容器之间的共享:
存储位置:
mkdir -p /data/volumes #新建目录 cd /data/volumes/ #切换目录 #编辑yaml配置文件 vim pod-emptydir.yaml apiVersion: v1 #指定Kubernetes API 的版本 kind: Pod #指定创建的资源类型为Pod metadata: #定义pod元信息 name: pod-emptydir #指定pod的名称 spec: #定义Pod的期望状态。 containers: #定义Pod中要运行的容器 - name: myapp #指定容器名称为myapp image: soscscs/myapp:v1 #指定镜像 imagePullPolicy: IfNotPresent #指定镜像拉取策略,优先使用本地镜像,本地没有则会拉取镜像 ports: #定义端口列表 - name: http #指定端口名称为http containerPort: 80 #指定容器暴漏端口为80 volumeMounts: #定义容器要挂载的卷 - name: html #这是卷的名称,与下面的volumes部分中定义的卷名称相对应 mountPath: /usr/share/nginx/html #容器内部的挂载路径 - name: centos #指定容器名称centos image: centos:7 #指定镜像 imagePullPolicy: IfNotPresent #指定镜像拉取策略 volumeMounts: #定义容器要挂载的卷 - name: html #同样定义卷的名称,与volumes部分定义的名称一致 mountPath: /data/ #容器内部的挂载路径 command: ['/bin/sh','-c','while true;do echo $(date +%F--%H:%M:%S) >> /data/index.html;sleep 2;done'] #容器内部执行的命令,使用死循环语句,每两秒输出时间格式为%F(年、月、日)--%H(时):%M(分):%S(秒)到挂载的文件 volumes: #定义了 Pod 中的卷 - name: web #卷的名称,与上面的volumeMounts部分中定义的名称相对应 emptyDir: {} #这定义了一个空目录卷。Pod 中的所有容器都可以访问这个卷 #当Pod被删除时,这个卷也会被删除。空目录卷通常用于临时存储,例如在Pod中的容器之间共享数据 -------------------------------------------------------------------------------------------------------- 说明: 最下方volumes定义了一个名为html的卷,类型为emptyDir。emptyDir是一个临时卷,它的生命周期与Pod相同。当Pod被分配给节点时,会创建一个空的卷(emptyDir: {}),并且只要Pod运行在该节点上,卷就一直存在。如果Pod从节点上删除(无论是由于某些错误还是正常的删除操作),则卷中的数据也会被永久删除。 nginx(soscscs/myapp:v1)容器将html卷(emptyDir: {})挂载到/usr/share/nginx/html路径下。 centos容器将html卷(emptyDir: {})挂载到/data/路径下。 因此,当这个Pod被创建并运行后,两个容器都可以访问和修改html卷(emptyDir: {})中的数据。这可以用于共享数据、配置文件、日志文件等。但是,由于emptyDir是临时的,所以一旦Pod被删除,这些数据也会丢失 --------------------------------------------------------------------------------------------------------
kubectl apply -f pod-emptydir.yaml
#创建资源
kubectl get pods -owide -w
#查看pod资源详细信息
curl 10.244.2.111
#访问ip
#在上面yaml文件中定义了2个容器,其中一个容器是输入日期到index.html中,然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。
kubectl delete -f pod-emptydir.yaml #删除之前创建的容器 #编辑yaml配置文件 vim pod-hostpath.yaml apiVersion: v1 kind: Pod metadata: name: pod-hostpath spec: containers: - name: nginx image: nginx:1.18.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 volumeMounts: #定义如何在容器内部挂载存储卷 - name: html #指定要挂载的存储卷的名称,volumes.name字段定义的名称 mountPath: /usr/share/nginx/html #容器内部的目录路径,存储卷将被挂载到这个路径上 readOnly: false #false表示容器可以读写该存储卷 volumes: #定义宿主机上的目录文件为Pod中可用的存储卷, - name: html #自定义存储卷的名称 hostPath: #指定存储卷类型为hostPath, path: /data/html/nginx/ #指定宿主机上可以挂载到pod中的目录或文件 type: DirectoryOrCreate #指定hostPath的类型,DirectoryOrCreate表示不存时创建 -------------------------------------------------------------------------------------------------------- 'readOnly' #如果设置为true,则容器以只读方式挂载的存储卷;如果设置为false或空值,则容器可以读写该存储卷 'hostPath' #允许将主机上的文件系统目录或文件挂载到Pod中 'type 可设置的类型值' #"" (默认):不进行任何特殊处理。 #DirectoryOrCreate:如果指定路径下的目录不存在,则创建它。 #Directory:目录必须存在。 #FileOrCreate:如果指定路径下的文件不存在,则创建它。 #File:文件必须存在。 #Socket:UNIX套接字必须存在。 #CharDevice:字符设备必须存在。 #BlockDevice:块设备必须存在 -------------------------------------------------------------------------------------------------------- kubectl apply -f pod-hostpath.yaml #创建资源 kubectl get pods -owide #查看pod资源详细信息
cd /data/html/nginx/
#切换目录
echo "this is hostpath" > index.html
#创建访问页面,因为是将宿主机上的目录挂载到pod上,会覆盖挂载点(/usr/share/nginx/html)下的文件
curl 10.244.2.112
#访问验证
kubectl delete -f pod-hostpath.yaml
#删除容器
node02节点查看
cat index.html
#删除容器之后到之前的node节点依然可以访问之前创建的页面
--------------------------------------------------------------------------------------------------------
#需要注意的是,当宿主机(即node节点)发生故障时,数据仍会丢失,且hostPath卷直接引用主机上的文件或目录,因此它可能会暴露敏感数据或允许Pod执行不受限制的操作。在生产环境中,通常建议使用更安全的存储解决方案,如持久卷(PersistentVolumes)或云提供商提供的存储服务。
#当pod生命周期结束后创建新的pod,只要是指定挂载此存储卷,依然可以访问到数据
#hostPath会自动优先选择合适的节点,如node02上有指定的挂载路径,则不需要再去node01节点上创建,会自动选择带有指定挂载路径的节点
--------------------------------------------------------------------------------------------------------
在Kubernetes中,NFS共享存储卷是一种常见的持久化存储解决方案,它允许多个Pod在集群中共享同一个NFS服务器上的存储空间。
mkdir -p /data/volumes #创建共享目录 chmod 777 /data/volumes/ #添加权限 echo "this is nfs" > /data/volumes/index.html #创建共享目录,并添加权限,自定义访问界面 vim /etc/exports /data/volumes/ 192.168.10.0/24(rw,no_root_squash) #添加共享目录信息及权限到/etc/exports文件中进行共享 systemctl start rpcbind systemctl start nfs #启动共享服务(未安装时,先进行安装) ss -natp |grep rpcbind #RPC端口,远程连接 ss -natp |grep 2049 #NFS端口,提供服务
showmount -e 192.168.10.14
#任意节点查看nfs目录共享
#编辑yaml配置文件,定义存储文件 vim pod-nfs.yaml apiVersion: v1 kind: Pod metadata: name: pod-nfs #pod的名称 spec: containers: - name: nginx #容器的名称 image: nginx:1.18.0 imagePullPolicy: IfNotPresent #镜像拉取策略 ports: - name: http containerPort: 80 volumeMounts: - name: nfs mountPath: /usr/share/nginx/html #容器内挂载卷的路径 readOnly: false volumes: #Pod级别的卷定义 - name: nfs nfs: #指定使用nfs存储卷 path: /data/volumes #指定nfs服务器的共享目录 server: 192.168.10.14 #指定挂载的nfs服务器,地址映射后,也可以写主机名
kubectl apply -f pod-nfs.yaml
#创建pod资源
kubectl get pods -owide
#查看pod资源详细信息
#访问
curl 10.244.2.113
this is nfs
#同样的,删除pod后,重新创建,只要使用nfs挂载此文件,可以得到数据的持久化存储。
#但是容易发生单点故障,服务器宕机时所有客户端无法访问,多台客户端挂载在同一台服务器上,管理维护较繁琐
总结
emptyDir、hostPath和NFS是Kubernetes中三种不同的存储卷类型,它们各自具有不同的特点和用途:
emptyDir适用于临时数据和需要共享数据的Pod;
hostPath适用于需要访问宿主机文件系统的特殊场景;
NFS则是一种网络存储解决方案,可以实现数据的跨节点共享和访问。
PV(Persistent Volume)从创建到销毁的过程通常包括以下几个步骤:
在 Pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候直接指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据配置的定义去 PV 申请,而 PV 是由存储空间创建出来的。PV 和 PVC 是 Kubernetes 抽象出来的一种存储资源
简单来说,类似于LVM逻辑卷,LVM逻辑卷是将磁盘整合建立卷组,而后根据卷组建立逻辑卷并指定使用空间的大小
而PV就是将共享服务器(例如NFS、CEPH等)进行划分,建立一个或多个PV存储卷,PVC指定挂载存储卷的大小及访问模式(读、写),挂载对应的PV卷,达到数据持久化存储
Provisioning---> Binding---> Using---> Releasing ---> Recycling
● Provisioning(创建):即 PV 的创建,可以直接创建 PV(静态方式),也可以使用 StorageClass 动态创建
● Binding(绑定):将 PV 分配给 PVC
● Using(使用):Pod 通 PVC使用该 Volume,并可以通过准入控制StorageProtection(1.9及以前版本为PVCProtection) 阻止删除正在使用的 PVC
● Releasing(释放):Pod 释放 Volume 并删除 PVC
● Reclaiming(回收): PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除
以NFS共享服务器为例
首先在NFS服务器上建立共享目录
建立PV卷,定义PV卷的大小与访问模式
创建PVS请求,是PVC与PC之间建立联系
创建pod,指定需要使用的PVC
静态PV
静态PV就是手动创建PV,然后等待PVC请求,建立连接
NFS使用PV与PVC
cd /data/volumes/ #切换目录 mkdir pv{1..4} #创建目录 #添加共享目录 vim /etc/exports /data/volumes/pv1 192.168.10.0/24(rw,no_root_squash) /data/volumes/pv2 192.168.10.0/24(rw,no_root_squash) /data/volumes/pv3 192.168.10.0/24(rw,no_root_squash) /data/volumes/pv4 192.168.10.0/24(rw,no_root_squash) exportfs -avr #重新导出/etc/ecports文件中定义的共享目录 showmount -e #查看nfs服务器的所有共享目录
#查看PV的定义方式
kubectl explain pv
KIND: PersistentVolume
VERSION: v1
apiVersion <string>
#设置为v1即可,通用版本
kind <string>
#设置PV卷,kind的值为:PersistentVolume
metadata <Object>
#PV是集群级别的资源,可以跨namespace,所以不需要指定
spec <Object>
#定义PV的特性
status <Object>
#状态,创建后自动生成,一般不需要配置
#查看pv.spec可设置字段 kubectl explain pv.spec ... ---------------------'accessModes ([string] 类型)'------------------------------------------------------- 定义了卷的访问模式。PV 可以被单个节点以某种方式访问,或者被多个节点以某种方式访问。 可能的值有: ReadWriteOnce (RWO): 卷可以被单个节点以读写模式挂载。 ReadOnlyMany (ROX): 卷可以被多个节点以只读模式挂载。 ReadWriteMany (RWX): 卷可以被多个节点以读写模式挂载。 #注意:nfs支持三种访问模式,但是不是所有的存储类型都支持所有的访问模式。 #例如iSCSI不支持ReadWriteMany;HostPath不支持ReadOnlyMany和ReadWriteMany -------------------------------------------------------------------------------------------------------- ---------------------------------'capacity '------------------------------------------------------------ 描述了 PV 的存储容量。通常包含一个条目键为storage值为存储容量大小, 如storage: 1Gi -------------------------------------------------------------------------------------------------------- -----------------------------------'nfs'---------------------------------------------------------------- 定义存储卷类型为nfs,以下常用两个字段 path: 定义挂载卷路径 server: 定义服务器名称 -------------------------------------------------------------------------------------------------------- -----------------'persistentVolumeReclaimPolicy (string 类型)'------------------------------------------- 当 PV 不再被 PVC 引用时(即 PVC 被删除),此字段定义了 PV 的回收策略 Retain: 手动回收,保留 PV,需要管理员手动处理。 Recycle: 基本弃用,只有 NFS 和 HostPath 支持 Delete: 删除与 PV 关联的存储资源。 -------------------------------------------------------------------------------------------------------- -------------------------------'storageClassName'------------------------------------------------------- 自定义存储类名称,此配置用于绑定具有相同类别的PVC和PV 如果 PV 属于某个 StorageClass,则该字段将包含 StorageClass 的名称。 PVC 可以请求特定 StorageClass 的 PV。 -------------------------------------------------------------------------------------------------------- --------------------------'volumeMode (string 类型)'----------------------------------------------------- 指定了卷的模式,可以是文件系统或块设备。 Filesystem: PV 作为文件系统挂载到容器中。 Block: PV 作为原始块设备挂载到容器中(通常用于数据库等需要直接访问块设备的场景)。 --------------------------'nodeAffinity (Object)'------------------------------------------------------- 描述了 PV 对节点的亲和性规则。 -------------------------------------------------------------------------------------------------------- ......
#编辑yaml配置文件 vim pod-pv.yaml apiVersion: v1 kind: PersistentVolume #定义了资源的类型为PersistentVolume metadata: name: pv01 labels: name: pv01 spec: #这是PV的规格描述 nfs: #指定了PV的后端存储类型为NFS path: /data/volumes/pv1 #NFS服务器上存储卷的路径 server: 192.168.10.14 #NFS服务器的IP地址 accessModes: ["ReadWriteMany","ReadWriteOnce"] #定义PV的访问模式为两种,RWX,RWO capacity: #定义PV容量 storage: 1Gi #指定PV存储容量为1GiB --- apiVersion: v1 kind: PersistentVolume metadata: name: pv02 labels: name: pv02 spec: nfs: path: /data/volumes/pv2 server: 192.168.10.14 accessModes: ["ReadWriteOnce"] #定义PV的访问模式为RWO capacity: storage: 2Gi #指定PV存储容量为2GiB --- apiVersion: v1 kind: PersistentVolume metadata: name: pv03 labels: name: pv03 spec: nfs: path: /data/volumes/pv3 server: 192.168.10.14 accessModes: ["ReadWriteMany","ReadWriteOnce"] #定义PV的访问模式为两种RWX,RWO capacity: storage: 2Gi #指定PV存储容量为2GiB --- apiVersion: v1 kind: PersistentVolume metadata: name: pv04 labels: name: pv04 spec: nfs: path: /data/volumes/pv4 server: 192.168.10.14 accessModes: ["ReadWriteMany","ReadWriteOnce"] #定义PV的访问模式为两种RWX,RWO capacity: storage: 3Gi #指定PV存储容量为3GiB
kubectl apply -f pod-pv.yaml
#创建资源
kubectl get pv
#查看pv资源
#查看pvc定义字段
kubectl explain pvc
......
apiVersion: v1
kind: PersistentVolumeClaim
metadata
spec
status
.....
#apiVersion、metadata、status字段与pv基本一致,kind字段设置为PersistentVolumeClaim
kubectl explain pvc.spec #查看pvc.spec下的字段 ---------------------'accessModes ([string] 类型)'------------------------------------------------------- 描述用户应用对存储资源的访问权限 ReadWriteOnce (RWO): 卷可以被单个节点以读写模式挂载。 ReadOnlyMany (ROX): 卷可以被多个节点以只读模式挂载。 ReadWriteMany (RWX): 卷可以被多个节点以读写模式挂载。 #注意:nfs支持三种访问模式,但是不是所有的存储类型都支持所有的访问模式。 #例如iSCSI不支持ReadWriteMany;HostPath不支持ReadOnlyMany和ReadWriteMany -------------------------------------------------------------------------------------------------------- --------------------------------'volumeMode'------------------------------------------------------------ 描述希望使用的 PV 存储卷模式。 可以是文件系统 (Filesystem) 或裸格式的块设备 (Block)。 -------------------------------------------------------------------------------------------------------- ----------------------------'resources (Object)'-------------------------------------------------------- 描述对存储资源的请求。定义申请资源的大小 目前仅支持设置 requests.storage,即对存储空间的设置。 -------------------------------------------------------------------------------------------------------- -------------------------'storageClassName (string)'---------------------------------------------------- 定义存储类名称,此配置用于绑定具有相同类别的PVC和PV 如果有多个 PV 符合 PVC 的要求,Kubernetes 会基于 PVC 指定的StorageClass来选择 PV -------------------------------------------------------------------------------------------------------- ----------------------------'selector (Object)'--------------------------------------------------------- 一个可选字段,用于更精细地选择 PV。 可以通过 matchLabels 和 matchExpressions 来选择具有特定标签的 PV。 --------------------------------------------------------------------------------------------------------
#编辑yaml配置文件 vim pod-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim #指定资源类型为PersistentVolumeClaim,即PVC metadata: name: pvc01 spec: accessModes: ["ReadWriteMany"] #定义期望获得的访问模式为ReadWriteMany,即RWX resources: #描述 PVC 的资源需求 requests: #列出PVC所请求的特定资源 storage: 2Gi #指定PVC所请求的存储容量。指定为2Gi,那么就会匹配存储容量为2Gi的PV kubectl apply -f pod-pvc.yaml #创建资源 kubectl get pv #查看创建结果 ------------------------------------------------------------------------------------------------------ PV 的状态(STATUS)有以下 4 种 - Available(可用):表示可用状态,还未被任何 PVC 绑定 - Bound(已绑定):表示 PV 已经绑定到 PVC - Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收 - Failed(失败):表示该 PV 的自动回收失败 ------------------------------------------------------------------------------------------------------
#编辑yaml配置文件 vim pod-pv01.yaml apiVersion: v1 kind: Pod metadata: name: pod-pv namespace: default spec: containers: - name: nginx image: nginx:1.18.0 volumeMounts: - name: html #指定要挂载的存储卷名称,与volumes.name字段设置的一致 mountPath: /usr/share/nginx/html #将volumes字段设置的存储卷挂载到该路径下 volumes: - name: html #定义存储卷名称 persistentVolumeClaim: #定义存储卷是由PersistentVolumeClaim(PVC)提供 claimName: pvc01 #指定PVC名称的pvc01 kubectl apply -f pod-pv01.yaml #创建pod资源 kubectl get pods pod-pv -owide #查看pod资源详细信息
cd /data/volumes/pv3
#切换到PVC绑定的路径
echo "this is pv3" >index.html
#编辑访问页面
master节点:
curl 10.244.2.199
#访问pod就可以看到自定义的访问界面
此时就可以实现存储数据的持久化,哪怕pod意外中断退出,或手动删除以后,数据依旧会保存在NFS服务器上。但是,此时因为手动创建了四个PV,而且是PVC是指定已经存在的PV,并匹配对应的PV资源类型,如果面对庞大的PVC请求,且请求的资源类型与访问模式不同,如果设置的是静态PV,那么就需要手动创建一个个对应的请求,这是一个庞大的工作量,想要解决这个问题就需要设置动态PV
动态PV是在集群级别使用StorageClass和Provisioner来自动创建PV对象的方式
Kubernetes 本身支持的动态PV创建,但是不包括NFS,所以需要使用外部存储卷插件分配PV。卷插件称为 Provisioner(存储分配器),NFS 使用的是 nfs-client,这个外部PV。
StorageClass为管理员提供了一种描述存储“类”(Class)的方法。它允许管理员定义不同的存储类别,每个类别可能会映射到不同的服务质量等级、备份策略或其他存储相关的策略。
StorageClass为用户屏蔽了后端存储的细节,用户只需指定StorageClass的名称,而无需关心具体的存储实现。
基于StorageClass,Kubernetes可以动态地为PersistentVolumeClaims(PVCs)创建PersistentVolumes(PVs),从而实现了动态的资源供应。
管理员首先定义一个StorageClass,它描述了存储类的属性,如存储类型、后端存储参数(如NFS服务器的地址和路径)、回收策略等。StorageClass中指定了Provisioner插件,该插件负责根据StorageClass的定义动态创建PV
根据StorageClass中指定的Provisioner插件,管理员需要在Kubernetes集群中安装并配置相应的插件
用户或应用开发者在Kubernetes集群中创建一个PVC,指定所需的存储大小、访问模式以及StorageClass的名称
Kubernetes系统监控PVC的创建,并查找与之匹配的StorageClass。一旦找到匹配的StorageClass,Kubernetes会触发Provisioner插件根据StorageClass的定义动态创建一个PV。
创建好的PV会自动与PVC进行绑定。这个绑定过程是基于PVC中的请求参数(如存储大小和访问模式)与PV的属性进行匹配的
当Pod创建时,它可以指定使用某个已绑定的PVC。Kubernetes会将PV挂载到Pod中,使得Pod中的应用可以访问该PV上的数据。
kubectl delete -f pod-pv01.yaml
kubectl delete -f pod-pvc.yaml
kubectl delete -f pod-pv.yaml
#删除之前创建的资源
#删除时需要注意的是,首先删除PVC,因为PV一旦被占用,则无法进行删除,需要删除PVC释放PV资源
mkdir /nfs/k8s #创建目录 chmod -R 777 /nfs/k8s/ #添加权限 #编辑共享目录 vim /etc/exports /nfs/k8s 192.168.10.0/24(rw,no_root_squash,sync) #允许192.168.10.0/24网段的主机以读写模式挂载/nfs/k8s目录,并且不进行root权限转换(norootsquash),并同步写入(sync) exportfs -avr #重新加载配置 showmount -e #查看共享目录
在所有node节点上部署NFS-CLIENT-PROVISIONER镜像
从Docker仓库或其他可信来源下载NFS-CLIENT-PROVISIONER的Docker镜像。并确保每个节点上都有NFS服务
镜像下载地址:external-storage/nfs-client at master · kubernetes-retired/external-storage · GitHub
镜像包下载完毕后上传到node节点服务器,并使用docker命令生成镜像
cd /data
#切换目录
#上传需要的镜像文件nfs-client-provisioner.tar
docker load -i nfs-client-provisioner.tar
#将镜像文件导入镜像库
# 创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限 vim nfs-client-rbac.yaml apiVersion: v1 kind: ServiceAccount #指定资源类型为用户 metadata: name: nfs-client-provisioner #Service Account 的名称 --- #创建集群角色 apiVersion: rbac.authorization.k8s.io/v1 #表示使用的是RBAC API的版本1 kind: ClusterRole #定义一个集群级别的角色 metadata: name: nfs-client-provisioner-clusterrole #集群角色的名称,用于在Kubernetes集群中唯一标识 rules: #ClusterRole中定义的具体权限列表 - apiGroups: [""] #表示核心API组,不包含任何前缀的API组 resources: ["persistentvolumes"] #表示对持久卷(PersistentVolumes)的权 verbs: ["get", "list", "watch", "create", "delete"] #verbs: 列出了可以执行的操作get(获取)、list(列表)、watch(监听)、create(创建)和delete(删除) - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] #第二个规则组,与第一个规则类似,但针对的是持久卷声明 - apiGroups: ["storage.k8s.io"] #表示存储API组的名称 resources: ["storageclasses"] #表示对存储类(StorageClasses)的权限。 verbs: ["get", "list", "watch"] #列出了可以执行的操作,但仅允许读取操作(get、list和watch) - apiGroups: [""] resources: ["events"] verbs: ["list", "watch", "create", "update", "patch"] #定义了对Kubernetes事件(Events)的权限 - apiGroups: [""] resources: ["endpoints"] verbs: ["create", "delete", "get", "list", "watch", "patch", "update"] #定义了对端点(Endpoints)的广泛权限,包括创建、删除、获取、列表、监听、补丁和更新 --- #集群角色绑定 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding #定义了一个名为nfs-client-provisioner-clusterrolebinding的ClusterRoleBinding,将前面定义的ClusterRole绑定到先前定义的Service Account上,以确保该Service Account拥有相应的权限 metadata: name: nfs-client-provisioner-clusterrolebinding # 集群角色绑定的名称 subjects: #定义了哪些用户或用户组会被授予权限 - kind: ServiceAccount #定义了一个名为nfs-client-provisioner的Service Account,用于代表NFS Provisioner在集群中运行时的身份 name: nfs-client-provisioner #绑定的Service Account的名称 namespace: default #所在的命名空间 roleRef: #定义了该绑定所引用的ClusterRole kind: ClusterRole #定义了一个名为nfs-client-provisioner-clusterrole的ClusterRole,包含了对于Persistent Volumes(PV)、Persistent Volume Claims(PVC)、StorageClasses等资源的访问权限规则。这些规则包括获取、列出、监视、创建和删除PV、PVC,以及获取、列出、监视StorageClasses等操作。 name: nfs-client-provisioner-clusterrole #所绑定的集群角色名称 apiGroup: rbac.authorization.k8s.io #表示API组的名称,对于ClusterRole,它通常是rbac.authorization.k8s.io #这段YAML文件定义了在Kubernetes中创建一个Service Account以及相关的ClusterRole和ClusterRoleBinding来管理NFS Provisioner的权限。通过这些定义,可以确保NFS Provisioner在Kubernetes集群中具有适当的权限,以管理PV、PVC和StorageClasses等资源。 kubectl apply -f nfs-client-rbac.yaml #创建资源 kubectl get serviceaccount/nfs-client-provisioner -owide kubectl get clusterrole nfs-client-provisioner-clusterrole -owide kubectl get clusterrolebindings nfs-client-provisioner-clusterrolebinding -owide #查看新建资源的详细信息
NFS Provisione(即 nfs-client),有两个功能:
NFS Provisioner能够自动为Kubernetes集群中的Pod提供NFS持久卷。,在 NFS 共享目录下创建挂载点(volume),持久卷的名称遵循一定的格式,通常是namespace-{pvcName}-${pvName}。
将 PV 与 NFS 的挂载点建立关联。
工作原理
#编辑yaml配置文件 vim nfs-client-pro.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: #指定更新Pod的策略 type: Recreate #更新Deployment时,将使用重建(Recreate)策略 template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner #指定Pod使用的ServiceAccount的名称 containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest #之前下载的镜像 imagePullPolicy: IfNotPresent volumeMounts: #定义容器内的挂载点,挂载到什么位置 - name: nfs-k8s #挂载卷名称、volumes定义的 mountPath: /persistentvolumes #挂载到该路径 env: #定义容器的环境变量。 - name: PROVISIONER_NAME #变量名称,配置provisioner的Name value: nfs-storage #变量值,此值在建立StorageClass时使用 - name: NFS_SERVER #变量名称,指定NFS服务器 value: 192.168.10.14 #NFS服务器地址或主机名 - name: NFS_PATH #变量名称,指定共享目录 value: /nfs/k8s #NFS共享目录 volumes: #定义Pod中的卷 - name: nfs-k8s #卷的名称,与上面的volumeMounts定义中的名称相匹配 nfs: #定义NFS卷的参数 server: 192.168.10.14 #NFS服务器的地址 path: /nfs/k8s #NFS服务器上的共享路径 ---------------------------------------------------------------------------------------------------- Recreate(重建): 使用此策略时,Kubernetes会首先终止所有的旧Pods,然后等待这些Pods都被 完全删除并清理后,再创建新的Pods。这意味着在更新过程中,服务可能会经历一段不可用时间,因 为所有的Pods都会被同时替换。虽然这种方法可能导致服务中断,但它有时更简单、更可靠,特别是 当应用程序不支持滚动更新或者需要确保在更新过程中没有两个版本的Pods同时运行时。 ---------------------------------------------------------------------------------------------------- kubectl apply -f nfs-client-pro.yaml #创建资源 kubectl get deployments.apps nfs-client-provisioner #查看deploy资源信息 kubectl get pod #查看pod资源信息
负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
定义StorageClass:StorageClass是Kubernetes中用于描述存储类的一种资源对象。通过定义StorageClass,可以指定如何为PVC提供后端存储(如NFS)。
在StorageClass中,可以指定Provisioner(如NFS-CLIENT-PROVISIONER)、存储类型、配置参数等。
StorageClass的作用:当PVC被创建时,Kubernetes会根据PVC的存储要求查找匹配的StorageClass,并委托给相应的Provisioner来创建满足要求的PV。因此,StorageClass是PVC和PV之间的桥梁,它使得Kubernetes能够根据PVC的要求动态地创建和管理PV。
#编辑yaml配置文件 vim nfs-storageclass.yaml apiVersion: storage.k8s.io/v1 #指定了Kubernetes API的版本和组 kind: StorageClass #创建StorageClass资源 metadata: name: nfs-client-storageclass #指定名称 provisioner: nfs-storage #指定了用于供应存储卷的供应器(provisioner)的名称 #与创建nfs-client-provisioner的PROVISIONER_NAME变量的值相同 parameters: #供应器需要的任何额外参数 archiveOnDelete: "false" #false表示在删除PVC时不会对数据进行存档,即删除数据 ------------------------------------------------------------------------------------------------------ PROVISIONER:这是负责为PersistentVolumeClaims(PVCs)动态创建PersistentVolumes(PVs)的存储系统 RECLAIMPOLICY:定义了当PersistentVolume(PV)的声明(PVC)被删除时,PV应该怎么做。Delete策略意味着PV和它上面的数据将被删除。 VOLUMEBINDINGMODE:定义了如何以及何时将PersistentVolumeClaims(PVCs)绑定到PersistentVolumes(PVs)。Immediate模式意味着一旦PVC被创建,就会立即查找并绑定一个合适的PV。 ALLOWVOLUMEEXPANSION:定义了是否允许扩展已存在的PersistentVolume(PV)。设置为false表示不允许扩展。 ----------------------------------------------------------------------------------------------------- kubectl apply -f nfs-storageclass.yaml #创建资源 kubectl get storageclass #查看资源信息
vim /etc/kubernetes/manifests/kube-apiserver.yaml ....... spec: containers: - command: - kube-apiserver - --feature-gates=RemoveSelfLink=false #添加此字段用于关闭自链接(self-link)功能 在Kubernetes 1.20及更高版本中,由于API的更改,许多组件不再使用或提供自链接字段。当NFS Provisioner尝试访问PVC(Persistent Volume Claim)的自链接以创建PV时,可能会因为找不到该字段而报错。 报错示例: 报错信息可能类似于“unexpected error getting claim reference: selfLink was empty, can't make reference”。 #这表明Provisioner试图获取PVC的自链接,但发现它是空的
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
#更新apiserver
kubectl get pod -n kube-system |grep apiserver
#查看创建的apiserver信息
kubectl delete pod kube-apiserver -n kube-system
#删除之前的kube-apiserver
kubectl get pod -n kube-system |grep apiserver
#查看apiserver信息
#编辑yaml配置文件 vim pvc-pod.yaml apiVersion: v1 kind: PersistentVolumeClaim #定义持久卷声明(PersistentVolumeClaim),用于请求持久卷 metadata: name: test-nfs-pvc #持久卷声明的名称 spec: accessModes: - ReadWriteMany #访问模式设置为读写多个节点 storageClassName: nfs-client-storageclass #关联的存储类对象 resources: requests: storage: 1Gi #请求的存储容量为1Gi --- #定义Pod,用于使用持久卷 apiVersion: v1 kind: Pod metadata: name: test-storageclass-pod #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 #Pod 的重启策略 volumes: - name: nfs-pvc #定义一个名为nfs-pvc的卷 persistentVolumeClaim: claimName: test-nfs-pvc #引用之前定义的持久卷声明的名称 #这个 YAML 文件定义了一个 Kubernetes Pod 和一个 PersistentVolumeClaim(持久卷声明)。Pod 使用了名为 test-nfs-pvc 的持久卷声明,请求了 1Gi 的存储空间,并使用了 nfs-client-storageclass 存储类。Pod 中的容器使用了 BusyBox 镜像,并将持久卷挂载到 /mnt 路径下。 Pod 的重启策略设置为 Never,这意味着当 Pod 退出时,不会自动重启。 kubectl apply -f pvc-pod.yaml #创建资源 nfs服务器节点: ls /nfs/k8s/ #创建完pvc后,会在NFS服务器的共享目录中建立一个文件 #自动创建的PV会以${namespace}-${pvcName}-${pvName}的目录格式放到NFS服务器上
kubectl exec -it test-storageclass-pod sh
#进入容器内部
cd mnt
#切换到挂载目录
echo "this is xxxx" > index.html
#编辑访问页面
exit
#退出
cd /nfs/k8s/
cd default-test-nfs-pvc-pvc-93d17ec0-127e-4e6d-b230-2844605abf27/
#切换目录
cat index.html
#查看页面内容
定义
生命周期
作用
定义
与PV的关系
生命周期
作用
存储类定义了存储的“类”,用于动态供应PV。管理员可以根据不同的需求(如性能、成本)定义多个存储类。
用户在创建PVC时可以选择一个存储类,Kubernetes会自动匹配并创建合适的PV。
对于存储资源,虽然不像CPU和内存那样频繁地设置请求和限制,但在使用PV/PVC时,可以通过设置存储容量的大小来间接限制使用量。
在Pod的YAML定义中,可以通过volumeMounts来指定容器如何挂载卷,以及是否需要设置读写权限等。
Pod中的存储卷可以配置访问模式(如只读、读写)来确保数据的安全性。
对于敏感数据,推荐使用Secrets或ConfigMaps,并注意权限控制。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。