zoukankan      html  css  js  c++  java
  • k8s的pv和pvc概念

    存储卷

      同一个pod内的所有容器共享存储 网络 用户等空间     pod内的容器都是以pause镜像为基础镜像来运行的
       k8s.gcr.io/pause 3.1 da86e6ba6ca1 17 mon 742 kB

    emptyDir
         临时存储目录 pod删除 存储卷也随即会被删除

    hostPath 主机目录
         pod所在主机上的目录

    搭建NFS网络存储

    nfs搭建
       yum install nfs-utils
       mkdir -pv /data/volumes
       vi /etc/exports
         /data/volumes 192.168.11.0/16(rw,no_root_squash)
       systemctl start nfs
      1.确保k8s集群中的所有节点都能驱动nfs 
        yum install nfs-utils
      2.[root@node2 ~]# mount -t nfs 192.168.11.157:/data/volumnes/ /mnt
    mount.nfs: access denied by server while mounting 192.168.11.157:/data/volumnes/
      3.在nfs服务器查看/var/log/messages查看 volumnes单词拼写错误
    
      [root@node2 ~]# mount -t nfs 192.168.11.157:/data/volumes  /mnt
    
      [root@localhost ~]# vi /etc/exports
       /data/volumes/ 192.168.11.0/16(insecure,rw,async,no_root_squash)
    
      [root@localhost ~]# exportfs -r
      exportfs: Invalid prefix `24*' for 192.168.11.0/24*
      [root@localhost ~]# showmount -e
      Export list for localhost.localdomain:
      /data/volumes 192.168.11.0/16
    nfs搭建
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-vol-hostpath
      namespace: default
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: html
        hostPath:
          path: /data/pod/volume1
          type: DirectoryOrCreate
    hostpath.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: 192.168.11.157
    nfs.yaml

      nfs远程文件存储并没有一个“存储设备”需要挂载在宿主机上 所以不需要attach阶段

      直接将远端 NFS 服务器的目录(比如:“/”目录)挂载到Volume的宿主机目录上即可 

      mount -t nfs <NFS服务器地址>:/ /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字> 

      通过挂载操作,Volume的宿主机目录就成为了一个远程NFS目录的挂载点,后面你在这个目录里写入的所有文件,都会被保存在远程NFS服务器

      所以,我们也就完成了对这个Volume宿主机目录的“持久化”

    pv和pvc的使用

           存储工程师把分布式存储系统上的总空间划分成一个一个小的存储块

           k8s管理员根据存储块创建与之一一对应的pv资源

           pv属于集群级别资源  不属于任何名称空间 定义的时候不能指定名称空间

           用户在创建pod的时候同时创建与pv一一对应的pvc资源

           创建Pod的时候,系统里并没有合适的PV跟它定义的PVC绑定 也就是说此时容器想要使用的Volume不存在.这时候Pod的启动就会报错

    [root@localhost volumes]# mkdir v{1,2,3,4,5}
    [root@localhost volumes]# ls
    index.html  v1  v2  v3  v4  v5
    [root@localhost volumes]# vi /etc/exports
    
    /data/volumes/v1 192.168.11.0/16(insecure,rw,async,no_root_squash)
    /data/volumes/v2 192.168.11.0/16(insecure,rw,async,no_root_squash)
    /data/volumes/v3 192.168.11.0/16(insecure,rw,async,no_root_squash)
    /data/volumes/v4 192.168.11.0/16(insecure,rw,async,no_root_squash)
    /data/volumes/v5 192.168.11.0/16(insecure,rw,async,no_root_squash)
    
    
    [root@localhost volumes]# exportfs -r
    [root@localhost volumes]# showmount -e
    Export list for localhost.localdomain:
    /data/volumes/v5 192.168.11.0/16
    /data/volumes/v4 192.168.11.0/16
    /data/volumes/v3 192.168.11.0/16
    /data/volumes/v2 192.168.11.0/16
    /data/volumes/v1 192.168.11.0/16
    创建小的存储块
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv001
      labels:
        name: pv001
    spec:
      nfs:
       path: /data/volumes/v1
       server: 192.168.11.158
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity:
        storage: 2Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv002
      labels:
        name: pv002
    spec:
      nfs:
       path: /data/volumes/v2
       server: 192.168.11.158
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv003
      labels:
        name: pv003
    spec:
      nfs:
       path: /data/volumes/v3
       server: 192.168.11.158
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity:
        storage: 2Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv004
      labels:
        name: pv004
    spec:
      nfs:
       path: /data/volumes/v4
       server: 192.168.11.158
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity:
        storage: 2Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv005
      labels:
        name: pv005
    spec:
      nfs:
       path: /data/volumes/v5
       server: 192.168.11.158
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity:
        storage: 2Gi
    创建pv资源
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mypvc
      namespace: default
    spec:
      accessModes: ["ReadWriteMany"]
      resources:
        requests:
          storage: 4Gi
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-vol-pvc
      namespace: default
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: mypvc
    创建pod和pvc资源
    [root@k8s-master ~]# kubectl get pv
    NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
    pv001     2Gi        RWO,RWX        Retain           Available                                            8m
    pv002     5Gi        RWO,RWX        Retain           Bound       default/mypvc                            8m
    pv003     2Gi        RWO,RWX        Retain           Available                                            8m
    pv004     2Gi        RWO,RWX        Retain           Available                                            8m
    pv005     2Gi        RWO,RWX        Retain           Available                                            8m
    
    
    [root@k8s-master ~]# kubectl get pvc
    NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    mypvc     Bound     pv002     5Gi        RWO,RWX                       8m
    
    
    [root@k8s-master ~]# kubectl get pods
    NAME                             READY     STATUS    RESTARTS   AGE
    myapp-deploy-67f6f6b4dc-2986w    1/1       Running   0          4h
    myapp-deploy-67f6f6b4dc-czvq4    1/1       Running   0          4h
    myapp-deploy-67f6f6b4dc-tpggj    1/1       Running   0          10d
    pod-vol-pvc                      1/1       Running   0          9m
    tomcat-deploy-588c79d48d-mdgml   1/1       Running   0          10d
    tomcat-deploy-588c79d48d-mvttj   1/1       Running   0          4h
    tomcat-deploy-588c79d48d-w2mxb   1/1       Running   0          10d
    
    
    在创建pvc的时候如果后端没有合适的pv 那么挂载此pvc的pod将会一致处于等待状态直到pvc匹配到一个符合条件的pv
    演示结果

    pv和pvc的机制

    pv和pvc绑定要求
         1.PV和PVC的spec字段.比如PV的存储(storage)大小
         2.PV和PVC的storageClassName字段必须一样

         3. PV描述的是持久化存储卷 这个API对象主要定义的是一个持久化存储在宿主机上的目录,如一个NFS的挂载目录

             PVC可以理解为持久化存储的 它提供了对某种持久化存储的描述,但不提供具体的实现

         4. 持久化存储的实现部分则由PV负责完成

         5.PV与PVC进行绑定,其实就是将这个PV对象的名字,填在了PVC对象的spec.volumeName字段上

           当PV和PVC成功绑定后 Pod就能像使用hostPath等常规类型的Volume一样 在YAML文件中使用PVC

         pv对象转换成持久化volume的原理

              所谓容器的Volume,其实就是将一个宿主机上的目录跟一个容器里的目录绑定挂载在了一起

    持久化宿主机目录

           远程存储服务,比如:远程文件存储(比如,NFS、GlusterFS),远程块存储(比如,公有云提供的远程磁盘)

          “持久化”宿主机目录的过程,我们可以形象地称为“两阶段处理”

           先把远程存储设备附加到指定节点上  然后在节点上格式化存储设备再挂载到节点上的具体目录下  这样才能通过节点目录访问远程存储设备

         Attach阶段
             为虚拟机挂载远程磁盘的操作
             当一个Pod调度到一个节点上之后,kubelet就要负责为这个Pod创建它的 Volume 目录.默认情况下,kubelet为Volume创建的目录是一个宿主机上的路径如
             /var/lib/kubelet/pods/volumes/kubernetes.io~/   这个目录是宿主机后面用来和远程存储服务mount的关联目录

             Kubernetes提供的可用参数是nodeName,即宿主机的名字

        Mount阶段
           将磁盘设备格式化并挂载到Volume宿主机目录的操作
           把格式化的磁盘mount到/var/lib/kubelet/pods/volumes/kubernetes.io~/

           Kubernetes提供的可用参数是dir   即Volume的宿主机目录

        经过了“两阶段处理” 我们就得到了一个“持久化”的 Volume 宿主机目录 但是还没有关联到docker容器

        接下来 kubelet 只要把这个 Volume目录通过 CRI 里的 Mounts 参数,传递给 Docker 然后就可以为 Pod 里的容器挂载这个“持久化”的 Volume 

       docker run -v /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>:/<容器内的目标目录> 我的镜像 

       上面是Kubernetes 处理 PV 的具体原理

    StorageClass自动创建pv 

          Kubernetes只会将StorageClass相同的PVC和PV绑定起来

          自动创建PV的机制Dynamic Provisioning
         人工管理PV的方式就叫作Static Provisioning
         StorageClass对象就是创建PV的模板

        定义StorageClass一般包含Name,后端使用存储插件类型,存储插件需要使用到的参数等信息 定义好之后相当于定义了一块巨大的存储磁盘

        当pvc中定义的storageClassName和StorageClass的Name相同的时候那么StorageClass会自动从巨大的存储磁盘创建一个指定storage大小的pv,创建的pv和pvc进行绑定

     StorageClass对象会定义如下两个部分内容
        第一   PV的属性.  比如,存储类型
        第二   创建这种PV需要用到的存储插件.   比如Ceph等等

        k8s根据用户提交的PVC中指定的storageClassName的属性值找到对应的StorageClass.然后调用该StorageClass声明的存储插件创建出需要的PV

       有了Dynamic Provisioning机制,运维人员只需要在Kubernetes集群里创建出数量有限的StorageClass对象就可以了

       当开发人员提交了包含StorageClass字段的PVC之后,Kubernetes就会根据这个StorageClass创建出对应的PV

       在没有StorageClass的情况下运维人员对开发人员定义的每一个pvc都要手动创建一个对应的pv与其进行绑定 这样就会大大的增加创建pv的工作量

  • 相关阅读:
    win7下cygwin命令行颜色和中文乱码解决
    maven mirror
    maven命令
    dubbo获取错误ip
    eclipse netbeans 代码模板
    windows下配置Groovy
    c++ 载入内存中dll ,以及内存注入
    表达式求值的 计算器
    vc 编译器的一些精典报错
    内联汇编实现 memcpy 和 memset
  • 原文地址:https://www.cnblogs.com/yxh168/p/11031003.html
Copyright © 2011-2022 走看看