在 Kubernetes 上分散工作负载

在 Kubernetes 上分散工作负载

我创建了一个部署,它可以包含 2 到 25 个容器,所有容器都在一个更大的逻辑工作单元的某个部分上工作。容器将使用 700MB-4GB 的峰值内存,我最初的方法是请求 1G,限制 4G。在最坏的情况下(4GB 内存多于 700MB),这导致节点关闭(或者从一开始就不会安排)即使在其他地方有 3 或 400% 的免费聚合资源可用。

观察一个或两个容器在 RAM 中缓慢上升并导致节点 OOM,而不是让调度程序将容器拔出并重新定位,这似乎是对稳定性的一个相当明显的担忧。

经过多年的 git 争论、文档和代码本身的挖掘。目前尚不清楚调度程序在启动时在哪个抽象层次上传播容器,或者 K8S 在部署工作后是否会采取任何主动措施。

如果 ReplicaSet(我相信这是新的、改进的 ReplicationController)只会在主机被杀死之前重新激活容器,那么您必须为其职责范围内的每个 pod 创建最坏情况的请求。对于我们作为 Deployment 运行的较大作业,这引入了一个由于“以防万一”而过度配置,导致 50% 以上的 RAM 浪费

保留过度配置的资源不是我们在这里试图解决的问题之一吗?

这些年来,我已经使用过相当多的调度程序/资源管理器,不记得有哪个案例,一个作业步骤 - 容器 - 无论类比是什么,被允许损害主机本身,而不是被强制迁移或直接标记为不适合调度..

尽管医生们不赞成这个想法,裸 Pod 或 1 个 Pod:1 个 ReplicaSet似乎是保持工作分布的唯一方法(假设容器检查点和自杀频率足够高,以便重新考虑整体资源状况)。

我还应该提到,这是托管的 Google 容器引擎 (v1.2.2),并且考虑到可以使用几页标志来启动 K8S,目前还不清楚这是否是一个固有问题,用户错误或者只是 GCE 如何配置 K8S。我真的希望这方面是用户错误。

答案1

根据 Kubernetes slack 频道上一些非常有帮助的人的意见来回答我自己的问题。

-- 我的经验是,由于容器的 OOM 导致节点失败,这可能是由于次要影响,因为资源管理器旨在防止这种情况发生。建议的罪魁祸首实际上是 I/O 子系统变得过载到使节点不稳定的程度,经过一些测量,这看起来很有可能。

在 GKE 中,OS、Docker、K8S 以及 pod 请求的任何临时目录都在一个非本地 100GB(我相信是默认的)ext4 文件系统上。

我们启动的大多数 pod 都在请求并写入临时目录,集体 I/O 使系统不堪重负,以至于变得无响应,在我们的例子中,甚至锁定了操作系统本身。

——初步测试,在自己的 ext4 驱动器上设置我自己的 K8S,操作系统、docker 和临时空间位于它们自己的 ZFS 池中,相同的部署清单确实会产生压力,但不会导致操作系统崩溃。

-- 有人提出但尚未测试的一种解决方法是使用作业并通过一些协调过程管理它们之间的依赖关系,大概是因为这会将各个容器分散到整个集群中。这可能有效,但我觉得这是在掩盖一个潜在的问题。

虽然我还没有测量为我们使用emptyDir的暂存空间分配持久磁盘,但我认为这也会减轻主磁盘上的负载,可能足以掩盖问题。

不幸的是,默认的 GKE 设置假定 sda 将能够处理整个操作系统、K8S 日志、Docker 和暂存空间的负载,这显然对大多数人来说都是可行的,因为我找不到像我们这样的其他问题。

从裸机开始,我希望避免在管理集群时出现一些低级细节,但 dataproc 和 GKE 到目前为止至少让我倾向于自己构建集群。

希望这可以为那些工作量适合作业模式或主要使用配置磁盘的人提供帮助。

我很惊讶任何最佳实践都会对启动驱动器抱有如此高的期望,并且会通过支持来标记这一点,因为即使是“常规”计算引擎似乎也不鼓励这样做,因为考虑到默认的启动驱动器大小。

相关内容