两年来,我们一直在使用 Kubernetes 进行深度学习方面的研究。虽然我们大量的 workloads 可以直接运行在云虚拟机上,但是因为 Kubernetes 目前仍在快速迭代,而且拥有比较好的扩展性,也没有过多的约束,因此 Kubernetes 成为了我们最理想的集群管理工具。目前,我们已经有好几个正在运行的 Kubernetes 集群了(有些运行在云虚拟机上,有些则直接运行在物理机上)。其中最大的一个集群运行在 Azure 上,由 D15v2 和 NC24 两种类型的虚拟机组成,目前已经超过 2500 个节点。


在达到 2500 节点规模的过程中,许多的系统组件都出现了问题,包括 etcd,Kube Master,Docker 拉取镜像,网络,Kube DNS,机器上的 ARP 缓存。接下来将分享我们所遇到的问题和解决方案,希望对大家有所帮助。


etcd


在集群中添加了超过 500 个节点的时候,我们的研究人员发现使用 kubectl 操作集群的时候会发生超时的情况。于是我们尝试添加更多的 Kube Master 节点(运行 kube-apiserver 的节点)。这样做临时解决了这个问题,但当我们添加了 10 个 Master 节点后,我们发现这只是在表面上解决问题,并没有找到这个问题的根本原因(作为对比,GKE 只使用了一台 32 核的虚拟机作为 Master 就能管理 500 个节点。


etcd 存储了 Kubernetes 集群的所有状态数据,因此我们强烈怀疑是 etcd 集群出现了问题。通过查看 Datadog,我们发现虽然我们的每台机器都使用了支持 5000 IOPS 的 P30 SSD,但是运行了 etcd 的 DS15v2 虚拟机的写延迟在某些时间段猛增至数百毫秒。

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

这么高的写延迟阻塞了整个集群!

在使用 fio 进行性能测试之后,我们发现 etcd 的 I/O 性能只能达到 I/O 上限的 10% 左右 。这主要是因为单次写延迟为 2ms,而 etcd 又使用了串行 I/O,导致 I/O 之间的延迟叠加(latency-bound)。