我创建了一个 Deployment,它可以包含 2 到 25 个容器,它们都在一个更大的单个逻辑工作单元的一个切片上工作。容器将使用 700MB-4GB 的峰值内存,我最初的方法是请求 1G,限制 4G。在最坏的情况下(4GB 多于 700MB),即使在其他地方有 3% 或 400% 的免费聚合资源可用,这也会导致节点停机(或不会安排开始)。
看着一个或两个容器在 RAM 中慢慢爬升并 OOM 节点关闭,而不是让调度程序将容器拔出并重新定位,这似乎是一个非常明显的稳定性问题。
经过多年的 git 辩论、文档和代码本身的挖掘。目前尚不清楚调度程序在抽象的哪个抽象级别上甚至在启动时传播容器,或者一旦部署工作,K8S 是否有任何主动步骤。
如果一个 ReplicaSet(我相信那是新的、改进的 ReplicationController)只会重新激活容器直到杀死主机,你必须在它的职权范围内创建对每个 pod 的最坏情况请求。对于我们作为部署运行的较大的作业,这会引入50% 以上的 RAM 浪费,因为“以防万一”过度配置。
保持过度配置的资源不是我们在这里试图解决的问题之一吗?
多年来,我使用了很多调度程序/资源管理器,并且不记得一个作业步骤 - 容器 - 无论是什么类比都会被允许损害主机本身,而不是被强制迁移或直接标记没有资格安排..
尽管文档告诫了这个想法,但裸 pod 或 1 pod:1 ReplicaSet似乎是保持工作分布式的唯一方法(假设容器检查点和自杀经常足以重新考虑整体资源图)。
我还应该提到,这是托管的 Google Container Engine (v1.2.2),鉴于看起来有几页标志可以启动 K8S,不清楚这是一个固有问题、用户错误还是 GCE 的配置方式K8S。我真的希望这个用户错误。
根据 Kubernetes slack 频道上一些非常有帮助的人来回答我自己的问题。
-- 我的节点由于容器的OOM'ing 而失败的经历可能是由于资源管理器旨在防止这种情况的次要影响。建议的罪魁祸首实际上是 I/O 子系统过载到节点不稳定的程度,经过一些测量,这看起来很可能。
我们创建的大多数 pod 都在请求并写入临时目录,而集体 I/O 使系统不堪重负,以至于系统变得无响应,在我们的例子中锁定了操作系统本身。
-- 一个初步测试,在自己的 ext4 驱动器上设置我自己的 K8S 操作系统,docker 和在他们自己的 ZFS 池中的临时空间,并且相同的部署清单确实有压力,但不会接近崩溃操作系统。
- 一个已经提出但尚未测试的解决方法是使用 Jobs 并通过一些协调过程管理它们之间的依赖关系,大概因为这会将单个容器分布在集群中。这可能会奏效,但让我印象深刻,因为它掩盖了一个潜在的问题。
虽然我还没有测量为我们使用 emptyDir 的暂存空间分配永久性磁盘,但我假设这也会减轻主磁盘上的负载,并且可能足以掩盖问题。
不幸的是,默认的 GKE 设置假定 sda 将能够处理操作系统、K8S 日志、Docker 和暂存空间的全部负载,这显然必须为大多数人工作,因为我找不到像我们这样的另一个问题。
来自裸机,我希望在管理集群时避免一些低级别的细节,但是到目前为止,dataproc 和 GKE 至少让我非常倾向于自己构建集群。
希望这将有助于那些工作负载适合作业模式或主要使用预置磁盘的人。
我很惊讶任何最佳实践都会对引导驱动器抱有如此多的期望,并且会在支持下标记这一点,因为即使是“常规”计算引擎也似乎不鼓励这种情况,因为默认引导驱动器大小。