0

我正在尝试调试通过使用解决的问题hostNetwork: true。k8s安装使用的是kubenet,k8s版本是1.9.8。

使用 m4.xlarge 和 c4.xlarge 实例在 AWS 上使用 kops 完成安装。

问题如下:

当我们将此应用程序迁移到 Kubernetes 时,某个端点的响应时间(百分位 95)增加了大约 20-30%。

hostNetwork: true但是,在 yaml 中使用时,此问题已解决。此端点的性能与虚拟机上的性能相同,即响应时间的百分位 95 与此端点相同。

我在 7 月 18 日(是的,不久前!)的 kubernetes 办公时间问过这个问题,然后hostNetwork: true解决方法就出现了。

请注意,所有 kube-proxy 的东西都可以丢弃,因为在应用程序本身进行测量时会看到响应时间的增加。我的意思是,ruby 应用程序测量它所花费的时间并将其发送到日志收集器。这一次,即由于请求开始由应用程序处理直到完成,已经显示出性能下降。所以 kube-proxy 和那些东西是不相干的。

pod 有 3 个容器:

  • Nginx
  • 日志收集器
  • 该应用程序(与独角兽一起运行的红宝石应用程序)

这些应用程序也处于虚拟机模式

我尝试了什么:

  • 找到了一种使用 ab(apache benchmark) 重现的方法
    • ab -c 1 -n 1000 'https://...
    • 同样的情况发生在 http,而不是 https
  • 我尝试删除 nginx 容器,但它并没有改变任何东西。日志收集器在 localhost 上使用,并且在没有出现问题的 VM 上执行相同的操作
  • 我尝试在 nginx 和应用程序之间使用 unix 套接字,而不是 localhost,但它也没有改变任何东西。
  • 尝试在 EKS 中使用相同的实例 (m4.xlarge):同样的情况。虽然不使用的性能成本hostNetwork: true更低,大约在 10% 左右。请注意,EKS 不使用 kubenet,而是使用基于一些开源的自己的网络覆盖。
  • 尝试使用仅返回字符串的另一个端点(输入“Ok”)并且问题没有发生
  • 尝试使用返回几 MB 的端点(如"Die" * 10 * 1024 * 1024),问题也没有发生
  • 尝试了具有不同查询字符串参数问题的同一端点,因此响应很大(9MB)或短(130kb)并且都可靠地重现了问题
  • 尝试了一个 nodejs 应用程序,它从类似的来源返回类似的 json,并且问题不存在(也不存在短/长响应)接下来可能会做什么:

所以,我正在尝试调试这个问题以了解它是什么,并希望停止使用hostNetwork: true. 似乎有进一步挖掘的途径:

  • 尝试其他 CNI(EKS 表现出较少的性能下降)以查看性能是否发生变化

  • 查看此端点的功能或它如何与独角兽和整个堆栈交互。一个很大的区别是,unicorn 是每个请求一个进程(同步),而 nodejs 不是。

  • 尝试使用更多较新的机器 (m5/c5) 来查看它们是否能减轻性能损失。但是,由于当前使用它们作为虚拟机的实例不存在这个问题,似乎如果它有帮助,只会隐藏问题

这个有性能问题的端点是 ruby​​ 中的一个端点,它读取数据库并返回一个 json。数据库、主机、网络看起来都很好(使用 vmstat、我们的常规工具、AWS 控制台、检查 kern.log、sysloca 等监控 CPU、磁盘 IO、交换等)

碰巧,你有过类似的经历吗?或者您对如何继续调试此问题有任何其他想法?

任何想法或任何形式的帮助都非常受欢迎!

罗德里戈

4

2 回答 2

1

问题似乎是https://github.com/kubernetes/kubernetes/issues/56903

那里提到的解决方法(如dnsPolicy: Default)为我解决了这个问题。

这两个帖子详细解释了这个问题:https ://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts和https://blog.quentin-machu.fr/2018/06/24 /5-15s-dns-lookups-on-kubernetes/

并且还提供了一些解决方法。

长话短说:在执行 DNAT/SNAT 时,nf 中有一个竞争条件会影响无连接协议(如 UDP)。编织者已经发送了一个补丁来修复大部分比赛。要解决此问题,您可以使用外部 dns(即不是 kube-dns,因为它通过服务公开,因此使用 DNAT),为 glibc 设置标志(但不适用于 musl),使用最小延迟与tc

注意: UsingdnsPolicy: Default可以解决问题,因为它使用的是外部 DNS 服务器(即不是托管在 kubernetes 中并通过服务访问,即 DNAT)。

我将为我的集群测试 glibc 标志,尽管这dnsPolicy: Default确实解决了我的问题,因为我们在某些应用程序上使用 k8s DNS 服务解析。

于 2018-09-26T15:16:14.360 回答
0

听起来您遇到的开销是由于 Docker 的 NAT。
hostNetwork: true将主机的网络暴露给 pod/容器,而不是使用 NAT,提供更好的性能......但降低了安全性。

希望这可以帮助!

于 2018-09-25T14:04:25.570 回答