kubernetes 并行镜像拉取应仅拉取唯一的镜像一次,

6za6bjd0  于 6个月前  发布在  Kubernetes
关注(0)|答案(9)|浏览(61)

需要添加什么?

创建大量使用相同镜像的pod会导致kubelet为每个pod并行拉取镜像,这会导致registry QPS被使用,减慢其他使用不同镜像的pod的速度,并且浪费带宽多次下载相同的镜像。
如果相同的镜像已经在并行下载中,其他pod应该只需等待它,而不是启动新的下载并不使用registry QPS。

为什么需要这个?

我们有一个用例,我们同时启动大量的pod(500+),其中许多pod被调度到单个节点(100+),并且大多数pod具有相同的init容器和相同的镜像(给定容器上的镜像提供了完整的SHA摘要)。
这导致在这些pod的启动过程中,节点上使用了大量带宽,并且一些pod由于ImagePullBackoff导致的pull QPS exceeded而延迟。

xurqigkl

xurqigkl1#

这个问题目前正在等待分类。
如果SIG或子项目确定这是一个相关的问题,他们将通过应用triage/accepted标签并提供进一步的指导来接受它。
组织成员可以通过在评论中写入/triage accepted来添加triage/accepted标签。
有关使用PR评论与我互动的说明,请查看here。如果您对我的行为有任何问题或建议,请针对kubernetes-sigs/prow仓库提出一个问题。

r9f1avp5

r9f1avp53#

问题在于我们应该在容器运行时还是kubelet本身内进行操作。我认为双方都有利弊。🤔

yws3nbqq

yws3nbqq4#

在kubernetes/pkg/kubelet/images/puller.go文件中,我们可以为每个要拉取的镜像添加一个广播通道,以便在并行镜像拉取器实现中使用:

type parallelImagePuller struct {
    imageService kubecontainer.ImageService
    tokens      chan struct{}
}

然后,在检查是否有已经在进行中的拉取操作时,我们可以使用广播而不是新的拉取操作。具体实现如下:

func (pip *parallelImagePuller) pullImage(ctx context.Context, spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult, podSandboxConfig *runtimeapi.PodSandboxConfig) {
    go func() {
        if pip.tokens != nil {
            pip.tokens <- struct{}{}
            defer func() { <-pip.tokens }()
        }
        startTime := time.Now()
        imageRef, err := pip.imageService.PullImage(ctx, spec, pullSecrets, podSandboxConfig)
        var size uint64
        if err == nil && imageRef != "" {
            // 尽最大努力获取镜像大小,忽略错误。
            size, _ = pip.imageService.GetImageSize(ctx, spec)
        }
        pullChan <- pullResult{
            imageRef: imageRef,
            imageSize: size,
            err:      err,
            pullDuration: time.Since(startTime),
        }
    }()
}

关于这个实现,你有什么想法吗?

odopli94

odopli946#

@saschagrunert,这是个bug报告还是功能请求?

1bqhqjot

1bqhqjot7#

我认为这更像是从角落里修复一个bug。

wvmv3b1j

wvmv3b1j8#

/remove-kind feature

b4wnujal

b4wnujal9#

我想分享一些关于这种行为可用性/透明度的更多想法。我认为为了让它不令人困惑,更具“可预测性”,它应该表现得像这样:

  • 如果 imagePullPolicy: Always ,则不应发生去重/等待,即使在指定图像摘要的情况下也是如此。因为图像可能已在注册表中更新,即使在同一时间多次拉取相同图像的几率很小,但仍然有可能发生。然而更重要的原因只是为了不引入基于图像URL类型的行为。
  • 如果 imagePullPolicy: IfNotPresent ,则如果具有相同URL(无论摘要还是标签)的图像已经在其他线程中被拉取,它应该等待。这种行为与无去重/等待一致,因为图像的存在是基于URL而不是特定的图像摘要(即,如果在同时在注册表下使用相同的标签更新了图像)。

这有意义吗?

相关问题