首页 存档 技术 查看内容

在Kubernetes上部署近1000个OpenStack节点的经验分享

2018-3-30 13:00 |来自: 互联网 826 0

摘要: 去年年底,我们尝试在已有的 Kubernetes 集群上部署大约 1000 个OpenStack 节点,试图发现可能遇到的问题,然后尽可能找到修复它们的方法。总的来说是有些问题,但一般情况下我们能解决,我们觉得这些经验是大家可能 ...


        去年年底,我们尝试在已有的 Kubernetes 集群上部署大约 1000 个OpenStack 节点,试图发现可能遇到的问题,然后尽可能找到修复它们的方法。总的来说是有些问题,但一般情况下我们能解决,我们觉得这些经验是大家可能在寻找的。


        整体而言,我们使用 Kargo 部署了 Kubernetes 集群,并用 Fuel-CCP 在其上又部署了 900 多个节点的 OpenStack 集群。Kargo 是 Kubernetes 孵化项目的一部分,并遵循了大型 Kubernetes 集群 的参考架构。


        实验中我们记录了发现的问题,对部署工具、参考设计文档的修改。下面就是我们的发现。





        01



        配置


        我们一开始使用了 175 个物理服务器,其中 3 个用于 Kubernetes 控制服务(API 服务器,ETCD,Kubernetes 调度器等),剩余的每个节点各有 5 个虚拟机作为 Kubernetes minion 节点。

        每台物理服务器的规格如下:


        HP ProLiant DL380 Gen9

        CPU 2x Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz

        内存 264G

        存储 3.0T on RAID on HP Smart Array P840 Controller, HDD 12 x HP EH0600JDYTL

        网络 2x Intel Corporation Ethernet 10G 2P X710


        运行的 OpenStack 集群(就 Kubernetes 而言)包括:


        1.OpenStack 控制服务运行在超过 6 个节点的 150 个 pod 中

        2.剩余节点有接近 4500个 pod,每个 minion 节点有5 个 pod




        02



        一个 Prometheus 的主要问题


        在实验中,我们使用Prometheus 工具来监测资源的消耗,核心系统、Kubernetes、OpenStack 服务的负载。当使用 Prometheus 时有个问题引起我们注意:删除 Prometheus 存储的旧数据会明显提高 Prometheus API 的速度,但是这样旧群集的信息也被删除了,使得后期无法处理数据了。所以在每次测试时都要详细的记录观察到的问题,以及每次调试都要足够充分。


        值得庆幸的是,我们做了详细的记录,另外我们决定将 Prometheus 数据备份到它支持的时间序列数据库中来防止这种情况,如 InfluxDB、Cassandra、OpenTSDB。默认情况下,Prometheus 对使用实时监控、报警系统进行了优化,Prometheus 开发团队也官方推荐只保留 15 天的监控数据,以保证系统工作响应速度。通过设置备份,我们可以从备份中获取数据来进行后期处理。




        03



        我们测试中遇到的问题



        3.1 Kube-apiserver 巨大的负载


        • 现象

        最初,我们把所有节点(包括 Kubernetes 控制平面)都运行在虚拟环境中,但负载是太高以至于不能正常工作,所以他们被转移了物理服务器上。尽管如此,在我们迁移到物理服务器后,Kubernetes 集群中运行的 API 服务器仍占用了 2000% 的 CPU(接近总计算节点性能的 45%)。


        • 根本原因

        所有不在 Kubernetes 主节点上的服务(kubelet、kube-proxy 在所有的 minion 节点上)都通过本地的 Nginx 代理来访问 API 服务。大多数的请求在初始化连接后(设置的超时时间为 5 至10分钟)都是空闲的。而 Nginx 配置中超过 3 秒的空闲连接都会被切断,这导致所有客户端进行重新连接,甚至更糟糕的会重新启动被中止的 SSL 会话。在服务端,Kube API 服务因此消耗了 2000% 的 CPU资源,使得其他请求响应非常慢。


        • 解决方法

        在 nginx.conf 中设置 proxy_timeout 参数为 10分钟,使得 Nginx 切断 SSL 连接前有足够多的时间等待连接本身超时。修改之后,一个 API 服务只消耗了 100% 的 CPU(总计算节点性能的2%),另一个 API 服务消耗了 200% 的 CPU(总计算节点性能的 4%),平均响应时间为 200-400毫秒。


        • 上游问题状态:已修复

        Kargo 部署时设置 proxy_timeout 为 10分钟:问题 已修复代码 由 Fuel CCP 团队提交。



        3.2 KubeDNS 默认设置不能处理大型集群的负载


        • 现象

        当部署这么大的 OpenStack 集群,KubeDNS 由于负载过高而失去响应。我们从 kubedns pod 的 dnsmasq 容器中的日志里发现了出错的原因:


        Maximum number of concurrent DNS queries reached.

        此外,dnsmasq 容器有时也会因为内存限制而重新启动。


        • 根本原因

        首先,kubedns 在这个架构中似乎即使没有负载也常常出错。在实验过程中,我们观察到,即使在一个没有 pod(但足够大) 的 Kubernetes 群集中 kubedns 容器也经常重新启动。重新启动是因为心跳检测失败而引起的,在日志中我们还没观察有价值的信息。


        其次,dnsmasq 理论上是让 kubedns 负载降低的,但这么大负载的情况下它需要重新调优才能正常工作。


        • 解决方法

        解决这个问题需要几个层次的步骤:


        1.放宽 dnsmasq 容器的限制:他们承担了大部分的负载。

        2.给 kubedns 冗余控制器添加更多的副本(我们左后使用了 6 个副本,因为它解决了问题 - 更大的集群它可能需要更多的副本)。

        3.增加 dnsmasq 的并发处理数量(我们使用 dnsmasq 手册中推荐的 dns-forward-max=1000)

        4.增加 dnsmasq 缓存的大小:它设置了 10000 个缓存条目的限制。

        5.修复 kubedns 来更合理地处理这种情况。


        • 上游问题状态:部分修复

        针对#1和#2 的问题 Kubernetes 团队使得 Kargo 可以修改参数配置:问题 代码

        其他问题 - 还未开始修复。



        3.3 Kubernetes 调度器需要部署到单独的节点上

        • 现象

        在 Kubernetes 上部署大规模的 OpenStack 集群,Kubernetes 的调度器、控制器、管理器和 API 服务负载都很高,对 CPU 资源的抢夺也很严重。调度器是最繁忙的,所以我们需要把它部署在单独的节点上。


        • 解决方法

        我们把 Kubernetes 调度器手动移动到单独的节点;手动杀死其他调度,以防止它们转移到其它节点上。


        • 上游问题状态:已报告

        在Kargo 中的问题



        3.4 Kubernetes 调度器处理 pod antiaffinity 非常低效


        • 现象

        每次使用 pod antiaffinity 规则调度 pod 时,调度器都要花费很长的时间。每个 pod 的调度时间大约为2-3秒,这使得部署 900 个节点的 OpenStack 集群需要非常长的时间(仅调度大约需要 3 小 时)。OpenStack 的部署必须使用 antiaffinity 规则,以防止单个 Kubernetes minion 节点启动多个 OpenStack 计算服务。


        • 根本原因

        根据分析结果,大部分的时间都花在创造新的选择器来匹配现有的pod,这会触发验证操作。基本上,我们有 O(N^2) 不必要的验证步骤(其中 n = pod 的数目),即使我们只有 5 个部署步骤需要调度。


        • 解决方法

        在这种情况下,我们需要优化调度的时间,使得其调度一个 pod最多需要 300 毫秒。这样调度还是很慢(调度一个 900 个节点的OpenStack 集群需要 30 分钟),但它至少合理。该解决方案降低了耗时的操作到 O(N) 的时间,这比之前的好,但仍取决于 pod的数目而不是部署的数目,因此还有很大的改进空间。


        • 上游问题状态:已修复

        这部分优化已经合并到主仓库(代码 ),以及移植到了 1.5 分支,并在 1.5.2 发布(代码 )。



        3.5 Kube API 服务默认速率限制非常低



        • 现象

        即使 Kube API 服务器可以承载更多的负载,不同的服务仍收到“429 Rate Limit Exceeded” 的 HTTP 错误。这个问题是在调度器 BUG 中发现(见下文)。


        • 解决方法

        通过 max-requests-inflight 选项来修改 Kube API 服务的最大连接速率。它默认为 400,但在我们的情况下,它设为 2000 比较合理。Kargo部署工具应该可以配置这个数字,因为部署更大规模的集群这个数字需要更大。


        • 上游问题状态:已报告

        在 Kargo 中的问题



        3.6 Kubernetes 调度器不能正确调度


        • 现象

        当创建大量 pod(在我们的例子中大约为 4500 个),并且 Kube API 服务返回了 429 错误(见上文),调度会安排同一部署中的几个 pod 到一个节点上,这违反了它们的 pod antiaffinity 规则。


        • 根本原因

        见下面的代码拉取请求。


        • 上游问题状态:已提交代码

        来自 Mirantis 团队的修复:代码拉取请求 (已合并,Kubernetes 1.6 的一部分)。




        3.7 Docker 有时无法响应



        • 现象

        多个节点的 Docker 都会偶尔停止响应,这导致 kubelet 日志中有超时错误。发生这种情况时,受影响的 minion 节点上的 pod 不能被创建和删除。尽管 Docker 1.11 以来很多问题都被修复了,我们还在观察这些现象。


        • 解决方法

        Docker 的日志没有包含有价值的信息,所以我们不得不在受影响的节点上重新启动 Docker 服务。(在实验中,我们使用的是 Docker 1.12.3,但我们在 Docker 1.13rc 版中也观察到了类似的现象。)



        3.8 OpenStack 服务不处理 PXC 伪死锁


        • 现象

        并行运行时,大量的资源都创建失败了,原因是 DBError:Percona Xtradb Cluster 发现了死锁,事务需要重新开始。


        • 根本原因

        oslo.db 负责处理从数据库收到的错误,并传给相应的类处理。这样,如果发生类似的错误,数据库事务可以重新开始。但是 Percona 的给出的错误 oslo.db 没有正确处理。我们解决了这个问题之后,仍然经历了类似的错误,因为 Nova 代码中不是所有的数据库事务都能正确的重新启动。


        • 上游问题状态:已修复

        问题 由 Roman Podolyaka 修复CR,并backports 回了 Newton 版。它修复了 Percona 的死锁错误检测,但在 Nova 中至少还有一个地方仍然需要修复。



        3.9 live_migration_uri 的配置导致热迁移失败


        • 现象

        配置了 live_migration_uri 后,因为一个计算节点上的 libvirt 不能连接另一个计算节点上的,而导致热迁移失败。


        • 根本原因

        我们没有在 live_migration_uri 模板中指定使用 IP 地址,从而它试图用第一个网络接口的地址,而这是 PXE 网络的,不是 libvirt 监听的私有网络。live_migration_inbound_addr 可以解决这个问题,但因为上游 Nova 的一个问题我们不能使用。


        • 上游问题状态:已修复

        一个 Nova 的错误 已经被修复 移植回 了Newton 版。之后我们切换 到使用 live_migration_inbound_addr。



        UMCloud(上海优铭云计算有限公司)是一家中方控股的合资云计算公司,两大股东分别是中国顶尖的中立公有云服务商UCloud和全球排名第一的OpenStack云计算服务商Mirantis。公司成立于2016年,专注于私有云产品方案与服务、存储产品、Mirantis OpenStack培训等业务。

        了解更多资讯 关注官方微信

        声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

        路过

        雷人

        握手

        鲜花

        鸡蛋

        相关分类

        返回顶部