小阿轩yx-Kubernetes存储入门

news2024/9/26 3:30:42

小阿轩yx-Kubernetes存储入门

前言

  • 数据是一个企业的发展核心,它涉及到数据存储和数据交换的内容。
  • 在生产环境中尤为重要的一部分在 Kubernetes 中另一个重要的概念就是数据持久化 Volume。

Volume 的概念

对多数项目而言

  • 数据文件的存储是非常常见的

在 Kubernetes 中

  • 由于应用的部署具有高度的可扩展性和编排能力(不像传统架构部署在固定的位置),数据存放在容器中是非常不可取的,也无法保障数据的安全。

应该把有状态的应用变成无状态应用,把产生的数据文件或者宦岑信息放在云端

传统的架构中

  • 使用这些存储,需要提前在宿主机挂载,然后程序才能访问,在实际使用时经常碰到新加节点忘记挂载存储导致的一系列问题。

Kubernetes

  • 设计之初就考虑了这些问题,并抽象出 Volume 的概念用于解决数据存储的问题。
  • 卷有明确的声明周期,与使用它的 Pod 相同,因此可以比 Pod 中运行的任何容器的生命周期都长
  • 并且可以在容器重启或者销毁后保留数据
  • 支持多种类型的卷,并且 Pod 可以同时使用任意数量的卷

容器中

  • 磁盘文件是短暂的,当容器崩溃时,Kubectl 会重新启动容器,但是容器运行时产生的数据文件都会丢失,之后容器会以干净的状态启动。

一个 Pod 运行多个容器

  • 各个容器可能需要共享一些文件,诸如此类的需求都可以使用 Volume 解决。

Docker 也有卷的概念

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

本质上

  • 和虚拟机或物理机一样
  • 卷被挂载后,在容器中只是一个目录,可能包含一些数据,Pod 中的容器也可以对其进行增删改查操作,使用方式和裸机挂载几乎没有区别

Volume 的类型

传统架构中

  • 企业有自己的存储平台(如:NFS、Ceph、GlusterFS、Minio)
  • 如果所在环境在公有云,也可以使用公有云提供的 NAS、对象存储等

Kubernetes 中

  • Volume 也支持配置存储
  • 用于挂载到 Pod 中实现数据持久化

Kubernetes Volume 支持的卷类型有很多

常见的卷

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

也支持一些 Kubernetes 独有的类型

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

将 images 镜像通过 Xftp 上传至master、node01、node02(101、102、103)

将资源清单单独上传至 master 主节点(101)

三台主机导入镜像(master、node01、node02)

主机一

[root@k8s-master ~]# cd images/
[root@k8s-master images]# bash imp_docker_img

主机二

[root@k8s-node01 ~]# cd images/
[root@k8s-node01 images ~]# bash imp_docker_img

主机三

[root@k8s-node02 ~]# cd images/
[root@k8s-node02 images ~]# bash imp_docker_img

通过 emptyDir共享数据

emptyir

  • 一个特殊的 Volume 类型

与 Volume 不同之处

  • 如果删除 Pod,EmptyDir 卷中的数据也将被删除,所以一般 emptyDir 用于 Pod 中不同容器共享数据
  • 使用 emptyDir 卷时,直接指定 emptyDir 为{}即可

编写 emptyDir 的 Deployment 文件

[root@k8s-master ~]# cat nginx-empty.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels :
    app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx01
        volumeMounts:
        - mountPath: /opt
          name:share-volume
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx02
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
      volumes :
      - name: share-volume
        emptyDir: {}
          #medium: Memory

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

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

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

默认情况下

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

创建该 Deployment

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

获取创建结果

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

登录 Pod 中第一个容器

[root@k8s-master ~]# kubectl exec -it nginx-6fffbd7c7b-jrw7f -c nginx01 -- sh
  • 该容器中的/opt 下创建一个文件,并到第二个容器中查看,是否是共享的目录

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

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

删除此 Pod

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

使用 HostPath 挂载宿主机文件

  • HostPath 卷可以将节点上的文件或目录挂载到 Pod 上,用于实现 Pod 和宿主机之间的数据共享

编写 Deployment 文件实现 HostPath 挂载

  • 实现将主机的/etc/localtime 文件挂载到 Pod 的 /etc/localtime
[root@k8s-master ~]# cat nginx-hostPath.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels :
    app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /etc/localtime
          name: timezone-time
      volumes:
      - name: timezone-time
        hostPath:
          path: /etc/localtime
          type: File

关于时区的设置

通过配置 /etc/localtime 文件设置系统的时区

/etc/localtime用于配置系统时区(此文件是一个链接文件,链接自 /usr/share/zoneinfo/Asia/Shanghai)

创建此 Pod

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

查看创建结果

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

测试挂载情况

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

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

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

删除

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

挂载 NFS 至容器

安装 NFS

这一步开启会话同步

三台节点都安装 nfs-utils

主节点(master)

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

 从节点(node01)

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

从节点(node02) 

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

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

[root@k8s-master ~]# mkdir /opt/wwwroot

回显一个页面文件

[root@k8s-master ~]# echo "This is my test file">/opt/wwwroot/index.html

编写 exports 配置文件

[root@k8s-master ~]# vim /etc/exports
/opt/wwwroot 192.168.10.0/24(rw,sync,no_root_squash)

开启 nfs(在 NFS 服务器上)

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

编写 Deployment 文件挂载 NFS

[root@k8s-master ~]# cat nginx-nfsVolume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels :
    app: nginx
  name: nginX
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app:nginx
  template:
    metadata:
      labels :
        app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: nfs-volume
      volumes:
      - name: nfs-volume
        nfs:
          server: 192.168.10.101
          path: /opt/wwwroot

创建此 Pod

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

查看部署结果

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

登录容器查看挂载结果

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

PersistenVolume(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

  • 无需提前创建。

PV 回收策略

  • 用户使用完卷时,可以从 API 中删除 PVC对象,从而允许回收资源。
  • 回收策略会告诉 PV 如何处理改卷。

目前回收策略可以设置为

  • Retain
  • Recycle
  • Delete

默认的为 delete

Retain

  • 保留
  • 该策略允许手动回收资源,当删除 PVC 时,PV 仍然存在,PV 中的数据也存在。
  • volume 被视为已释放,管理员可以手动回收卷。

Recycle

  • 回收
  • 如果 volume 插件支持,Recycle 策略会对卷执行 rm -rf 清理该 PV,卷中的数据已经没了,但卷还在,使其可用于下一个新的 PVC,但是本策略将会被弃用
  • 目前只有 NFSHostPath 支持该策略。

Delete

  • 删除
  • 如果 volume 插件支持,删除 PVC 时会同时删除 PV,PV 中的数据自然也就没了。
  • 动态卷默认为 Delete

目前支持 Delete 的存储后端包括

  • AWS EBS
  • GCE PD
  • Azure Disk
  • openstackCinder

PV 访问策略

  • 实际使用 PV 时,可能针对不同的应用会有不同的访问策略

目前支持的访问策略

  1. Readwrite0nce:单路可读可写,可以被单节点以读写模式挂载,命令行中可以被缩写橙 RWO。
  2. ReadonlyMany:多路只读,可以被多节点以只读模式挂载,命令行中可以被缩写为 ROX。
  3. ReadwriteMany:多路可读可写,可以被多个节点以读写模式挂载,命令行中可以被缩写为 RWX。
  4. ReadwriteoncePod:单节点只读(1.22+),只能被一个 Pod 以读写的模式挂载,命令行中可以被
  5. 缩写为 RWOP。
  • Readwriteonce:表示具有读写权限,但是只能被一个 node 挂载一次
  • ReadonlyMany:表示具有只读权限,可以被多个 node 多次挂载
  • ReadWriteMany:表示具有读写权限,可以被多个 node 多次挂载
  • ReadwriteoncePod:表示具有读写权限,只能被一个Pod 挂载

虽然 PV 在创建时可以指定不同的访问策略,但是也要后端的存储支持才行。

一般情况下,大部分块存储是不支持 ReadwriteMany 的。

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

PV 的配置方式

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

基于 HostPath 的 PV

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

在所有 node 节点上创建主机目录

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

编辑 hostpath 的 yaml 文件

[root@k8s-master ~]# cat hostpath-pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
  name: mypv-hostpath
  labels :
    type: local
spec:
  storageclassName: pv-hostpath
  capacity:
    storage:10Gi
  accessModes:
    - ReadWriteonce
  hostPath:
  path: "/mnt/data"
  • hostPath:宿主机的路径
  • 使用 hostPath 类型需要固定 Pod 所在的节点,防止 Pod 漂移造成数据丢失。

创建 hostPath-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

基于 NFS 的 PV

提前安装好 nfs 服务
  • 可以使用上一个案例中安装好的 NFS
  • 或重新安装一台

步骤

  • 提前安装好 nfs 服务,192.168.10.101 是 nfs 服务器,也可以是任意一台提供了 NFS 服务的主机。
  • 客户端需要在所有的 Kubernetes 节点安装
[root@k8s-master ~]# yum -y install nfs-utils

创建存储目录

[root@k8s-master ~]# mkdir /opt/wwwroot

回显一个页面文件

[root@k8s-master ~]# echo "This is my test file">/opt/wwwroot/index.html

编辑一个 exports 配置文件

[root@k8s-master ~]# vim /etc/exports
/opt/wwwroot 192.168.10..0/24(rw,sync,no_root_squash)

启动服务

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

创建一个基于 NFS 的 PV

  • PV 目前没有 NameSpace 隔离,不需要指定命名空间,在任意命名空间下创建的 PV 均可以在其它 NameSpace 使用

编辑 nfs-pv 配置文件

[root@k8s-master ~]# cat nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv-nfs
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy:Recycle
  storageClassName: pv-nfs
  mountOptions:
    - hard
    - nfsvers=4.1
nfs:
  path: /opt/wwwroot/
  server: 192.168.10.101
  1. capacity:容量配置
  2. volumeMode:卷的模式,目前支持 Filesystem (文件系统)和 Block(块),其中 Block 类型需要后端存储支持,默认为文件系统。
  3. accessModes:该 PV 的访问模式
  4. storageclassName:PV 的类,一个特定类型的 PV 只能绑定到特定类别的 PVC。
  5. persistentVolumeReclaimPolicy:回收策略
  6. mountoption:非必要,新版本中已经弃用

nfs:NFS 服务配置,包括以下两个选项

  • path:NFs 上的共享目录
  • server:NFs的IP地址

创建 PV

root@k8s-master ~]# kubectl create -f nfs-pv.yaml

查看 PV 创建结果

[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-hostpath    5Gi       RWO            Retain            Available    pv-hostpath                    4s

PersistenVolumeClaim(PVC,持久卷声明)

当 kubernetes 管理员提前创建好了 PV,我们又应该如何使用它呢?

kubernetes 另一个概念

  • PersistentVolumeclaim(简称PVC)。

PVC

  • 是其他技术人员在 kubernetes 上对存储的申请,他可以标明一个程序需要用到什么样的后端存储、多大的空间以及什么访问模式进行挂载。

这一点和 Pod 的 Qos 配置类似

  • Pod 消耗节点资源
  • PVC 消耗 PV 资源
  • Pod 可以请求特定级别的资源(CPU和内存)
  • PVC 可以请求特定的大小和访问模式的 PV

实际使用时,虽然用户通过 PVC 获取存储支持,但是用户可能需要具有不同性质的 PV 来解决不同的问题

集群管理员需要根据不同的存储后端来提供各种 PV,而不仅仅是大小和访问模式的区别,并且无须让用户了解这些卷的具体实现方式和存储类型,打扫了存储的解耦,降低了存储使用的复杂度。

PVC和 PV 进行绑定的前提条件是一些参数必须匹配

  • 比如 accessModes、storageclassName、volumeMode 都需要相同,并且 PVC 的 storage 需要小于等于 PV 的 storage 配置。

PVC 的创建

为 hostpath 类型的 PV 创建 PVC

[root@k8s-master ~]# vim pvc-hostpath.yaml
kind: PersistentVolumeclaim
apiVersion: v1
metadata:
  name: mypvc-hostpath
spec:
  storageClassName: pv-hostpath
  accessModes :
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
  • storageclassName:存储类名称需要和对应的 PV 中的名称一致,PV 和 PVC 进行绑定并非是名字相同,而是 StorageclassName 相同且其他参数一致才可以进行绑定

创建 pvc-hostpath 配置文件

[root@k8s-master ~]# kubectl create -f pvc-hostpath.yaml

获取文件信息

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

为 NFS 类型的 PV 创建 PVC

[root@k8s-master ~]# cat pvc-nfs.yaml
kind: PersistenVolumeClaim
apiVersion: v1
metadata:
  name: mypvc-nfs
spec:
  storageClassName:pv-nfs
  accessModes:
    - ReadWriteonce
  resources:
    requests:
      storage: 3Gi
  • storageclassName:存储类名称需要和对应的 PV 中的名称一致

创建 pvc-nfs 文件

[root@k8s-master ~]# kubectl create -f pvc-nfs.yaml

获取状态

[root@k8s-master ~]# kubectl get pv
NAME             STATUS    VOLUME           CAPACITY   ACCESS MODES    STORAGECLASS   AGE
mypv-hostpath    Bound     mypv-hostpath    10Gi       RWO             pv-hostpath    3m12s
mypv-nfs         Bound     mypv-nfs         5Gi        RWO             pv-nfs         5s
  • PVC的定义和后端存储并没有关系。
  • 对于有存储需求的技术人员,直接定义 PVC 即可绑定一块 PV,之后就可以供 Pod使用,而不用去关心具体的实现细节,大大降低了存储的复杂度

PVC 的使用

  • 和之前的挂载方式类似
  • PVC 的挂载也是通过 volumes 字段进行配置的,只不过之前需要根据不同的存储后端填写很多复杂的参数’而使用 PVC 进行挂载时,只填写 PVC 的名字即可,不需要再关心任何的存储细节,这样即使不是 Kubemetes 管理员,不懂存储的其他技术人员想要使用存储,也可以非常简单地进行配置和使用。

创建 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-storage
      persistentVolumeclaim:
        claimName:mypvc-hostpath
    containers:
      - name: task-pv-container
        image: nginx:1.7.9
        ports:
          - containerPort: 80
            name: "http-server
        volumeMounts:
          - mountPath: "/usr/share/nginx/html
            name: task-pv-storage
  • claimName: mypvc-hostpath 是基于 hastpath 创建的 PVC 的名字

创建 pvc-pv-pod-hostpath 文件

[root@k8s-master ~]# kubectl create -f pvc-pv-pod-hostpath.yaml

获取状态

[root@k8s-master ~]# kubectl get pv
NAME             READY   STATUS    RESTARTS    AGE    IP                NODE        NOMINATED NODE    REDINESS GAMES
hostpath-pv-pod  1/1     Running    0          113s   10.244.85.204     k8s-node01    <none>            <none>

进入挂载目录(node02节点)

[root@k8s-node02 ~]# cd /mnt/data

创建一个文本

[root@k8s-node02 data]# touch aaa.txt

登录容器(master节点)

[root@k8s-master ~]# kubectl exec -it hostpath-pv-pod -- bash
root@hostpath-pv-pod:/# ls /usr/share/nginx/html
aaa.txt

创建 pod 绑定 NFS 的 PV

root@k8s-master ~]# cat pvc-pv-pod-nfs.yaml
kind: Pod
apiVersion: v1
metadata:
  name: pvc-nfs
spec:
  volumes:
    - name: pvc-nfs01
      persistentVolumeclaim:
        claimName: mypvc-nfs
  containers:
    - name: task-pv-container
      image: nginx:1.7.9
      ports:
        - containerPort: 80
          name: "http-server
      volumeMounts:
         - mountPath: "/usr/share/nginx/html
           name: pvc-nfs01
  • claimName: mypvc-nfs        是基于 NFS 创建的 PVC 的名字

创建 pvc-pv-pod-nfs 文件

root@k8s-master ~]# kubectl create -f pvc-pv-pod-nfs.yaml

获取状态

root@k8s-master ~]# kubectl get pod
NAME       READY    STATUS      RESTARTS    AGE
pvc-nfs    1/1      Running     0           4s

登录容器并查看页面文件

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

小阿轩yx-Kubernetes存储入门

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机的错误计算(七十四 )

摘要 回复网友的疑问&#xff1a;用错数解释计算机的错误计算&#xff08;六十四&#xff09;中的错误计算原因。 计算机的错误计算&#xff08;六十四&#xff09;到&#xff08;六十九&#xff09;&#xff0c;以及&#xff08;七十一&#xff09;与&#xff08;七十三&…

攻防世界 1000次点击

做题笔记。 下载解压 查壳。 32位ida打开。 查找字符串。 winmain函数写的&#xff0c;程序运行如下&#xff1a; 一开始思路是想着分析找到关键代码然后去od进行调试。 后来&#xff0c;额&#xff0c;不想看代码了。吐了。 尝试去字符串搜索flag样式&#xff0c;确实一发现…

高效恢复,无忧存储:2024年数据恢复工具大搜罗

不知道你是否了解过电子存储设备&#xff0c;我们的设备往往都存储在一个小小的芯片里&#xff0c;它为我们提供了数据携带的便捷性&#xff0c;当然也为我们带来了数据意外丢失的风险。为了我们的数据安全&#xff0c;我们来探讨一下有什么数据恢复工具能为我们的资料保驾护航…

Ruo-Yi 前后端分离如何不使用注解@DataSource的方式而是使用Mybatis插件技术实现多数据源的切换【可以根据配置文件进行开启/关闭】

Ruo-Yi 前后端分离如何不使用注解DataSource的方式而是使用Mybatis插件技术实现多数据源的切换【可以根据配置文件进行开启/关闭】 1、首先 配置文件&#xff1a; # 数据源配置 spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.c…

ZooKeeper--基于Kubernetes部署ZooKeeper

ZooKeeper 服务 服务类型: 无头服务&#xff08;clusterIP: None&#xff09;&#xff0c;这是 StatefulSet&#xff08;有状态集&#xff09;必需的配置。 端口: 2181 (客户端): 用于客户端连接。 2888 (跟随者): 用于 ZooKeeper 服务器之间的连接。 3888 (领导者): 用于领导者…

邮政快递批量查询解决方案:提升业务运营效率

邮政快递批量查询&#xff1a;固乔快递查询助手的高效体验 在电商行业日益繁荣的今天&#xff0c;快递物流成为了连接商家与消费者的关键纽带。而对于需要处理大量订单的电商企业或个人而言&#xff0c;如何高效、准确地查询和跟踪快递物流信息显得尤为重要。幸运的是&#xf…

linux 云主机下载压缩包安装配置 maven 实录(华为云 EulerOS)

本想通过 yum install maven 直接安装的, 方便省事, 但报错说没找到, 于是只能手动安装了, 把整个过程记录了一下, 包括下载, 解压, 配置及验证的全过程, 并对用到的命令及参数作了详细说明, 需要的同学可以参考. maven 官网找到下载链接 首先要去到 maven 的官网, https://m…

OpenCV+Python自动填涂机读卡

接上一篇OpenCVPython识别机读卡-CSDN博客&#xff0c;既然可以识别机读卡填涂答案了&#xff0c;将标准答案绘制到机读卡上也就简单了。 工作原理 1.答题区域为整张图片最大轮廓&#xff0c;先找出答题区域。 2.答题区域分为6行&#xff0c;每行4组&#xff0c;第6行只有1组…

【Java设计模式】抽象文档模式:以灵活性简化数据处理

文章目录 抽象文档设计模式的意图抽象文档模式的详细解释及实际示例Java中抽象文档模式的编程示例抽象文档模式类图Java中何时使用抽象文档模式抽象文档模式的优点和权衡源码下载参考和致谢 抽象文档设计模式的意图 Java中的抽象文档设计模式是一种关键的结构设计模式&#xf…

【mysql集群之组复制】

目录 一、 mysql高可用之组复制 (MGR)组复制单主和多主模式实现mysql的组复制 二、 mysql-router&#xff08;mysql路由&#xff09;实现负载均衡 一、 mysql高可用之组复制 (MGR) MySQL Group Replication(简称 MGR )是 MySQL 官方于 2016 年 12 月推出的一个全新的高可用与高…

OpenHarmony南向开发:SmartPerf-Device使用说明

简介 SmartPerf 端是一款基于 OpenHarmony 系统开发的性能功耗测试工具&#xff0c;操作简单易用&#xff0c;可提供包括性能、功耗的关键 KPI 指标&#xff0c;给出具体指标的测试值&#xff0c;包括采集设备的 FPS、CPU、GPU、Ftrace 等指标数据&#xff1b; 目前 SmartPer…

uniapp之app版本更新,整体更新和热更新

目录 需求&#xff1a; 版本更新有两种更新模式&#xff1a; 实现&#xff1a; 前提&#xff1a; 热更新&#xff1a; 打包wgt包&#xff1a;菜单->发行->原生App-制作移动App资源升级包 代码逻辑: 整体更新&#xff1a; 实际项目开发&#xff1a; 需求&#xf…

Linux网络编程——C/C++Web服务器(二):IO多路复用select/poll/epoll实现服务器监听多客户端事件

环境配置&#xff1a;windows电脑用户可以安装WSL配置Linux环境&#xff0c;并且安装vscode及wsl的插件通过vscode连接本机电脑的Linux。 前置内容&#xff1a; Linux网络编程——C/CWeb服务器&#xff08;一&#xff09;&#xff1a;不断创建新线程处理多客户端连接和通信-C…

代码随想录算法训练营第二十七天(贪心 一)

硬拖拖到现在才写完。。。 关于贪心: 文章链接: 代码随想录 文章摘要: 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 贪心算法并没有固定的套路。 和其他算法不同&#xff0c;贪心没有能看出局部最优是否能推出整体最优的通法。 用来验证可不可以…

软件渗透测试必要性简析,第三方软件测试机构如何进行渗透测试?

在信息技术迅速发展的今天&#xff0c;软件渗透测试逐渐成为了确保信息安全的重要环节。软件渗透测试指的是对系统或应用程序进行模拟攻击&#xff0c;以发现其潜在的安全风险与脆弱性。不同于传统的安全审计&#xff0c;渗透测试更注重实际攻击过程和攻击者的视角&#xff0c;…

IO进程线程8月26ri

1&#xff0c;思维导图 2&#xff0c;用两个进程分别复制文件的上下两部分到另一个文件 #include<myhead.h> int main(int argc, const char *argv[]) {int fpopen("./1.txt",O_RDONLY);if(fp-1){perror("open");return -1;}int countlseek(fp,0,SE…

如何在 mind+ 中编写 python 程序

打开Mind&#xff0c;点击窗口右上角的【Python模式】按钮&#xff0c;由实时模式切换到Python模式。 将默认的循环执行模块拖动到左边的模块区删除。 点击【变量】&#xff0c;将【打印【Hello World】】模块拼接到【Python主程序开始】下方。 将【获取输入&#xff0c;提示语…

redis(未授权访问漏洞)

环境准备 下载并安装Redis 首先&#xff0c;下载Redis的源代码包并解压&#xff1a; wget http://download.redis.io/releases/redis-2.8.17.tar.gz tar xzf redis-2.8.17.tar.gz cd redis-2.8.17接着&#xff0c;编译安装Redis&#xff1a; 编译完成后&#xff0c;进入src目录…

自动化任务工具 | zTasker v1.97.1 绿色版

在自动化任务管理领域&#xff0c;一款名为zTasker的软件以其卓越的性能和易用性脱颖而出。今天&#xff0c;电脑天空将为大家详细介绍这款软件的亮点和使用场景。 功能特点 1. 轻量级设计&#xff0c;快速启动 zTasker以其小巧的体积和快速的启动速度&#xff0c;为用户提供…

模型 7S分析法(麦肯锡)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。组织全面诊断&#xff0c;战略协同优化。 1 7S分析法(麦肯锡)的应用 1.1 邮储银行的转型&#xff1a;基于麦肯锡7S模型的竞争力提升 中国邮储银行面临着激烈的金融行业竞争&#xff0c;为了迅速提升…