精华内容
下载资源
问答
  • 2018-06-21 14:08:22

    https://blog.csdn.net/liyingke112/article/details/76851145

    https://blog.csdn.net/tiger435/article/details/54380542

    https://www.cnblogs.com/styshoo/p/6731425.html

    中文 官网:https://www.kubernetes.org.cn/pvpvcstorageclass

    https://kubernetes.io/docs/concepts/storage/persistent-volumes/#storageclasses

    实例:https://blog.csdn.net/idea77/article/details/72842723

    https://blog.csdn.net/iiiiher/article/details/77865530

    https://kubernetes.io/blog/2016/10/dynamic-provisioning-and-storage-in-kubernetes/

    本文基于kubernetes 1.5.2版本编写

    概念

    存储管理跟计算管理是两个不同的问题。理解每个存储系统是一件复杂的事情,特别是对于普通用户来说,有时并不需要关心各种存储实现,只希望能够安全可靠地存储数据。

    为了简化对存储调度,K8S对存储的供应和使用做了抽象,以API形式提供给管理员和用户使用。要完成这一任务,引入了两个新的API资源:Persistent Volume(持久卷,以下简称PV)和Persistent Volume Claim(持久卷申请,以下简称PVC)。

    PV是集群中的一块网络存储,跟Node一样,也是集群的资源。PV跟Volume(卷)类似,不过会有独立于Pod的生命周期。由系统管理员配置创建的一个数据卷(即PV类型),它代表了某一类存储插件实现。

    PVC是用户的一个请求,跟Pod类似。Pod消费Node的资源,PVC消费PV的资源。Pod 能够申请特定的资源(CPU和内存);PVC能够申请特定的尺寸和访问模式(例如可以加载一个读写,以及多个只读实例),而无须感知后端的存储实现。.

    Volume

    Volume是Pod的挂载接口,生命周期同Pod,可以在Pod内的各个Container之间进行共享,主要用于存储Pod生命周期内的临时数据,当然,也可以挂在在Host主机或者其他后端存储介质上实现永久存储,根据选用的Volume Type可以实现不同的存储需求,下边是Volume支持的类型:

    PV类型

    PV类型使用插件的形式来实现。K8S现在支持以下插件:

      GCEPersistentDisk

      AWSElasticBlockStore

      AzureFile

      AzureDisk

      FC (FibreChannel)

      Flocker

      NFS

      iSCSI

      RBD (CephBlock Device)

      CephFS

      Cinder(OpenStack block storage)

      Glusterfs

      VsphereVolume

      QuobyteVolumes

      HostPath

      VMware Photon

      PortworxVolumes

      ScaleIOVolumes

    • emptyDir
    • hostPath
    • gcePersistentDisk
    • awsElasticBlockStore
    • nfs
    • iscsi
    • flocker
    • glusterfs
    • rbd
    • cephfs
    • gitRepo
    • secret
    • persistentVolumeClaim
    • downwardAPI
    • azureFileVolume
    • azureDisk
    • vsphereVolume
    • Quobyte

    此处不作一一介绍,可以参考文档:Volume Docs


    PV、PVC生命周期

    PV是集群的资源。PVC是对这一资源的请求,也是对资源的所有权的检验。PV和PVC 之间的互动遵循如下的生命周期。

    供应

      有两种PV提供的方式:静态和动态。

    静态

      集群管理员创建多个PV,它们携带着真实存储的详细信息,这些存储对于集群用户是可用的。它们存在于Kubernetes API中,并可用于存储使用。集群管理员会创建一系列的PV。这些PV包含了为集群用户提供的真实存储资源。可利用 K8S API来消费。

    动态

      当管理员创建的静态PV都不匹配用户的PVC时,集群可能会尝试专门地供给volume给PVC。这种供给基于StorageClass:PVC必须请求这样一个等级,而管理员必须已经创建和配置过这样一个等级,以备发生这种动态供给的情况。请求等级配置为“”的PVC,有效地禁用了它自身的动态供给功能。

    绑定

    用户创建一个包含了容量和访问模式的PVC。Master会监听PVC的产生,并尝试根据请求内容查找匹配的PV,并把PV和PVC进行绑定。用户能够获取满足需要的资源,并且在使用过程中可能超出请求数量。

    如果找不到合适的卷,这一申请就会持续处于非绑定状态,一直到出现合适的PV。例如一个集群准备了很多的50G大小的持久卷,(虽然总量足够)也是无法响应100G的申请的,除非把100G的PV加入集群。

    使用

    Pod把PVC作为卷来使用。集群会通过PVC查找绑定的PV,并Mount给Pod。对于支持多种访问方式的卷,用户在使用 PVC 作为卷时,可以指定需要的访问方式。

    一旦用户拥有了一个已经绑定的PVC,被绑定的PV就归该用户所有了。用户的Pods能够通过在Pod的卷中包含的PVC来访问他们占有的PV。

    Pod使用PVC就像使用volume一样。集群检查PVC,查找绑定的PV,并映射PV给Pod。对于支持多种访问模式的PV,用户可以指定想用的模式。
      一旦用户拥有了一个PVC,并且PVC被绑定,那么只要用户还需要,PV就一直属于这个用户。用户调度Pod,通过在Pod的volume块中包含PVC来访问PV。

    释放

    当用户完成对卷的使用时,就可以利用API删除PVC对象了,而且还可以重新申请。删除PVC后,对应的卷被视为“被释放”,但这时还不能给其他的PVC使用。之前的PVC数据还保存在卷中,要根据策略来进行后续处理。

    回收

    PV的回收策略向集群阐述了在PVC释放卷时,应如何进行后续工作。目前可以采用三种策略:保留,回收或者删除。保留策略允许重新申请这一资源。在PVC能够支持的情况下,删除策略会同时删除卷以及AWS EBS/GCE PD或者Cinder卷中的存储内容。如果插件能够支持,回收策略会执行基础的擦除操作(rm -rf /thevolume/*),这一卷就能被重新申请了。

    Recycled(再利用)

      如果PV卷支持再利用,再利用会在PV卷上执行一个基础的擦除操作(rm -rf /thevolume/*),使得它可以再次被其他PVC声明利用。
      管理员可以通过Kubernetes controller manager的命令行工具(点击查看),来配置自定义的再利用Pod模板。自定义的再利用Pod模板必须包含PV卷的详细内容,如下示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pv-recycler-
      namespace: default
    spec:
      restartPolicy: Never
      volumes:
      - name: vol
        hostPath:
          path: /any/path/it/will/be/replaced
      containers:
      - name: pv-recycler
        image: "gcr.io/google_containers/busybox"
        command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/*  && test -z \"$(ls -A /scrub)\" || exit 1"]
        volumeMounts:
        - name: vol
          mountPath: /scrub

      如上,在volumes部分的指定路径,应该被替换为PV卷需要再利用的路径。

    PersistentVolume(PV)

    假如有一个独立的存储后端,底层实现可以是NFS、GlusterFS、Cinder、HostPath等等,可以使用PV从中划拨一部分资源用于kubernetes的存储需求,其生命周期不依赖于Pod,是一个独立存在的虚拟存储空间,但是不能直接被Pod的Volume挂载,此时需要用到PVC。

    PV支持的后端存储插件:

    • GCEPersistentDisk
    • AWSElasticBlockStore
    • AzureFile
    • AzureDisk
    • FC (Fibre Channel)
    • NFS
    • iSCSI
    • RBD (Ceph Block Device)
    • CephFS
    • Cinder (OpenStack block storage)
    • Glusterfs
    • VsphereVolume
    • HostPath (single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)

    PersistentVolumeClaim(PVC)

    Pod使用PV资源是通过PVC来实现的,PVC可以理解为资源使用请求,一个Pod需要先明确使用的资源大小、访问方式,创建PVC申请提交到kubernetes中的PersistentVolume Controller,由其调度合适的PV来与PVC绑定,然后Pod中的Volume就可以通过PVC来使用PV的资源。

    StorageClasse

    用于定义动态PV资源调度,相比起静态PV资源来说,动态PV不需要预先创建PV,而是通过PersistentVolume Controller动态调度,根据PVC的资源请求,寻找StorageClasse定义的符合要求的底层存储来分配资源。提供了一种方式,使得管理员能够描述他提供的存储的等级。集群管理员可以将不同的等级映射到不同的服务等级、不同的后端策略。

    请查看https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/

    创建范例

    PV

    每个PV包含一个spec,用于描述该卷的规格和状态。

    每个PV都包含一个spec和状态,即说明书和PV卷的状态。

    [plain]  view plain  copy
    1. 使用NFS或者其他插件作为存储底层,需要提前准备好NFS Server:
    2. cat << EOF > pv-lykops-sfs-0.yaml  
    3. apiVersion: v1  
    4. kind: PersistentVolume  
    5. metadata:  
    6.  name: pv-lykops-sfs-0  
    7.  labels:  
    8.    type: nfs  
    9.    app: pv  
    10.    version: v1  
    11. spec:  
    12.  capacity:  
    13.    storage: 1Gi  
    14.  accessModes:  
    15.    - ReadWriteOnc 
    16.  persistentVolumeReclaimPolicy: Recycle  
    17.   nfs:  
    18.    path: /data  
    19.    server: 192.168.20.128  
    20.    readOnly: false  
    21. EOF  
    22. kubectl create -f pv-lykops-sfs-0.yaml

    23. 定义PersistentVolume,这里使用hostPath作为存储底层。
    24. apiVersion: v1
    25. kind: PersistentVolume
    26. metadata:
    27. name: pv-lykops-sfs-0 
    28. labels:
    29. type: nfs
    30. app: pv 
    31. version: v1  
    32. spec:
    33. capacity:
    34. storage: 1Gi
    35. accessModes:
    36. - ReadWriteOnc
    37. persistentVolumeReclaimPolicy: Recycle
    38. hostPath:
    39. path: /tmp/data

    每个PV都包含一个spec和状态,即说明书和PV卷的状态。

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv0003
      spec:
        capacity:
          storage: 5Gi
        accessModes:
          - ReadWriteOnce
        persistentVolumeReclaimPolicy: Recycle
        storageClassName: slow
        nfs:
          path: /tmp
          server: 172.17.0.2


    Capacity(容量)

    一般来说,PV会指定存储容量。这里需要使用PV的capcity属性。

    用于定义PV的存储容量,当前只支持定义大小,未来会实现其他能力如:IOPS、吞吐量

    目前存储大小是唯一一个能够被申请的指标。

    Access Modes(访问模式)

    用于定义资源的访问方式,受限于存储底层的支持,访问方式包括以下几种:

    • ReadWriteOnce – 被单个节点mount为读写rw模式
    • ReadOnlyMany – 被多个节点mount为只读ro模式
    • ReadWriteMany – 被多个节点mount为读写rw模式

    下边途中列举了k8s支持的存储插件的访问方式:

    Volume PluginReadWriteOnceReadOnlyManyReadWriteMany
    AWSElasticBlockStorex
    AzureFilexxx
    CephFSxxx
    Cinderx
    FCxx
    FlexVolumexx
    GCEPersistentDiskxx
    Glusterfsxxx
    HostPathx
    iSCSIxx
    NFSxxx
    RDBxx
    VsphereVolumex

    只要资源提供者支持,持久卷能够被用任何方式加载到主机上。每种存储都会有不同的能力,每个PV的访问模式也会被设置成为该卷所支持的特定模式。例如NFS能够支持多个读写客户端,但某个NFS PV可能会在服务器上以只读方式使用。每个PV都有自己的一系列的访问模式,这些访问模式取决于PV的能力。

    访问模式的可选范围如下:

        ReadWriteOnce:该卷能够以读写模式被加载到一个节点上。

        ReadOnlyMany:该卷能够以只读模式加载到多个节点上。

        ReadWriteMany:该卷能够以读写模式被多个节点同时加载。

    在 CLI 下,访问模式缩写为:

        RWO:ReadWriteOnce

        ROX:ReadOnlyMany

        RWX:ReadWriteMany

    重要!一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。例如一个 GCEPersistentDisk既能支持ReadWriteOnce,也能支持ReadOnlyMany。

    Recycling Policy,persistentVolumeReclaimPolicy(回收策略)

    用于定义资源的回收方式,也首先与存储底层的支持,现有的回收策略:

    • Retain – 手动回收
    • Recycle – 删除数据 (“rm -rf /thevolume/*”)
    • Delete – 通过存储后端删除卷,后端存储例如AWS EBS, GCE PD或Cinder等。

    目前只有NFS和HostPath支持Recycle策略,AWS EBS、GCE PD、Azure Disk、Cinder支持Delete策略。

    注意:Recycle策略会通过运行一个busybox容器来执行数据删除命令,默认定义的busybox镜像是:gcr.io/google_containers/busybox:latest,并且imagePullPolicy: Always,如果需要调整配置,需要增加kube-controller-manager 启动参数:--pv-recycler-pod-template-filepath-hostpath=/etc/kubernetes/manifests/recycler.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pv-recycler-
      namespace: default
    spec:
      restartPolicy: Never
      volumes:
      - name: vol
        hostPath:
          path: [Path of Persistent Volume hosted]
      containers:
      - name: pv-recycler
        image: "gcr.io/google_containers/busybox"
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/*  && test -z \"$(ls -A /scrub)\" || exit 1"]
        volumeMounts:
        - name: vol
          mountPath: /scrub

    Class

      一个PV可以有一种class,通过设置storageClassName属性来选择指定的StorageClass。有指定class的PV只能绑定给请求该class的PVC。没有设置storageClassName属性的PV只能绑定给未请求class的PVC。
      过去,使用volume.beta.kubernetes.io/storage-class注解,而不是storageClassName属性。该注解现在依然可以工作,但在Kubernetes的未来版本中已经被完全弃用了。



    阶段(Phase)

    一个卷会处于如下阶段之一:

        Available:可用资源,尚未被绑定到PVC上

        Bound:该卷已经被绑定

        Released:PVC已经被删除,但该资源尚未被集群回收

        Failed:该卷的自动回收过程失败。

    CLI 会显示绑定到该 PV 的 PVC。

    映射选项

      当PV被映射到一个node上时,Kubernetes管理员可以指定额外的映射选项。可以通过使用标注volume.beta.kubernetes.io/mount-options来指定PV的映射选项。
      比如:

    apiVersion: "v1"
    kind: "PersistentVolume"
    metadata:
      name: gce-disk-1
      annotations:
        volume.beta.kubernetes.io/mount-options: "discard"
    spec:
      capacity:
        storage: "10Gi"
      accessModes:
        - "ReadWriteOnce"
      gcePersistentDisk:
        fsType: "ext4"
        pdName: "gce-disk-1

      映射选项是当映射PV到磁盘时,一个可以被递增地添加和使用的字符串。
      注意,并非所有的PV类型都支持映射选项。在
    Kubernetes v1.6中,以下的PV类型支持映射选项。
       ● GCEPersistentDisk
       ● AWSElasticBlockStore
       ● AzureFile
       ● AzureDisk
       ● NFS
       ● iSCSI
       ● RBD (Ceph Block Device)
       ● CephFS
       ● Cinder (OpenStack block storage)
       ● Glusterfs
       ● VsphereVolume
       ● Quobyte Volumes
       ● VMware Photon


    创建PersistentVolumeClaim

    每个PVC都包含一个 spec status ,即该PVC的规则说明和状态。

    [plain]  view plain  copy
    1. cat << EOF > pvc-lykops-sfs-0.yaml  
    2. apiVersion: v1  
    3. kind: PersistentVolumeClaim  
    4. metadata:  
    5.  name: pvc-lykops-sfs-0  
    6.  labels:  
    7.    type: nfs  
    8.    app: pvc  
    9.    version: v1  
    10. spec:  
    11.  accessModes:  
    12.     -ReadWriteMany  
    13.  resources:  
    14.    requests:  
    15.      storage: 1Gi
    16. EOF  
    17. kubectl create -f pvc-lykops-sfs-0.yaml  

    定义PersistentVolumeClaim

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-lykops-sfs-0
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
      selector:
        matchLabels:
          release: pv-lykops-sfs-0

     每个PVC都包含一个specstatus,即该PVC的规则说明和状态。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: myclaim
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 8Gi
      storageClassName: slow
      selector:
        matchLabels:
          release: "stable"
        matchExpressions:
          - {key: environment, operator: In, values: [dev]}

    accessModes

    与PersistentVolume的访问方式一致,PersistentVolume Controller调度访问方式一致PV资源与PVC绑定。

    resources

    用于定义申请使用的存储资源大小,适用于kubernetes的resource模型,具体信息可以查看Resource Model docs

    selector

    定义PVC申请过滤PV卷集,搭配label定义使用,同kubernetes中其他的selector概念一致,用法上稍有不同,增加了匹配选项:

    • matchLabels – 匹配标签,卷标签必须匹配某个值
    • matchExpressions – 匹配表达式,由键值对,操作符构成,操作符包括 In,NotIn,Exists,和 DoesNotExist。

    此外还有volume.beta.kubernetes.io/storage-class定义,具有相同定义的PV和PVC才会绑定,具体用法可以查看PersistentVolume docs

    等级(Class,StorageClassName)

      PVC可以使用属性storageClassName来指定StorageClass的名称,从而请求指定的等级。只有满足请求等级的PV,即那些包含了和PVC相同storageClassName的PV,才能与PVC绑定。
      PVC并非必须要请求一个等级。设置storageClassName为“”的PVC总是被理解为请求一个无等级的PV,因此它只能被绑定到无等级的PV(未设置对应的标注,或者设置为“”)。未设置storageClassName的PVC不太相同,DefaultStorageClass的权限插件打开与否,集群也会区别处理PVC。
       • 如果权限插件被打开,管理员可能会指定一个默认的StorageClass。所有没有指定StorageClassName的PVC只能被绑定到默认等级的PV。要指定默认的StorageClass,需要在StorageClass对象中将标注storageclass.kubernetes.io/is-default-class设置为“true”。如果管理员没有指定这个默认值,集群对PVC创建请求的回应就和权限插件被关闭时一样。如果指定了多个默认等级,那么权限插件禁止PVC创建请求。
       • 如果权限插件被关闭,那么久没有默认StorageClass的概念。所有没有设置StorageClassName的PVC都只能绑定到没有等级的PV。因此,没有设置StorageClassName的PVC就如同设置StorageClassName为“”的PVC一样被对待。
       根据安装方法的不同,默认的StorageClass可能会在安装过程中被插件管理默认的部署在Kubernetes集群中。
       当PVC指定selector来请求StorageClass时,
    所有请求都是操作的。只有满足了指定等级和标签的PV才可能绑定给PVC。当前,一个非空selector的PVC不能使用PV动态供给。
       过去,使用volume.beta.kubernetes.io/storage-class注解,而不是storageClassName属性。该注解现在依然可以工作,但在Kubernetes的未来版本中已经被完全弃用了。

    挂载Volume到Pod

    Pod通过使用PVC(使用方式和volume一样)来访问存储。PVC必须和使用它的pod在同一个命名空间,集群发现pod命名空间的PVC,根据PVC得到其后端的PV,然后PV被映射到host中,再提供给pod。

    PV和PVC创建并绑定之后,类似这样:

    NAME       CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM               REASON    AGE
    pv/pv001   5Gi        RWO           Recycle         Bound     default/myclaim-1             11m
    
    NAME            STATUS    VOLUME    CAPACITY   ACCESSMODES   AGE
    pvc/myclaim-1   Bound     pv001     5Gi        RWO           3s

    PersistentVolume有四种状态:

    • Available – 可用状态
    • Bound – 绑定到PVC
    • Released – PVC被删掉,但是尚未回收
    • Failed – 自动回收失败

    挂载创建好的PVC:myclaim-1到Pod上:

    kind: Pod
    apiVersion: v1
    metadata:
      name: mypod
    spec:
      containers:
        - name: myfrontend
          image: hub.c.163.com/library/nginx:latest
          volumeMounts:
          - mountPath: "/var/www/html"
            name: mypd
      volumes:
        - name: mypd
          persistentVolumeClaim:
            claimName: pvc-lykops-sfs-0
    • 命名空间注意事项

        PV绑定是独有的,因为PVC是命名空间对象,映射PVC时只能在同一个命名空间中使用多种模式(ROXRWX)。


    如果是NFS:kuberctl exec -it bash ls /var/www/html 就会有挂载的内容

    如果是HostPath Volum:挂载成功后,Pod所在的Host上会自动创建/tmp/data用于存储数据,HostPath Volume便于测试调试,但是只适用于单节点环境,多节点环境中如果Pod漂移或者重建后不在原先节点,则无法访问原来的数据。

    StatefulSet调用

    (https://blog.csdn.net/Michaelwubo/article/details/80763586)

    Pod能够借助PVC来访问存储。PVC必须跟Pod处于同一个命名空间。集群找到Pod命名空间中的PVC,然后利用PVC获取到PV。这个卷就会被加载到主机上,让Pod使用。

    [plain]  view plain  copy
    1. cat << EOF > lykops-sfs.yaml  
    2. apiVersion: apps/v1beta1   
    3. kind: StatefulSet   
    4. metadata:  
    5.   name: lykops-sfs  
    6.  labels:  
    7.    software: apache  
    8.    project: lykops  
    9.    app: lykops-sfs  
    10.    version: v1  
    11. spec:  
    12.  serviceName: lykops-sfs  
    13.  template:  
    14.    metadata:  
    15.      labels:  
    16.        software: apache  
    17.        project: lykops  
    18.        app: lykops-sfs  
    19.        version: v1  
    20.        name: test-sfs  
    21.    spec:  
    22.      containers:  
    23.      - name: lykops-sfs  
    24.        image: hub.c.163.com/library/nginx:latest 
    25.        ports:  
    26.        - containerPort: 80  
    27.          name: apache  
    28.        volumeMounts:  
    29.        - name: pvc  
    30.          mountPath: /mnt  
    31.  volumeClaimTemplates:  
    32.   -metadata:  
    33.      name: pvc  
    34.    spec:  
    35.      accessModes:  
    36.      - ReadWriteMany  
    37.      resources:  
    38.        requests:  
    39.          storage: 1Gi  
    40. EOF  
    41. kubectl create -f lykops-sfs.yaml  

    StorageClass

      每个StorageClass都包含字段provisionerparameters,在所属的PV需要动态供给时使用这些字段。
      StorageClass对象的命名是非常重要的,它是用户请求指定等级的方式。当创建StorageClass对象时,管理员设置等级的名称和其他参数,但对象不会在创建后马上就被更新。
      管理员可以指定一个默认的StorageClass,用于绑定到那些未请求指定等级的PVC。详细信息可参考PersistentVolumeClaim章节。

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: standard
    provisioner: kubernetes.io/aws-ebs
    parameters:
      type: gp2

    Provisioner

      StorageClass都有存储供应商provisioner,用来决定哪种volume插件提供给PV使用。必须制定该字段。
      你不限于指定此处列出的“内部”供应商(其名称前缀为“kubernetes.io”并与Kubernetes一起分发)。你还可以运行和指定外部供应商,它们是遵循Kubernetes定义的规范的独立程序。外部提供者的作者对代码的生命周期,供应商的分发方式,运行状况以及使用的卷插件(包括Flex)等都有充分的自主权。库kubernetes-incubator/external-storage存放了一个库, 用于编写外部存储供应商,而这些提供者实现了大量的规范,并且是各种社区维护的。

    参数

      StorageClass有一些参数用于描述归属于该StorageClass的volume。不同的存储提供商可能需要不同的参数。比如,参数type对应的值io1,还有参数iopsPerGB,都是EBS专用的参数。当参数省略时,就会使用它的默认值。

    AWS

    ...

    GCE

    ...

    Glusterfs

    ...

    OpenStack Cinder

    ...

    vSphere

    ...

    Ceph RBD

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: fast
      provisioner: kubernetes.io/rbd
      parameters:
        monitors: 10.16.153.105:6789
        adminId: kube
        adminSecretName: ceph-secret
        adminSecretNamespace: kube-system
        pool: kube
        userId: kube
        userSecretName: ceph-secret-user

      ● monitors:Ceph的monitor,逗号分隔。该参数是必须的。
      ● adminId:Ceph的客户端ID,可在pool中创建镜像。默认的是“admin”。
      ● adminSecretNamespace:adminSecret的命名空间,默认值是“default”。
      ● adminSecretNameadminId的Secret Name。改参数是必须的,提供的秘钥必须有类型“kubernetes.io/rbd”。
      ● pool:Ceph的RBD pool,默认值是“rbd”。
      ● userId:Ceph的客户ID,用于映射RBD镜像的,默认值和adminId参数相同。
      ● userSecretName:Ceph Secret的名称,userId用该参数来映射RBD镜像。它必须和PVC在相同的命名空间。该参数也是必须的。提供的秘钥必须有类型“kubernetes.io/rbd”。比如,按照下面的方式来创建:

    $ kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' --namespace=kube-system

    Quobyte

    ...

    Azure Disk

    ...

    Portworx Volume

    ...

    ScaleIO

    ...

    配置

      如果你在写配置模板和示例,用于在需要持久化存储的集群中使用,那么,我们建议你使用以下的一些模式:
       ● 在你的捆绑配置(如Deployment、ConfigMap胖)中包含PVC对象。
       ● 在配置中不要包含PersistentVolume对象,因为实例化配置的用户可能没有创建PersistentVolumes的权限
       ● 当用户提供实例化模板时,给用户提供存储类名称的选项。
        ▷ 如果用户提供了一个StorageClass名称,并且Kubernetes版本是1.4及以上,那么将该值设置在PVC的volume.beta.kubernetes.io/storage-class标注上。这会使得PVC匹配到正确的StorageClass
        ▷ 如果用户没有提供StorageClass名称,或者集群版本是1.3,那么久需要在PVC配置中设置volume.alpha.kubernetes.io/storage-class: default标注。
         ☞ 这会使得在一些默认配置健全的集群中,PV可以动态的提供给用户。
         ☞ 尽管在名称中包含了alpha单词,但是该标注对应的代码有着beta级别的支持。
         ☞ 不要使用volume.beta.kubernetes.io/storage-class,无论设置什么值,甚至是空字符串。因为它会阻止DefaultStorageClass许可控制器。
       ● 在你的工具中,要监视那些一段时间后还没有获得绑定的PVC,并且展示给用户。因为这可能表明集群没有支持动态存储(此时我们应该创建匹配的PV),或者集群没有存储系统(此时用户不能部署需要PVC的情况)。
       ● 未来,我们期望大多数集群都可以使能DefaultStorageClass,并且能有一些可用的存储形式。然而,可能没有行在所有集群都能运的StorageClass,所以默认情况下不要只设置一种。在某些时候,alpha标注将不再具有意义,但复位PVC的storageClass字段将具有所需的效果。


    PV、PVC、调用资源的创建注意事项

    使用限制

    PVC、PV不能使用在deployment、rc、rs等场景下

    命名规则

        如上面的例子:

            调用PVC的StatefulSet:StatefulSet名称为test-sfs,卷名为pvc

            PV:pv-test-sfs-{0,1}

            PVC:pvc-test-sfs-{0,1}

        规则如下:

            PVC和PV的命名规则为:资源类型-StatefulSet名称-副本数序号(从0开始)

    PV和PVC的yaml规划

        除了命名规则外,还需要保证访问accessModes、resources这两个一样

        按照以上规则创建后,可以看到PV和PVC能关联起来

     

    版权声明:本文属于原创,欢迎转载,转载请保留出处:http://blog.csdn.net/liyingke112 https://blog.csdn.net/liyingke112/article/details/76851145


    更多相关内容
  • 施耐德M258系统功能变量库指南,详细介绍此类型PLC的变量地址分配空间
  • 目录关于k8s存储类准备基础环境开始操作(nfs存储类部分)persistentVolumeReclaimPolicy: DeletepersistentVolumeReclaimPolicy: Retain存储类总结 关于k8s存储类 采用nfs类型存储类 准备基础环境 准备好现有的k8s...

    关于k8s存储类

    采用nfs类型存储类

    准备基础环境

    准备好现有的k8s环境

    创建nfs存储类

    ## 创建了一个存储类
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: nfs-storage
      annotations:
        storageclass.kubernetes.io/is-default-class: "true"
    provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
    parameters:
      archiveOnDelete: "true"  ## 删除pv的时候,pv的内容是否要备份
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nfs-client-provisioner
      labels:
        app: nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: default
    spec:
      replicas: 1
      strategy:
        type: Recreate
      selector:
        matchLabels:
          app: nfs-client-provisioner
      template:
        metadata:
          labels:
            app: nfs-client-provisioner
        spec:
          serviceAccountName: nfs-client-provisioner
          containers:
            - name: nfs-client-provisioner
              image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2
              # resources:
              #    limits:
              #      cpu: 10m
              #    requests:
              #      cpu: 10m
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  value: k8s-sigs.io/nfs-subdir-external-provisioner
                - name: NFS_SERVER
                  value: 20.88.10.31 ## 指定自己nfs服务器地址
                - name: NFS_PATH  
                  value: /nfs/data  ## nfs服务器共享的目录
          volumes:
            - name: nfs-client-root
              nfs:
                server: 20.88.10.31 ## 指定自己nfs服务器地址
                path: /nfs/data ## nfs服务器共享的目录
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: default
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: nfs-client-provisioner-runner
    rules:
      - apiGroups: [""]
        resources: ["nodes"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["persistentvolumes"]
        verbs: ["get", "list", "watch", "create", "delete"]
      - apiGroups: [""]
        resources: ["persistentvolumeclaims"]
        verbs: ["get", "list", "watch", "update"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["events"]
        verbs: ["create", "update", "patch"]
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: run-nfs-client-provisioner
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        # replace with namespace where provisioner is deployed
        namespace: default
    roleRef:
      kind: ClusterRole
      name: nfs-client-provisioner-runner
      apiGroup: rbac.authorization.k8s.io
    ---
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: leader-locking-nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: default
    rules:
      - apiGroups: [""]
        resources: ["endpoints"]
        verbs: ["get", "list", "watch", "create", "update", "patch"]
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: leader-locking-nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: default
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        # replace with namespace where provisioner is deployed
        namespace: default
    roleRef:
      kind: Role
      name: leader-locking-nfs-client-provisioner
      apiGroup: rbac.authorization.k8s.io
    

    创建服务

    # 创建一个Pod
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      namespace: default
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: nginx
        spec:
          volumes:
            - name: html
              persistentVolumeClaim:
                claimName: html
          containers:
            - name: nginx
              image: 'nginx:1.14.2'
              ports:
                - containerPort: 80
                  protocol: TCP
              volumeMounts:
                - name: html
                  mountPath: /usr/share/nginx/html
              resources: {}
              terminationMessagePath: /dev/termination-log
              terminationMessagePolicy: File
              imagePullPolicy: IfNotPresent
          restartPolicy: Always
    ---
    # 创建pv
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: html
      namespace: default
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      storageClassName: nfs-storage
      volumeMode: Filesystem
    ---
    # 创建service
    kind: Service
    apiVersion: v1
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
        - name: web
          protocol: TCP
          port: 80
          targetPort: web
      selector:
        app: nginx
      # 采用LoadBalancer类型
      type: LoadBalancer
      sessionAffinity: ClientIP
      externalTrafficPolicy: Cluster
      sessionAffinityConfig:
        clientIP:
          timeoutSeconds: 10800
    

    准备一个index.html文件

    <html>
      <head>
        <h1>hello,world!</h1>
      </head>
    </html>
    

    确保页面可以访问即可.

    开始操作(nfs存储类部分)

    persistentVolumeReclaimPolicy: Delete

    pv策略使用默认,为persistentVolumeReclaimPolicy: Delete

    先将Pod数量改为0,删除对应的PVC,然后重新使用上面的编排文件创建一个新的PVC.

    原有的数据在容器中找不到了,但是NFS中依然有存储,名称为:archived-名称空间-卷名称,里面是备份数据.同时创建了一个新的PV.
    在这里插入图片描述
    经过测试,哪怕是一个空卷被删除,该目录下同样会有备份
    在这里插入图片描述

    原来的PV在主机对应的目录同样被删除了,留下是备份,因为配置文件中开启了备份

    # 开启备份策略的参数
    parameters:
      archiveOnDelete: "true"
    

    persistentVolumeReclaimPolicy: Retain

    创建存储类文件改为

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: nfs-storage
      annotations:
        storageclass.kubernetes.io/is-default-class: "true"
    provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
    parameters:
      archiveOnDelete: "true"  ## 删除pv的时候,pv的内容是否要备份
    reclaimPolicy: Recycle ## 指定存储类默认规则
    

    删除原有的存储类,然后重新创建

    删除存储类同样没有删除主机上的文件

    将存储类改为persistentVolumeReclaimPolicy: Retain后重新创建PVC和Pod,朝目录中写入数据.

    然后删除Pod,删除PVC.这个时候看一下PV,并没有像上次之前同样被删掉,而是变成了Released状态!
    在这里插入图片描述
    同时,主机上依然存在这个对应的PVC目录
    在这里插入图片描述
    这时候我们重新创建一个PVC,依旧使用相同的配置文件
    在这里插入图片描述
    原来的PV依旧存在处于Released状态,PVC自动重新创建了一个PV不用想都知道,新建的这个里面肯定是空的.

    然后我们删除PVC,同时制定使用第一次创建出来的PV.

    # 使用指定的PV
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: html
      namespace: default
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      storageClassName: nfs-storage
      ## 制定PV的名字
      volumeName: pvc-ad855ee0-3013-47e6-bd95-bd95394db606
      volumeMode: Filesystem
    

    但是,现在创建出来的PVC一直处于pending状态,因为PV是release状态,需要手动干预将其改为Available状态

    kubectl edit pv/pvc-ad855ee0-3013-47e6-bd95-bd95394db606
    
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 1Gi
      # 删除这个标签下的所有
      claimRef:
        apiVersion: v1
        kind: PersistentVolumeClaim
        name: html
        namespace: default
        resourceVersion: "494860"
        uid: ad855ee0-3013-47e6-bd95-bd95394db606
    

    重新查看

    [root@h1 ~]# kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM          STORAGECLASS   REASON   AGE
    pvc-97b15824-54d0-4266-8bbf-094fb6a133ba   1Gi        RWX            Retain           Released    default/html   nfs-storage             38m
    pvc-ad855ee0-3013-47e6-bd95-bd95394db606   1Gi        RWX            Retain           Available                  nfs-storage             44m
    [root@h1 ~]# 
    

    PVC也绑定上了
    在这里插入图片描述
    进入Pod查看数据,数据还在.

    存储类总结

    存储类只支持两种类型,DeleteRetain.

    The StorageClass "nfs-storage" is invalid: reclaimPolicy: Unsupported value: "Recycle": supported values: "Delete", "Retain"
    

    如果在创建存储类时通过archiveOnDelete: "true"参数指定备份,那么删除PVC的时候,PV也会被删除但是主机上存储的数据不会删除,而会重命名为一个archived开头的目录.
    如果没有设置这一条,那么删除PVC的时候,数据就真的全部被删掉了.
    如果persistentVolumeReclaimPolicy设为了Retain,那么删除PVC后PV不会被删除,这个时候的PV处于Released状态,需要管理员手动干预修改配置,才能恢复到Available状态并被重新可绑定,同时,PV如果处于Released状态,那么他是不可用的.

    PV处于Released状态时,需要手动干预,才能恢复到Available状态或者被删除.

    展开全文
  • 一、global 官方解释: help global global Define global variable. global X Y Z defines X, Y, and Z as global in scope. Ordinarily, each MATLAB function has its own local variables, which are ...

    一、global

    官方解释:

     help global
     global Define global variable.
        global X Y Z defines X, Y, and Z as global in scope.
     
        Ordinarily, each MATLAB function has its
        own local variables, which are separate from those of other functions,
        and from those of the base workspace.  However, if several functions, 
        and possibly the base workspace, all declare a particular name as 
        global, then they all share a single copy of that variable.  Any 
        assignment to that variable, in any function, is available to all the 
        other functions declaring it global.
     
        If the global variable doesn't exist the first time you issue
        the global statement, it will be initialized to the empty matrix.
     
        If a variable with the same name as the global variable already exists
        in the current workspace, MATLAB issues a warning and changes the
        value of that variable to match the global.
     
        Stylistically, global variables often have long names with all
        capital letters, but this is not required.

    1、简单说:

           用matlab写代码时,如果有多个.m文件,且之间存在相互调用关系;每个.m文件中的变量,都为局部变量,都有自己的工作区域/Workspace,当函数调用结束之后,其变量的声明周期也就结束了(记住,变量的声明周期随着子函数的结束而结束);

    如果定义了全局变量/global,则需要注意几点:

    1、在每一个子函数/.m文件中,都需要先声明,然后再进行操作;

    2、global/全局变量,只占一个workspace,即在某一个地方修改,同时在变量存在的地方全部修改;

    3、定义多个global/全局变量方式为: global var1 var2 var3 ……;

    4、去掉/消除某一个或多个全局变量方式为:clear var1 var2 var3……;

    2、优缺点:

    (1) 优点

    传递大数据的参数:
          如果通过函数传参数的方式的话,系统会浪费过多的时间在复制数据的时间上,如果采用global的方式共享数据的话代码的效率会大大提高

    过多的常量需要传递
           如果每个量都作为函数函数的参数传递的话,代码参数列表就很长,如果采用global的话代码的可读性提高,函数调用也方便。

    (2) 缺点

          在多数情况下,使用全局变量不是值得推荐的做法,因为会导致模块之间存在强耦合,并且由于各模块的访问顺序问题,可能导致一些难以预料的情况。

    示例:

    function global_plot()
    global X
    X=0:0.1:2*pi;
    plot_sin(2)
    plot_cos(2)
    function plot_sin(a)
    global X
    y=a*sin(X);
    figure
    plot(X,y)
    
    function plot_cos(a)
    global X   %使用全局变量X时,也要用global定义
    X=-pi:0,1:pi; %全局变量被修改
    y=a*cos(X);
    figure
    plot(X,y)

    结果;

    二、persistent 永久变量

    1、解释: 局部静态变量

          和global变量很像,和global不同的是,persistent只被定义persistent的函数所知晓/访问,其他函数无法访问或改变它的值。当m文件被从内存中清除或m文件改变时,persistent变量才会被清除。

    如果persistent变量中第一次使用时未进行初始化赋值,则初始化为空矩阵。

    如果workspace中已经有同名变量,则声明persistent变量会出错。

     示例:

    % 脚本文件: test_runstats.m
    %
    % 程序目的:
    % 计算输入一系列数的平均值和方差,(是随时保存值的)
    %
    % 版本记录:
    % 日期                      负责人       版本描述
    % ====                     ========== =====================
    % 2015-10-9 17:43:33        王茂春         源代码
    %
    % 定义变量:
    % array --输入数组
    % ave --平均值
    % ii --循环索引
    % nvals --输入数的数量
    % std --方差
    % 首先清零初始化
    [ave std] = runstats('reset');
    % 确定输入数的数量
    nvals = input('输入这一组总数: ');
    % 获取输入值
    for ii = 1:nvals
    % 提示输入(这种方法:分成两个语句的学习下。。。)
    string = ['输入数值 ' int2str(ii) ': '];
    x = input(string);
    
    % 调用函数求解(输出变量是多个)
    [ave std] = runstats(x);
    % 显示运算结果
    fprintf('平均值 = %8.4f; 标准差 = %8.4f\n',ave, std);
    end

    子函数:

    function [ave, std] = runstats(x)
    %RUNSTATS 随时计算一组数的平均值和方差
    % 输入数x必须一次一个,当输入字符串'reset'时,持久变量清零
    
    % 定义输入输出变量
    % ave    --平均值
    % msg    --错误信息
    % n      --一组数的个数
    % std    --方差
    % sum_x  --一组数的的和
    % sum_x2 --一组数的平方和
    % x       --输入值
    % 版本记录:
    % 日期                      负责人       版本描述
    % ====                     ========== =====================
    % 2015-10-9 17:43:33        王茂春         源代码
    
    % 持久变量声明(重要)
    persistent n     % 输入数的个数
    persistent sum_x % 输入数的和
    persistent sum_x2 % 输入数的平方和
    
    % 检查输入数的合法性
    msg = nargchk(1,1,nargin); %最少1个参数,最多一个参数,检查输入变量
    error(msg);
    % 如果输入时'reset',重置
    if x == 'reset'
    n = 0;
    sum_x = 0;
    sum_x2 = 0;
    else
    n = n + 1;
    sum_x = sum_x + x;
    sum_x2 = sum_x2 + x^2;
    end
    % 计算平均值和方差
    if n == 0     %0输入
    ave = 0;
    std = 0;
    elseif n == 1  %1输入
    ave = sum_x;
    std = 0;
    else
    ave = sum_x / n;
    std = sqrt((n*sum_x2 - sum_x^2) / (n*(n - 1)));
    end

    示例:

     

    参考

    matlab 全局变量的使用举例

    Matlab中的保留字:global和persistent

    matlab 利用persistent关键字 存储持久变量

    展开全文
  • CODESYS之保持型变量常量 1:普通的变量可以在线更改其状态或数值,如下 CODESYS软件使用说明,从入门到精通
  • 【Matlab】彻底清除persistent变量

    千次阅读 2019-03-01 16:10:37
    MATLAB中persistent变量相当于C中局部静态变量,只能在所定义的函数内部访问到,并且一旦定义一直存在。 一般的解决方案 clear var 变量名 新的问题 如下图所示,本来想着将算法每次迭代的结果先暂时存放在一个...

    MATLAB中persistent变量相当于C中局部静态变量,只能在所定义的函数内部访问到,并且一旦定义一直存在。

    一般的解决方案

    clear var 变量名

    新的问题

    如下图所示,本来想着将算法每次迭代的结果先暂时存放在一个persistent变量中,最后一次运行时将数据写入到文件中。后来调试发现,即使是利用clear var命令,该变量再次被初始化的时候仍然会被初始化为上次写入的结果。  

    function [ ] = RecordResult( Global )
        %检查静态变量是否存在,若存在且是第一次运行,则清除
        if Global.evaluated <= Global.N
            clear var global_result;%第一次运行时,清除上次该函数运行留下的persistent变量
        end
        persistent global_result;
        
        %% 判断目录是否存在
    	method = func2str(Global.algorithm);
    	question = func2str(Global.problem);
        dir_1 = sprintf('Data/%s/',question);                               %问题对应的第一级目录
        dir_2 = sprintf('%s%d/',dir_1,Global.run);                       %问题对应的第二级目录,单次运行结果存放在一个文件夹里面,文件夹的名称为运行序号
        %判断路径是否存在    
        if ~exist(dir_1,'dir')
            mkdir(dir_1);
        end
        if ~exist(dir_2,'dir')
            mkdir(dir_2);
        end
        
        %% 输出运行过程中的信息
        clc;%清空命令行
        fprintf('run %d\n',Global.run);
        fprintf('%s with %s on %s\n',method,func2str(Global.operator),question);
        fprintf('N: %d     evaluation: %d\n',Global.N,Global.evaluation);
        fprintf('status: (%6.2f%%), %.2fs passed...\n',Global.evaluated/Global.evaluation*100,Global.runtime);
        
        [r,~] = size(Global.result);
       	result = {Global.result{r,:}};                                           %每个算法最后一次运行结果
        global_result = [global_result;result];
        
        %% 运行完毕后,保存实验结果到本地
        if Global.evaluated >= Global.evaluation
            filename = sprintf('%s%s.mat',dir_1,question);              %存放汇总的运行结果(近似PF)
            filename2 = sprintf('%s%s.mat',dir_2,method);              %存放每个算法的所有运行结果
            if exist(filename2,'file')
                delete(filename2);
            end
            save(filename2,'global_result');
            global_result = [];        %清除函数内部静态变量
            
            if exist(filename,'file')
                PF = load(filename);
                PF = CombineArchive(result{1,2},PF.PF,500);       %设置储备集中元素的个数
            else
                PF = CombineArchive(result{1,2},[],500);     %个体组成的PF
            end
           	fprintf('\nnumber of Non-dominant Solutions :%d\n',size(PF.objs,1));
           	save(filename,'PF');        %保存结果
        end
    end

     原因分析:本来在RecordResult函数中有一个if判断,用来判断算法是否是最后一次迭代,若是,就会将该函数内部的persistent变量global_result设置为空。然而,由于自己中途中断了整个算法的运行,导致RecordResult函数中的persistent变量global_result没有被置为空。当再次运行整个程序时,第一次进入RecordResult函数时,虽然还是会执行如下面代码来清除上次实验保留的persistent变量。

    if Global.evaluated <= Global.N
        clear var global_result;%仍然会恢复上次的global_result的值
    end

    然而,当执行完persistent global_result后,系统仍然会恢复上次中断程序执行时保留的persistent变量global_result的值,即原内存空间部分的值,该内存区域的值好像只能在关闭matlab才能彻底释放内存。

    新的解决方案

    为了使得程序不会受到上次没有运行完的结果的影响,在该函数的开头,判断该程序是否为第一次执行,若是,则直接清空该persistent变量中的值。

    function [ ] = RecordResult( Global )
        persistent global_result;
        % 声明静态变量    
        if Global.evaluated <= Global.N
            global_result = [];%第一次运行时,清除上次该函数运行留下的persistent变量
        end
        
        %% 判断目录是否存在
    	method = func2str(Global.algorithm);
    	question = func2str(Global.problem);
        dir_1 = sprintf('Data/%s/',question);                               %问题对应的第一级目录
        dir_2 = sprintf('%s%d/',dir_1,Global.run);                       %问题对应的第二级目录,单次运行结果存放在一个文件夹里面,文件夹的名称为运行序号
        %判断路径是否存在    
        if ~exist(dir_1,'dir')
            mkdir(dir_1);
        end
        if ~exist(dir_2,'dir')
            mkdir(dir_2);
        end
        
        %% 输出运行过程中的信息
        clc;%清空命令行
        fprintf('run %d\n',Global.run);
        fprintf('%s with %s on %s\n',method,func2str(Global.operator),question);
        fprintf('N: %d     evaluation: %d\n',Global.N,Global.evaluation);
        fprintf('status: (%6.2f%%), %.2fs passed...\n',Global.evaluated/Global.evaluation*100,Global.runtime);
        
        [r,~] = size(Global.result);
       	result = {Global.result{r,:}};                                           %每个算法最后一次运行结果
        global_result = [global_result;result];
        
        %% 运行完毕后,保存实验结果到本地
        if Global.evaluated >= Global.evaluation
            filename = sprintf('%s%s.mat',dir_1,question);              %存放汇总的运行结果(近似PF)
            filename2 = sprintf('%s%s.mat',dir_2,method);              %存放每个算法的所有运行结果
            if exist(filename2,'file')
                delete(filename2);
            end
            save(filename2,'global_result');
            
            if exist(filename,'file')
                PF = load(filename);
                PF = CombineArchive(result{1,2},PF.PF,500);       %设置储备集中元素的个数
            else
                PF = CombineArchive(result{1,2},[],500);     %个体组成的PF
            end
           	fprintf('\nnumber of Non-dominant Solutions :%d\n',size(PF.objs,1));
           	save(filename,'PF');        %保存结果
        end
    end

    因此,每次实验开始前切记使用global_result=[];将persistent变量设置为空。

    if Global.evaluated <= Global.N
        global_result = [];%第一次运行时,清除上次该函数运行留下的persistent变量
    end

    这样一来,只需要在开始的时候检测该函数是否为第一次执行,若是,则将该persistent变量设置为空,也就不需要每次结束之后都将该persistent变量设置为空了。

    即便是中途中断程序的运行,当函数重新运行时,第一次执行仍然会将结果设置为空,问题就解决了。代码来自改进的PlatEMO

    展开全文
  • 为了能够屏蔽底层存储实现的细节,让用户方便使用及管理员方便管理,Kubernetes从1.0版本就已经引入了Persistent Volume(PV)和Persistent Volume Claim(PVC) 两个资源对象来实现存储管理系统。 PV(持久卷)是对...
  • Persistent Volume 1、概念 PersistentVolume (PV) 是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命...
  • 完成nfs服务器搭建客户端nfs软件安装安装后,可在master各node节点检查nfs服务是否正常 [root@master ~]# showmount -e 172.27.9.181 Export list for 172.27.9.181: /backup 172.27.9.0/24 masternode01...
  • 概念 存储管理跟计算管理是两个不同的问题。理解每个存储系统是一件复杂的事情,特别是对于普通用户来...要完成这一任务,引入了两个新的API资源:Persistent Volume(持久卷,以下简称PV)和Persistent Volume Cla...
  • 摘要:本文分析了hostPath volume缺陷,然后对local persistent volume的使用场景、基本的工作机制进行了分析,介绍了使用时的注意事项,并简单介绍local volume manager如何帮助administrator进行local persistent ...
  • KUBERNETES存储之PERSISTENT VOLUMES简介 简介  管理存储管理计算有着明显的不同。PersistentVolume子系统给用户管理员提供了一套API,从而抽象出存储是如何提供消耗的细节。在这里,我们介绍两种新的API...
  • 概念 存储管理跟计算管理是两个不同的问题。理解每个存储系统是一件复杂的事情,特别是对于普通用户来说,...要完成这一任务,引入了两个新的API资源:Persistent Volume(持久卷,以下简称PV)和Persistent Volum...
  • 概念 存储管理跟计算管理是两个不同的问题。理解每个存储系统是一件复杂的事情,特别是对于普通用户来说,有时并不需要关心...要完成这 一任务,引入了两个新的API资源:Persistent Volume(持久卷,以下简称PV)...
  • kubernetes中的local persistent volume

    千次阅读 2019-09-18 05:14:33
    什么是Local Persistent Volumes 在kubernetes 1.14版本中, Local Persistent Volumes已变为正式版本(GA...现在用户终于可以在生产环境中使用Local PV的功能API了。首先:Local Persistent Volumes代表了直接绑...
  • PersistentVolume给用户管理员提供了一套API,抽象出存储是如何提供消耗的细节。在这里,我们介绍两种新的API资源:PersistentVolume(简称PV)PersistentVolumeClaim(简称PVC)。 PersistentVolume...
  • key: failure-domain.beta.kubernetes.io/zone values: us-central1-a us-central1-b accessMode:满足pv的accessMode即可,及pv的access privilege 可以更多 动态扩展:Expanding Persistent Volumes Claims 只能...
  • 官网:https://kubernetes.io/docs/concepts/storage/persistent-volumes/ 1、理解PV&PVC 当pod中定义volume的时候,我们只需要使用pvs存储卷就可以,...pvpvc是kubernetes抽象出来的一种存储资源。 Persiste...
  • Kubernetes PV在Retain策略Released状态下重新分配到PVC恢复数据 文章目录Kubernetes PV在Retain策略Released状态下重新分配到PVC恢复数据1. 实验目的环境说明2. 实验过程3. 小结 1. 实验目的环境说明 原由:在...
  • 0/1 nodes are available: 1 node(s) didn't find available persistent volumes to bind. ## 配置如下 ########################## apiVersion: v1 kind: PersistentVolume metadata: name: pv namespace: kafka ...
  • 官网参考:https://kubernetes.io/docs/concepts/storage/persistent-volumes/# 1、介绍 管理存储是与管理计算实例不同的问题。PersistentVolume子系统为用户管理员提供了一个API,该API从存储的使用方式中抽象出...
  • pv003 1Gi RWO,RWX Retain Available 16s pv004 1Gi RWO,RWX Retain Available 16s pv005 1Gi RWO,RWX Retain Available 16s pv006 1Gi RWO,RWX Retain Available 16s pv007 2Gi RWO,RWX Retain Available 16s pv008...
  • Kubernetes存储之Persistent Volumes简介 简介  管理存储管理计算有着明显的不同。PersistentVolume子系统给用户管理员提供了一套API,从而抽象出存储是如何提供消耗的细节。在这里,我们介绍两种新的API...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,172
精华内容 1,668
关键字:

persistent和retain