首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AccessMode: ReadWriteOnce的库伯奈茨聚氯乙烯

AccessMode: ReadWriteOnce的库伯奈茨聚氯乙烯
EN

Stack Overflow用户
提问于 2017-05-25 06:24:34
回答 2查看 4.8K关注 0票数 1

我们的设想:

我们使用ceph存储一些机器学习培训数据集,工作流如下所示:

使用AccessMode: ReadWriteOnce创建一个ceph pvc pvc培训数据。

创建一个用1脚安装pvc培训数据的写作业,并将培训数据写入pvc培训数据。

将培训数据写入pvc培训数据后,容器将退出,pvc培训数据pvc由k8s卸载,完成写入工作。

创建一个带有n个n >= 1的读取作业,在其中安装pvc-培训-数据和readOnly: true来使用培训数据。顺便说一句:我们使用k8s 1.6.1

到目前为止,工作流在我们的使用场景中运行良好,但是我有一些关于PVC AccessMode和ceph与AccessMode: ReadWriteOnce有关的问题。

  1. 如何理解AccessModes: ReadOnlyMany,ReadWriteOnce,ReadWriteMany?我认为使用范围是ReadOnlyMany < ReadWriteOnce < ReadWriteMay,所以如果我将PVC与AccessMode: ReadWriteOnce一起应用,我可以将它用作AccessMode: ReadOnlyMany PVC,对吗?
  2. ceph是一个块设备,每个容器(在不同的主机上)装入同一个ceph设备都会有自己的文件系统,所以唯一允许的AccessMode是ReadOnlyMany或ReadWriteOnce,我们应该在k8s代码中限制ReadWriteOnce的使用吗?
  3. 如果一个ReadWriteOnce pvc是由一个Pod安装在readOnly:false,那么就没有更多的Pod可以安装这个设备,直到它被卸载。
  4. 如果ReadWriteOnce pvc是由带有readOnly:true的Pod安装的,那么它只能安装到其他Pod上,只要它们设置了readOnly: true。
  5. 对于同一个Pod中的容器没有限制,因为它们共享来自主机${KUBELET_ROOT}/plugins/{xx}/ /的相同的文件系统。
EN

回答 2

Stack Overflow用户

发布于 2017-05-25 19:45:59

关于你的第一个问题:

  1. 如何理解AccessModes: ReadOnlyMany,ReadWriteOnce,ReadWriteMany?我认为使用范围是ReadOnlyMany < ReadWriteOnce < ReadWriteMay,所以如果我将PVC与AccessMode: ReadWriteOnce一起应用,我可以将它用作AccessMode: ReadOnlyMany PVC,对吗?

文档明确指出:

代码语言:javascript
运行
复制
Important! A volume can only be mounted using one access mode at a
time, even if it supports many.

我不太清楚你的第二个问题。但考虑到第一个问题的答案,我认为这可能是无效的吗?

票数 1
EN

Stack Overflow用户

发布于 2019-10-18 07:58:53

要回答这个问题,不妨看一下源代码。正如我在集群迁移中遇到的一个问题一样,下面是这样的情况:我们有一个具有v1.9的集群,还有一个具有accessMode: ReadWriteMany (RWX)的PV和accessMode: ReadWriteOnce的PVC,这两个集群都可以绑定而不会出现任何错误。

我们将一些应用程序迁移到新集群(v1.12),在新集群中,PVC绑定给出了一个错误:

无法绑定到请求的卷“卷名”:不兼容的accessMode

我在v1.12的源代码中搜索了错误,并看到了以下几行:

第1.12节:

代码语言:javascript
运行
复制
//checkVolumeSatisfyClaim checks if the volume requested by the claim satisfies the requirements of the claim
func checkVolumeSatisfyClaim(volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) error {
    requestedQty := claim.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
    requestedSize := requestedQty.Value()

    // check if PV's DeletionTimeStamp is set, if so, return error.
    if utilfeature.DefaultFeatureGate.Enabled(features.StorageObjectInUseProtection) {
        if volume.ObjectMeta.DeletionTimestamp != nil {
            return fmt.Errorf("the volume is marked for deletion")
        }
    }

    volumeQty := volume.Spec.Capacity[v1.ResourceStorage]
    volumeSize := volumeQty.Value()
    if volumeSize < requestedSize {
        return fmt.Errorf("requested PV is too small")
    }

    requestedClass := v1helper.GetPersistentVolumeClaimClass(claim)
    if v1helper.GetPersistentVolumeClass(volume) != requestedClass {
        return fmt.Errorf("storageClassName does not match")
    }

    isMisMatch, err := checkVolumeModeMisMatches(&claim.Spec, &volume.Spec)
    if err != nil {
        return fmt.Errorf("error checking volumeMode: %v", err)
    }
    if isMisMatch {
        return fmt.Errorf("incompatible volumeMode")
    }

    if !checkAccessModes(claim, volume) {
        return fmt.Errorf("incompatible accessMode")
    }

    return nil
}

// Returns true if PV satisfies all the PVC's requested AccessModes
func checkAccessModes(claim *v1.PersistentVolumeClaim, volume *v1.PersistentVolume) bool {
    pvModesMap := map[v1.PersistentVolumeAccessMode]bool{}
    for _, mode := range volume.Spec.AccessModes {
        pvModesMap[mode] = true
    }

    for _, mode := range claim.Spec.AccessModes {
        _, ok := pvModesMap[mode]
        if !ok {
            return false
        }
    }
    return true
}

五.9:

代码语言:javascript
运行
复制
//checkVolumeSatisfyClaim checks if the volume requested by the claim satisfies the requirements of the claim
func checkVolumeSatisfyClaim(volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) error {
    requestedQty := claim.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
    requestedSize := requestedQty.Value()
    isMisMatch, err := checkVolumeModeMisMatches(&claim.Spec, &volume.Spec)
    if err != nil {
        return fmt.Errorf("error checking if volumeMode was a mismatch: %v", err)
    }

    volumeQty := volume.Spec.Capacity[v1.ResourceStorage]
    volumeSize := volumeQty.Value()
    if volumeSize < requestedSize {
        return fmt.Errorf("Storage capacity of volume[%s] requested by claim[%v] is not enough", volume.Name, claimToClaimKey(claim))
    }

    requestedClass := v1helper.GetPersistentVolumeClaimClass(claim)
    if v1helper.GetPersistentVolumeClass(volume) != requestedClass {
        return fmt.Errorf("Class of volume[%s] is not the same as claim[%v]", volume.Name, claimToClaimKey(claim))
    }

    if isMisMatch {
        return fmt.Errorf("VolumeMode[%v] of volume[%s] is incompatible with VolumeMode[%v] of claim[%v]", volume.Spec.VolumeMode, volume.Name, claim.Spec.VolumeMode, claim.Name)
    }

    return nil
}

// checkVolumeModeMatches is a convenience method that checks volumeMode for PersistentVolume
// and PersistentVolumeClaims along with making sure that the Alpha feature gate BlockVolume is
// enabled.
// This is Alpha and could change in the future.
func checkVolumeModeMisMatches(pvcSpec *v1.PersistentVolumeClaimSpec, pvSpec *v1.PersistentVolumeSpec) (bool, error) {
    if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
        if pvSpec.VolumeMode != nil && pvcSpec.VolumeMode != nil {
            requestedVolumeMode := *pvcSpec.VolumeMode
            pvVolumeMode := *pvSpec.VolumeMode
            return requestedVolumeMode != pvVolumeMode, nil
        } else {
            // This also should retrun an error, this means that
            // the defaulting has failed.
            return true, fmt.Errorf("api defaulting for volumeMode failed")
        }
    } else {
        // feature gate is disabled
        return false, nil
    }
}

当您查看checkAccessModes函数中的v1.12代码时,它将卷accessModes放入 map 并在该映射中搜索PVC accessModes,如果在该映射中找不到PVC accessMode,则返回false,这将导致不兼容的accessMode错误。

那么为什么我们在1.9版中没有得到这个错误呢?因为它在checkVolumeModeMisMatches函数中有不同的控件。它检查一个默认为假的alpha特性,名为BlockVolume. 。因为它是假的,它不会碰到

代码语言:javascript
运行
复制
if isMisMatch {
    return fmt.Errorf("VolumeMode[%v] of volume[%s] is incompatible with VolumeMode[%v] of claim[%v]", volume.Spec.VolumeMode, volume.Name, claim.Spec.VolumeMode, claim.Name)
}

代码块。

您可以使用以下方法检查主节点上的BlockVolume功能:

代码语言:javascript
运行
复制
ps aux | grep apiserver | grep feature-gates

我希望这能澄清你的问题。特别是v1.12中的checkAccessModes函数,目前也在主支路中进行PVC控制。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44173653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档