目录

前言

一、Volume 的概念

二、Volume 的类型

常见的卷类型

Kubernetes 独有的卷类型

三、通过 emptyDir 共享数据

1. 编写 emptyDir 的 Deployment 文件

2. 部署该 Deployment

3. 查看部署结果

4. 登录 Pod 中的第一个容器

5. 登录 Pod 中的第二个容器查看/mnt下的文件

6. 删除此 Pod

四、使用 HostPath 挂载宿主机文件

1. 编写 Deployment 文件,实现 HostPath 挂载

2. 创建此 Pod

3. 查看创建结果

4. 测试挂载情况

5. 删除

五、挂载 NFS 至容器

1. 安装 NFS

2. 设置共享目录(在 NFS 服务器上)

3. 开启 nfs(在 NFS 服务器上)

4. 编写 Deployment 文件,挂载 NFS

5. 部署此 Pod

6. 查看部署结果

7. 登录容器查看挂载结果

六、PersistentVolume(PV,持久卷)

1. PV 回收策略

2. PV 访问策略

3. PV 的配置方式

(1)静态配置

(2)动态配置

4. 基于 HostPath 的 PV

5. 基于 NFS 的 PV

七、PersistentVolumeClaim(PVC,持久卷声明)

1. PVC 的创建

2. PVC 的使用


前言

数据是企业发展的核心,尤其在生产环境中,数据的存储和管理显得尤为重要。Kubernetes 作为容器编排领域的佼佼者,在数据存储方面也提供了强大的支持。本笔记将详细介绍 Kubernetes 存储相关知识,包括 Volume 的概念、类型及使用方法,以及 PersistentVolume 和 PersistentVolumeClaim 的相关内容,帮助读者掌握 Kubernetes 中存储的基本概念和操作方法,为在生产环境中构建高效、可扩展的存储解决方案打下坚实的基础。

一、Volume 的概念

对于大多数项目而言,数据文件的存储是非常常见的需求,比如存储用户上传的头像、文件以及数据库的数据。在 Kubernetes 中,由于应用的部署具有高度的可扩展性和编排能力(不像传统架构部署在固定的位置),因此把数据存放在容器中是非常不可取的,这样无法保障数据的安全。

我们应该把有状态的应用变成无状态的应用,即把数据从应用中剥离出来,将产生的数据文件或者缓存的信息放在云端,比如常用的 NFS(生产环境中不建议使用,因为存在单点故障,推荐使用分布式的存储或者公有云的 NAS 服务)、Ceph、GlusterFS、Minio 等。

在传统架构中,如果要使用这些存储,需要提前在宿主机挂载,然后程序才能访问,实际使用时,经常会碰到新加节点忘记挂载存储导致的一系列问题。而 Kubernetes 在设计之初就考虑了这些问题,并抽象出 Volume 的概念用于解决数据存储的问题。

容器中的磁盘文件是短暂的,当容器崩溃时,Kubectl 会重新启动容器,但容器运行时产生的数据文件都会丢失,之后容器会以干净的状态启动。另外,当一个 Pod 运行多个容器时,各个容器可能需要共享一些文件,诸如此类的需求都可以使用 Volume 解决。

Docker 也有卷的概念,但在 Docker 中,卷只是磁盘上或另一个容器中的目录,其生命周期不受管理。虽然 Docker 已经提供了卷驱动程序,但功能非常有限,例如从 Docker1.7 版本开始,每个容器只允许一个卷驱动程序,并且无法将一些特殊的参数传递给后端存储。

另一方面,Kubernetes 卷具有明确的生命周期,与使用它的 Pod 相同,因此在 Kubernetes 中的卷可以比 Pod 中运行的任何容器的生命周期都长,并且可以在容器重启或者销毁之后保留数据。Kubernetes 支持多种类型的卷,并且 Pod 可以同时使用任意数量的卷。

从本质上讲,和虚拟机或者物理机一样,卷被挂载后,在容器中也只是一个目录,可能包含一些数据,Pod 中的容器也可以对其进行增删改查操作,使用方式和裸机挂载几乎没有区别。要使用卷也非常简单,和其他参数类似,Pod 只需要通过.spec.volumes字段指定为 Pod 提供的卷,然后在容器中配置块,使用.spec.containers.volumeMounts字段指定卷的挂载目录即可。

二、Volume 的类型

在传统架构中,企业内可能有自己的存储平台,比如 NFS、Ceph、GlusterFS、Minio 等。如果所在的环境在公有云,也可以使用公有云提供的 NAS、对象存储等。在 Kubernetes 中,Volume 也支持配置这些存储,用于挂载到 Pod 中实现数据的持久化。Kubernetes Volume 支持的卷的类型有很多。

常见的卷类型

  • CephFS
  • GlusterFS
  • ISCSI
  • Cinder
  • NFS
  • RBD
  • HostPath

Kubernetes 独有的卷类型

  • ConfigMap:用于存储配置文件
  • Secret:用于存储敏感数据
  • EmptyDir:用于一个 Pod 内多个容器的数据共享
  • PersistentVolumeClaim:对 PersistentVolume 的申请

三、通过 emptyDir 共享数据

emptyDir 是一个特殊的 Volume 类型,与上述 Volume 不同的是,如果删除 Pod,EmptyDir 卷中的数据也将被删除,所以一般 emptyDir 用于 Pod 中不同容器共享数据,比如一个 Pod 存在两个容器 A 和容器 B,容器 A 需要使用容器 B 产生的数据,此时可以采用 emptyDir 共享数据,类似的使用如 Filebeat 收集容器内程序产生的日志。

使用 emptyDir 卷时,直接指定 emptyDir 为{}即可。

1. 编写 emptyDir 的 Deployment 文件

[root@k8s-master ~]#cat <<EOF>nginx-empty.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: nginxnamespace: default
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx01volumeMounts:- mountPath: /optname: share-volume- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx02command:- sh- -c- sleep 3600volumeMounts:- mountPath: /mntname: share-volumevolumes:- name: share-volumeemptyDir: {}#medium: Memory
EOF

备注

  • volumeMounts:
    • mountPath: /mnt name: share-volume:容器定义部分的卷挂载名称,此处的名称引用了 volumes 对应的名称
  • volumes:
    • name: share-volume:共享存储卷的名称

此案例会将 nginx01 中/opt中的数据,共享给 nginx02 中的/mnt目录。

此部署文件创建一个 Deployment,采用spec.volume字段配置了一个名字为share-volume、类型为emptyDir的 volume,同时里面包含两个容器nginx01nginx02,并将该 volume 挂载到了/opt/mnt目录下,此时/opt/mnt目录的数据就实现了共享。

默认情况下,emptyDir 支持节点上的任何介质,可以是 SSD、磁盘或是网络存储,具体取决于自身环境。可以将emptyDir.medium字段设置为Memory,让 Kubernetes 使用tmpfs(内存支持的文件系统),虽然tmpfs非常快,但是在节点重启时,数据同样会被清除,并且设置的大小会被记入 Container 的内存限制中。

2. 部署该 Deployment

[root@k8s-master ~]#kubectl create -f nginx-empty.yaml

3. 查看部署结果

[root@k8s-master ~]#kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6fffbd7c7b-jrw7f 2/2 Running 0 10s

4. 登录 Pod 中的第一个容器

[root@k8s-master~]#kubectl exec -ti nginx-6fffbd7c7b-jrw7f -c nginx01 -- sh

备注:在该容器中的/opt下创建一个文件,并到第二个容器中查看,是否是共享的目录。

5. 登录 Pod 中的第二个容器查看/mnt下的文件

[root@k8s-master~]#kubectl exec -ti nginx-6fffbd7c7b-jrw7f -c nginx02 -- sh

注意:登录后,此处可以使用date命令查看容器中的时间,会发现时间是不对的。是因为时区的问题,容器内使用的不是亚洲上海市区,导致时间不对。

6. 删除此 Pod

[root@k8s-master ~]#kubectl delete -f nginx-empty.yaml

四、使用 HostPath 挂载宿主机文件

HostPath 卷可以将节点上的文件或目录挂载到 Pod 上,用于实现 Pod 和宿主机之间的数据共享,常用的示例有挂载宿主机的时区至 Pod,或者将 Pod 的日志文件挂载到宿主机等。

1. 编写 Deployment 文件,实现 HostPath 挂载

以下为使用 HostPath 卷的示例,实现将主机的/etc/localtime文件挂载到 Pod 的/etc/localtime

[root@k8s-master ~]#cat<<EOF nginx-hostPath.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: nginxnamespace: default
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxvolumeMounts:- mountPath: /etc/localtimename: timezone-timevolumes:- name: timezone-timehostPath:path: /etc/localtimetype: File
EOF

备注:关于时区的设置是通过配置/etc/localtime文件设置系统的时区,/etc/localtime用于配置系统时区(此文件是一个链接文件,链接自/usr/share/zoneinfo/Asia/Shanghai)。

2. 创建此 Pod

[root@k8s-master ~]#kubectl create -f nginx-hostPath.yaml

3. 查看创建结果

[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-5c9b77966c-jrw7f 1/1 Running 0 47m

4. 测试挂载情况

[root@k8s-master~]#kubectl exec -ti nginx-5c9b77966c-jrw7f - nginx --sh
#date

在配置 HostPath 时,有一个type参数,用于表达不同的挂载类型,HostPath 卷常用的类型有:

  • type为空字符串:默认选项,在挂载 HostPath 卷之前不会有任何检查
  • DirectoryOrCreate:如果给定的 path 不存在任何东西,那么将根据需要创建一个权限为 0755 的空目录,和 kubelet 具有相同的组和权限
  • Directory:目录必须存在于给定的路径下
  • FileOrCreate:如果给定的路径不存在任何内容,则会根据需要创建一个空文件,权限设置为 0644,和 kubelet 具有相同的组和所有权
  • File:文件,必须存在于给定的路径中
  • Socket:UNIX 套接字,必须存在于给定的路径中
  • CharDevice:字符设备,必须存在于给定的路径中
  • BlockDevice:块设备,必须存在于给定的路径中

5. 删除

[root@k8s-master ~]#kubectl delete -f nginx-hostPath.yaml

五、挂载 NFS 至容器

1. 安装 NFS

在所有的 Kubernetes 节点都要安装:

[root@k8s-master ~]#yum -y install nfs-utils

2. 设置共享目录(在 NFS 服务器上)

[root@k8s-master~]#mkdir /opt/wwwroot
[root@k8s-master~]#echo "This is my test file" > /opt/wwwroot/index.html
[root@k8s-master ~]#vim /etc/exports
/opt/wwwroot 192.168.10.0/24(rw,sync,no_root_squash)

3. 开启 nfs(在 NFS 服务器上)

[root@k8s-master ~]#systemctl start nfs
[root@k8s-master ~]#systemctl start rpcbind

4. 编写 Deployment 文件,挂载 NFS

[root@k8s-master ~]#cat<<EOF nginx-nfsvolume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: nginxnamespace: default
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxvolumeMounts:- mountPath: /usr/share/nginx/htmlname: nfs-volumevolumes:- name: nfs-volumenfs:server: 192.168.10.101path: /opt/wwwroot
EOF

5. 部署此 Pod

[root@k8s-master~]#kubectl create -f nginx-nfsvolume.yaml

6. 查看部署结果

[root@k8s-master ~]#kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-fbd476c4c-zscq9 1/1 Running 0 8m12s

7. 登录容器查看挂载结果

[root@k8s-master~]#kubectl exec -ti nginx-fbd476c4c-zscq9 - nginx --bash

六、PersistentVolume(PV,持久卷)

虽然 volume 已经可以接入大部分存储后端,但是实际使用时还有诸多的问题。比如:

  • 当某个数据卷不再被挂载使用时,里面的数据如何处理?
  • 如果想要实现只读挂载,要如何处理?
  • 如果想要只能有一个 Pod 挂载,要如何处理?

如上所述,对于很多复杂的需求,volume 可能难以实现,并且无法对存储的生命周期进行管理。另一个很大的问题是,在企业内使用 kubernetes 的不仅仅是 kubernetes 管理员,可能还有开发人员、测试人员以及初学 kubernetes 的技术人员,对于 kubernetes 的 volume 或者相关存储平台的配置参数并不了解,所以无法自行完成存储的配置。

为此,kubernetes 引入了两个新的 API 资源:PersistentVolume(持久卷,简称 PV)和 PersistentVolumeClaim(持久卷声明,简称 PVC)。

PV 是 kubernetes 管理员设置的存储,PVC 是对 PV 的请求,标识需要什么类型的 PV。他们同样是集群中的一类资源,但其生命周期比较独立,管理员可以单独对 PV 进行增删改查,不受 Pod 的影响,生命周期可能比挂载它的其他资源还要长。如果一个 kubernetes 集群的使用者并非只有 kubernetes 管理员,那么可以通过提前创建 PV,用以解决对存储概念不是很了解的技术人员对存储的需求。和单独配置 volume 类似,PV 也可以使用 NFS、GFS、CEPH 等常见的存储后端,并且可以提供更为高级的配置,比如访问模式、空间大小以及回收策略等。目前 PV 的提供方式有两种:静态或动态。静态 PV 由管理员提前创建,动态 PV 无需提前创建。

1. PV 回收策略

当用户使用完卷时,可以从 API 中删除 PVC 对象,从而允许回收资源。回收策略会告诉 PV 如何处理该卷。目前回收策略可以设置为 Retain、Recycle 和 Delete。静态 PV 默认的为 Retain,动态 PV 默认为 Delete。

  • Retain:保留,该策略允许手动回收资源,当删除 PVC 时,PV 仍然存在,PV 中的数据也存在。volume 被视为已释放,管理员可以手动回收卷。
  • Recycle:回收,如果 volume 插件支持,Recycle 策略会对卷执行rm -rf清理该 PV,卷中的数据已经没了,但卷还在,使其可用于下一个新的 PVC,但是本策略将会被弃用,目前只有 NFS 和 HostPath 支持该策略。
  • Delete:删除,如果 volume 插件支持,删除 PVC 时会同时删除 PV,PV 中的数据自然也就没了。动态卷默认为 Delete,目前支持 Delete 的存储后端包括 ANS EBS、GCE PD、Azure Disk、OpenStack Cinder 等。

2. PV 访问策略

在实际使用 PV 时,可能针对不同的应用会有不同的访问策略,比如某类 Pod 可以读写,某类 Pod 只能读,或者需要配置是否可以被多个不同的 Pod 同时读写等,此时可以使用 PV 的访问策略进行简单控制,目前支持的访问策略如下:

  • ReadWriteOnce:单路可读可写,可以被单节点以读写模式挂载,命令行中可以被缩写为 RWO。
  • ReadOnlyMany:多路只读,可以被多节点以只读模式挂载,命令行中可以被缩写为 ROX。
  • ReadWriteMany:多路可读可写,可以被多个节点以读写模式挂载,命令行中可以被缩写为 RMX。
  • ReadWriteOncePod:单节点只读(1.22+),只能被一个 Pod 以读写的模式挂载,命令行中可以被缩写为 RWOP。

虽然 PV 在创建时可以指定不同的访问策略,但是也要后端的存储支持才行。比如一般情况下,大部分块存储是不支持ReadWriteMany的。

在企业内,可能存储很多不同类型的存储,比如 NFS、Ceph、GlusterFS 等,针对不同类型的后端存储具有不同的配置方式,这也是对集群管理员的一种挑战,因为集群管理员需要对每种存储都要有所了解。

3. PV 的配置方式

(1)静态配置

静态配置是手动创建 PV 并定义其属性,例如容量、访问模式、存储后端等。在这种情况下,Kubernetes

第12章:Kubernetes存储入门.pdf

接着上面的继续

管理员负责管理和配置 PV,然后应用程序可以使用这些 PV。静态配置通常用于一些固定的存储后端,如 NFS。

(2)动态配置

动态配置允许 Kubernetes 集群根据 PVC 的需求自动创建 PV,在这种情况下,管理员只需为存储后端配置 storageClass,然后应用程序就可以通过 PVC 请求存储。Kubernetes 将自动创建与 PVC 匹配的 PV,并将其绑定到 PVC 上。这种方法使得存储管理更加灵活和可扩展,允许管理员在集群中动态添加、删除和管理存储资源。

4. 基于 HostPath 的 PV

可以创建一个基于 HostPath 的 PV,和配置 NFS 的 PV 类似,只需要配置 hostPath 字段即可,其它配置基本一致。

(1)在所有 node 节点创建主机目录

[root@k8s-master~]#mkdir /mnt/data

(2)编辑 hostpath 的 yaml 文件

[root@k8s-master~]#cat<<EOF>hostpath-pv.yaml
kind: PersistentVolume
apiVersion:v1
metadata:name:mypv-hostpathlabels:type:local
spec:storageClassName :pv-hostpathcapacity:storage:10GiaccessModes :- ReadWriteOncehostPath:path:"/mnt/data"
EOF

备注

  • hostPath: 宿主机的路径,使用 hostPath 类型需要固定 Pod 所在的节点,防止 Pod 漂移造成数据丢失。
  • storageClassName 是一个用于标识 StorageClass 对象名称的标签。当你创建或配置 PersistentVolumeClaim (PVC) 时,可以指定 storageClassName 来告诉 Kubernetes 你希望使用哪个 Storageclass 来配置存储。

(3)创建并查看 PV

[root@k8s-master ~]# kubectl create -f hostpath-pv.yaml
[root@k8s-master~]#kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv-hostpath 10Gi RWO Retain Available pv-hostpath 5s

5. 基于 NFS 的 PV

(1)提前安装好 nfs 服务
可以使用上一个案例中安装好的 NFS,或重新安装一台,步骤如下:
提前安装好 nfs 服务,192.168.10.101 是 nfs 服务器,也可以是任意一台提供了 NFS 服务的主机。
客户端需要在所有的 Kubernetes 节点安装:

yum -y install nfs-utils
mkdir /opt/wwwroot
echo "This is my test file">/opt/wwwroot/index.html
vim /etc/exports
/opt/wwwroot 192.168.10.0/24(rw,sync,no_root_squash)
systemctl start nfs
systemctl start rpcbind

(2)创建一个基于 NFS 的 PV
PV 目前没有 NameSpace 隔离,不需要指定命名空间,在任意命名空间下创建的 PV 均可以在其他 NameSpace 使用。

[root@k8s-master~]#cat<<EOF>nfs-pv.yaml
apiVersion:v1
kind:PersistentVolume
metadata:name:mypv-nfs
spec:capacity:storage:5GivolumeMode: FilesystemaccessModes :- ReadWriteOncepersistentVolumeReclaimPolicy: RecyclestorageClassName:pv-nfsmountOptions:- hard- nfsvers=4.1nfs:path:/opt/wwwroot/server:192.168.10.101
EOF

备注

  • capacity: 容量配置。
  • volumeMode: 卷的模式,目前支持 Filesystem (文件系统) 和 Block (块),其中 Block 类型需要后端存储支持,默认为文件系统。
  • accessModes: 该 PV 的访问模式。
  • storageClassName:PV 的类,一个特定类型的 PV 只能绑定到特定类别的 PVC。
  • persistentVolumeReclaimPolicy: 回收策略。
  • mountoption: 非必要,新版本中已经弃用。
  • nfs:NFS 服务配置,包括 path(NFS 上的共享目录)和 server(NFS 的 IP 地址)。

(3)创建并查看 PV

[root@k8s-master ~]#kubectl create -fnfs-pv.yaml
[root@k8s-master~]#kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv-hostpath 10Gi RWO Retain Available pv-hostpath 76s
mypv-nfs 5Gi RWO Recycle Available pv-nfs 4s

七、PersistentVolumeClaim(PVC,持久卷声明)

当 kubernetes 管理员提前创建好了 PV,我们可以通过 PersistentVolumeClaim(简称 PVC)来使用它。PVC 是其他技术人员在 kubernetes 上对存储的申请,它可以标明一个程序需要用到什么样的后端存储、多大的空间以及什么访问模式进行挂载。这一点和 Pod 的 Qos 配置类似,Pod 消耗节点资源,PVC 消耗 PV 资源,Pod 可以请求特定级别的资源(CPU 和内存),PVC 可以请求特定的大小和访问模式的 PV。例如申请一个大小为 5G 且只能被一个 Pod 只读访问的存储。

在实际使用时,虽然用户通过 PVC 获取存储支持,但是用户可能需要具有不同性质的 PV 来解决不同的问题,比如使用 SSD 硬盘来提高性能。所以集群管理员需要根据不同的存储后端来提供各种 PV,而不仅仅是大小和访问模式的区别,并且无须让用户了解这些卷的具体实现方式和存储类型,实现了存储的解耦,降低了存储使用的复杂度。

PVC 和 PV 进行绑定的前提条件是一些参数必须匹配,比如 accessModes、storageClassName、volumeMode 都需要相同,并且 PVC 的 storage 需要小于等于 PV 的 storage 配置。

1. PVC 的创建

(1)为 hostpath 类型的 PV 创建 PVC

[root@k8s-master ~]# vim pvc-hostpath.yaml
kind: PersistentVolumeClaim
apiVersion:v1
metadata:name:mypvc-hostpath
spec:storageClassName: pv-hostpathaccessModes:- ReadWriteOnceresources:requests:storage:3Gi

注意
storageClassName: 存储类名称需要和对应的 PV 中的名称一致,PV 和 PVC 进行绑定并非是名字相同,而是 StorageClassName 相同且其他参数一致才可以进行绑定。

创建并查看 PVC:

[root@k8s-master ~]#kubectl create -f pvc-hostpath.yaml
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc-hostpath Bound mypv-hostpath 10Gi RWO pv-hostpath 4s

(2)为 NFS 类型的 PV 创建 PVC

[root@k8s-master ~]#cat pvc-nfs.yaml
kind: PersistentVolumeClaim
apiVersion:v1
metadata:name:mypvc-nfs
spec:storageClassName: pv-nfsaccessModes:- ReadWriteOnceresources:requests:storage:3Gi

注意
storageClassName: 存储类名称需要和对应的 PV 中的名称一致。

创建并查看 PVC:

[root@k8s-master ~]#kubectl create -f pvc-nfs.yaml
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc-hostpath Bound mypv-hostpath 10Gi RWO pv-hostpath 3m21s
mypvc-nfs Bound mypv-nfs 5Gi RWO pv-nfs 5s

从上述两个简单的例子可以看出,PVC 的定义和后端存储并没有关系。对于有存储需求的技术人员,直接定义 PVC 即可绑定一块 PV,之后就可以供 Pod 使用,而不用去关心具体的实现细节,大大降低了存储的复杂度。

2. PVC 的使用

上述创建了 PV,并使用 PVC 与其绑定,接下来需要将 PVC 挂载到 Pod。和之前的挂载方式类似,PVC 的挂载也是通过 volumes 字段进行配置的,只不过之前需要根据不同的存储后端填写很多复杂的参数,而使用 PVC 进行挂载时,只填写 PVC 的名字即可,不需要再关心任何的存储细节,这样即使不是 Kubernetes 管理员,不懂存储的其他技术人员想要使用存储,也可以非常简单地进行配置和使用。

(1)创建 pod,绑定 hostpath 的 PV

[root@k8s-master ~]#cat pvc-pv-pod-hostpath.yaml
kind:Pod
apiVersion:v1
metadata:name:hostpath-pv-pod
spec:volumes:- name: task-pv-storagepersistentVolumeClaim:claimName:mypvc-hostpathcontainers:- name:task-pv-containerimage:nginx:1.7.9ports:- containerPort:80name:"http-server"volumeMounts:- mountPath:"/usr/share/nginx/html"name:task-pv-storage

备注
claimName: mypvc-hostpath 是基于 hostpath 创建的 PVC 的名字。

创建并查看 Pod:

[root@k8s-master ~]#kubectl create -f pvc-pv-pod-hostpath.yaml
[root@k8s-master~]#ku get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath-pv-pod 1/1 Running 0 113s 10.244.85.204 k8s-node1 <none> <none>

测试挂载情况:

[root@k8s-node01~]#cd/mnt/data/ 
[root@k8s-node01 data]#touch aaa.txt
[root@k8s-master~]#ku exec -it hostpath-pv-pod -- bash
root@hostpath-pv-pod:/#ls /usr/share/nginx/html/
aaa.txt

(2)创建 pod,绑定 NFS 的 PV

[root@k8s-master ~]#cat pvc-pv-pod-nfs.yaml
kind:Pod
apiVersion: v1
metadata:name:pvc-nfs
spec:volumes:- name:pvc-nfs01persistentVolumeClaim:claimName:mypvc-nfscontainers:- name:task-pv-containerimage:nginx:1.7.9ports:- containerPort:80name:"http-server"volumeMounts:- mountPath:"/usr/share/nginx/html"name:pvc-nfs01

备注: claimName:mypvc-nfs 是基于 NFS 创建的 PVC 的名字。

创建并查看 Pod:

[root@k8s-master~]# kubectl create -f pvc-pv-pod-nfs.yaml
[root@k8s-master~]#ku get pod
NAME READY STATUS RESTARTS AGE
pvc-nfs 1/1 Running 0 4s

测试挂载情况:

[root@k8s-master~]#ku exec -it pvc-nfs -- bash 
root@pvc-nfs:/#ls /usr/share/nginx/html/ 
index.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88374.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88374.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/88374.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10.Docker安装mysql

(1)docker pull mysql:版本号eg&#xff1a;docker pull mysql(默认安装最新版本)docker pull mysql:5.7(2)启动并设置mysql镜像docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 --name mysql1 mysql其他参数都不多讲&#xff0c;下面这个参数指的是设置数据库用户ro…

Debian-10编译安装Mysql-5.7.44 笔记250706

Debian-10编译安装Mysql-5.7.44 笔记250706 单一脚本安装 ### 1. 安装编译依赖 sudo apt install -y cmake gcc g build-essential libncurses5-dev libssl-dev \ pkg-config libreadline-dev zlib1g-dev bison curl wget libaio-dev \ libjson-perl libnuma-dev libsystemd-d…

HarmonyOS 中状态管理 V2和 V1 的区别

鸿蒙ArkUI框架中的ComponentV2与V1在状态管理、组件开发模式、性能优化等方面存在显著差异。以下是两者的核心区别及技术解析&#xff1a;一、状态管理机制V1的局限性V1的Observed装饰器只能观察对象的第一层属性变化&#xff0c;需配合ObjectLink手动拆解嵌套对象。例如&#…

centos7 安装jenkins

文章目录前言一、pandas是什么&#xff1f;二、安装依赖环境1.前提准备2.安装git3.安装jdk&#xff0c;以及jdk版本选择4.安装maven5.安装NodeJS6.验证三、安装Jenkins四、验证Jenkins总结前言 正在学习jenkinsdocker部署前后端分离项目&#xff0c;安装jenkins的时候遇到了一…

Leetcode刷题营第二十题:删除链表中的重复节点

面试题 02.01. 移除重复节点 编写代码&#xff0c;移除未排序链表中的重复节点。保留最开始出现的节点。 示例1&#xff1a; 输入&#xff1a;[1, 2, 3, 3, 2, 1]输出&#xff1a;[1, 2, 3]示例2&#xff1a; 输入&#xff1a;[1, 1, 1, 1, 2]输出&#xff1a;[1, 2]提示&…

关于市场主流自动化测试工具和框架的简要介绍

下面我会分别讲解 Selenium、Appium、Playwright 等主流自动化框架的区别、联系、适用场景和归属范畴&#xff0c;帮助你更系统地理解它们。&#x1f527; 一、它们都属于哪一类工具&#xff1f;Selenium、Appium、Playwright、Cypress 等都属于&#xff1a;▶️ 自动化测试框架…

基于cornerstone3D的dicom影像浏览器 第三十二章 文件夹做pacs服务端,fake-pacs-server

文章目录 前言一、实现思路二、项目与代码三、dicom浏览器调用1. view2d.vue前言 本系列最后一章,提供一个模拟pacs服务,供访问dicom图像测试。 修改nodejs本地目录做为http服务根目录,提供一个根目录,其中的每个子目录代表一个检查。在dicom浏览器url中带入参数studyId=目…

【Python 核心概念】深入理解可变与不可变类型

文章目录一、故事从变量赋值说起二、不可变类型 (Immutable Types)三、可变类型 (Mutable Types)四、一个常见的陷阱&#xff1a;当元组遇到列表五、为什么这个区别如此重要&#xff1f;1. 函数参数的传递2. 字典的键 (Dictionary Keys)3. 函数的默认参数陷阱六、进阶话题与扩展…

wpf使用webview2显示网页内容(最低兼容.net framework4.5.2)

wpf使用webview2显示网页内容(最低兼容.net framework4.5.2 一、核心功能与架构混合开发支持‌进程隔离模型‌通信机制‌二、核心优势性能与兼容性‌跨平台部署‌开发效率‌安全机制‌三、适用场景四、开发部署要点WebView2 是微软推出的现代浏览器控件,基于 Chromium 内核的 …

MySQL断开连接后无法正常启动解决记录

问题现象 夜里23点MySQL在还原备份的时候断开连接&#xff0c;尝试重启&#xff0c;表面上是运行中实际上无法通过命令端连接&#xff0c;无法正常启动。 问题检查 可以使用 systemctl start mysql 但是没有监听 3306端口 mysql -ucosmic -p 提示无法找到socket文件 删除原先的…

隧道安全监测系统的应用意义

随着我国交通基础设施建设的快速发展&#xff0c;公路、铁路及城市地铁隧道数量不断增加&#xff0c;隧道安全问题日益凸显。隧道作为地下封闭空间&#xff0c;受地质条件、施工质量、运营环境等多因素影响&#xff0c;易出现结构变形、渗漏水、衬砌开裂等安全隐患。一旦发生事…

前端UI逻辑复杂可以用什么设计模式

中介者模式 当UI组件间存在复杂交互或多个组件需共享状态时&#xff0c;中介者模式能集中管理事件分发和状态更新&#xff0c;减少组件间的直接依赖&#xff0c;提升解耦性。 vue实现中介者模式 在Vue中实现中介者模式&#xff0c;你可以通过创建一个全局的事件中心&#xff08…

WIFI协议全解析05:WiFi的安全机制:IoT设备如何实现安全连接?

&#x1f510; WiFi的安全机制&#xff1a;IoT设备如何实现安全连接&#xff1f;“我的设备明明连上WiFi了&#xff0c;为什么还是能被‘蹭网’&#xff1f;” “WPA3 是什么&#xff1f;ESP32 支持吗&#xff1f;” “我做了MQTT加密就算安全了吗&#xff1f;”IoT设备连接WiF…

HTTP 请求体类型详解:选择最适合的数据提交格式

HTTP 请求体类型详解&#xff1a;选择最适合的数据提交格式 &#x1f680; 本文全面解析 HTTP 请求中不同 Content-Type 的适用场景、数据结构与优劣势&#xff0c;帮助开发者高效选择数据传输方案。 &#x1f4cc; 目录 核心请求体类型对比详细类型解析最佳实践指南总结 &am…

C语言 | 函数核心机制深度解构:从底层架构到工程化实践

个人主页-爱因斯晨 文章专栏-C语言 引言 最近偷懒了&#xff0c;迷上了三国和李贺。给大家分享一下最喜欢的一句诗&#xff1a;吾不识青天高黄地厚&#xff0c;唯见月寒日暖来煎人寿。我还不是很理解27岁的李贺&#xff0c;如何写出如此绝笔。 正文开始&#xff0c;今天我们…

uniapp真机调试“没有检测到设备,请插入设备或启动模拟器后点击刷新再试”

当真机调试&#xff0c;运行到安卓 APP基座 时&#xff0c;有时会检测不到设备&#xff0c;显示下面的问题&#xff1a;此时&#xff0c;可以通过下面的几种方法进行排查&#xff1a;1.在手机中找到“开发者选项”选项&#xff08;可在设置中搜索&#xff0c;如搜索不到&#x…

使用langchain连接llama.cpp部署的本地deepseek大模型开发简单的LLM应用

langchain是一个基于python实现的开源LLM开发框架&#xff0c;llama.cpp是一个基于C框架可以在本地部署大模型并开放服务端接口开放给外部应用使用。 本文结合langchain和llama.cpp&#xff0c;在本地部署轻量级的deepseek大模型&#xff0c;并构建一个简单的链式LLM应用&…

Serverless 数据库来了?无服务器数据库 vs 传统数据库有何不同?

随着云计算技术的迅猛发展&#xff0c;无服务器&#xff08;Serverless&#xff09;架构逐渐成为一种主流趋势。其中&#xff0c;Serverless 数据库作为云原生应用的重要组成部分&#xff0c;为开发者提供了前所未有的灵活性和成本效益。相比传统的数据库管理方式&#xff0c;S…

【读书笔记】如何画好架构图:架构思维的三大底层逻辑

【读书笔记】如何画好架构图&#xff1a;架构思维的三大底层逻辑 架构图并非技术人的“画功比拼”&#xff0c;而是一个团队、一个系统、一次项目从混沌走向清晰的关键抓手。它是系统的视觉语言&#xff0c;是让技术人员、产品经理、运营甚至老板都能站在统一上下文下讨论的“…

Maven 编译过程中发生了 Java Heap Space 内存溢出(OutOfMemoryError)

这个是我最近遇到的&#xff0c;因为本人最近换了电脑&#xff0c;这个电脑的前任是配置好了环境&#xff0c;但是当我用这个环境去做另外一个项目的时候&#xff0c;在maven构建war和jar包的时候&#xff0c;报了这个内存溢出mvn clean install 就给我报错了[ERROR] Failed to…