【问题标题】:Kubernetes Ephemeral Storage Limit and Container LogsKubernetes 临时存储限制和容器日志
【发布时间】:2021-06-22 06:14:17
【问题描述】:

假设我为 Kubernetes 集群(使用 Docker)中的容器设置了 resource.limits.ephemeral-storage,并在工作节点上设置了以下 Docker daemon.json 日志配置:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "10",
  }
}

我的理解是,所有日志文件(甚至轮换的日志文件)都将计入此临时存储限制。这意味着要确定resource.limits.ephemeral-storage 的值,我必须考虑计算允许的最大日志大小(此处为 10*100MB)。

有没有办法将日志文件从容器的临时存储限制中“排除”?

由于日志处理是在 Kubernetes “外部”完成的,我想避免 Kubernetes 工作负载的资源限制取决于 Docker 日志配置。否则,如果忘记调整每个容器的限制,对轮换设置的任何更改(例如增加到 10*200MB)都可能导致 pod 被驱逐。

【问题讨论】:

  • 你好@hessfr,欢迎来到 StackOverflow!请确认您是如何设置集群的?您是否使用过 Docker Desktop 或其他解决方案?
  • 感谢@MikołajGłodziak!该集群使用 Rancher RKE 设置并使用 Kubernetes v.1.17
  • 您可能正在使用已弃用的 Kubernetes 版本。 rancher.com/support-maintenance-terms/all-supported-versions/…
  • 我认为这里的版本不是问题:Rancher 2.5.5 支持 k8s 版本 1.17.16(根据rancher.com/support-maintenance-terms/all-supported-versions/…)。我的问题实际上是更笼统的:如果更新版本的 k8s/docker 支持“排除”旋转的日志文件不计入临时存储,我会碰巧升级
  • 是什么让您认为 kubelet 在 pod 磁盘使用率计算中包含 docker 日志?目前,我的印象是只考虑临时磁盘使用和容器映像大小。

标签: kubernetes ephemeral-storage


【解决方案1】:

基于 release 1.17.16 source code 中的函数 calcEphemeralStorage,如果您想从计算中排除日志,您可以注释或删除这些行并重建 kubelet:

if podLogStats != nil {
        result.UsedBytes = addUsage(result.UsedBytes, podLogStats.UsedBytes)
        result.InodesUsed = addUsage(result.InodesUsed, podLogStats.InodesUsed)
        result.Time = maxUpdateTime(&result.Time, &podLogStats.Time)
    }

这部分代码负责计算日志的临时存储使用量。但是删除这部分代码可能还需要调整一些期望计算日志量的测试文件。 所有统计信息都计入this function:

func (p *criStatsProvider) makePodStorageStats(s *statsapi.PodStats, rootFsInfo *cadvisorapiv2.FsInfo) {
    podNs := s.PodRef.Namespace
    podName := s.PodRef.Name
    podUID := types.UID(s.PodRef.UID)
    vstats, found := p.resourceAnalyzer.GetPodVolumeStats(podUID)
    if !found {
        return
    }
    logStats, err := p.hostStatsProvider.getPodLogStats(podNs, podName, podUID, rootFsInfo)
    if err != nil {
        klog.ErrorS(err, "Unable to fetch pod log stats", "pod", klog.KRef(podNs, podName))
        // If people do in-place upgrade, there might be pods still using
        // the old log path. For those pods, no pod log stats is returned.
        // We should continue generating other stats in that case.
        // calcEphemeralStorage tolerants logStats == nil.
    }
    etcHostsStats, err := p.hostStatsProvider.getPodEtcHostsStats(podUID, rootFsInfo)
    if err != nil {
        klog.ErrorS(err, "Unable to fetch pod etc hosts stats", "pod", klog.KRef(podNs, podName))
    }
    ephemeralStats := make([]statsapi.VolumeStats, len(vstats.EphemeralVolumes))
    copy(ephemeralStats, vstats.EphemeralVolumes)
    s.VolumeStats = append(append([]statsapi.VolumeStats{}, vstats.EphemeralVolumes...), vstats.PersistentVolumes...)
    s.EphemeralStorage = calcEphemeralStorage(s.Containers, ephemeralStats, rootFsInfo, logStats, etcHostsStats, true)
}

在最后一行你可以找到calcEphemeralStorage的用法。

在最近的版本中,mentioned code 包含相同的日志计算部分,因此该解决方案也适用于 latest release。

另见:

【讨论】:

    猜你喜欢
    • 2020-03-21
    • 2020-12-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 1970-01-01
    相关资源
    最近更新 更多