与任何 Kubernetes 集群一样,Google Distributed Cloud 集群可扩缩性具有许多相互关联的维度。本文档旨在帮助您了解可以在不中断工作负载的情况下通过调整来纵向扩容集群的关键维度。
了解限制
Google Distributed Cloud 是一个具有大型集成界面的复杂系统。影响集群可扩缩性的维度有很多。例如,节点数只是 Google Distributed Cloud 可以扩缩的多个维度之一。其他维度包括 Pod 总数和 Service 总数。其中许多维度(如每个节点的 pod 数和每个集群的节点数)是相互关联的。如需详细了解会影响可伸缩性的维度,请参阅 GitHub 上的 Kubernetes 社区代码库的“可伸缩性特别兴趣小组 (SIG)”部分中的 Kubernetes 可伸缩性阈值。
可扩缩性限制对集群运行所在的硬件和节点配置也极为敏感。本文档中所述的限制已在可能与您的环境不同的环境中经过验证。因此,当底层环境成为限制因素时,您可能无法重现相同的数字。
如需详细了解适用于 Google Distributed Cloud 集群的限制,请参阅配额和限制。
准备扩缩
在准备扩缩 Google Distributed Cloud 集群时,请考虑以下部分中所述的要求和限制。
控制平面节点的 CPU 和内存要求
下表概述了运行生产工作负载的集群的控制平面节点建议的 CPU 和内存配置:
集群节点数 | 推荐的控制平面 CPU | 推荐的控制平面内存 |
---|---|---|
1-50 | 8 核 | 32 GiB |
51 - 100 | 16 核 | 64 GiB |
Pod 和 Service 的数量
集群中可拥有的 Pod 和 Service 的数量由以下设置控制:
clusterNetwork.pods.cidrBlocks
用于指定集群中允许的 Pod 数量。nodeConfig.podDensity.maxPodsPerNode
指定可在单个节点上运行的最大 pod 数。clusterNetwork.services.cidrBlocks
用于指定集群中允许的 Service 数量。
Pod CIDR 和最大节点数
为集群中的 Pod 预留的 IP 地址总数是集群纵向扩容的限制因素之一。此设置以及每个节点的 Pod 数上限设置决定了您的集群中可以拥有的节点数上限,以免 Pod 的 IP 地址耗尽。
请考虑以下事项:
为集群中的 Pod 预留的 IP 地址总数由
clusterNetwork.pods.cidrBlocks
指定,后者采用 CIDR 表示法指定的 IP 地址范围。例如,预填充的值192.168.0.0/16
指定了从192.168.0.0
到192.168.255.255
的 65,536 个 IP 地址的范围。可在单个节点上运行的 Pod 数上限使用
nodeConfig.podDensity.maxPodsPerNode
指定。根据每个节点的最大 Pod 设置,Google Distributed Cloud 为节点预配大约两倍的 IP 地址。额外的 IP 地址有助于防止在短时间内不慎重复使用 Pod IP。
将 Pod IP 地址总数除以每个节点上预配的 Pod IP 地址数量,即可得到集群中可以拥有的节点总数。
例如,如果您的 Pod CIDR 为 192.168.0.0/17
,则您总共拥有 32,768 个 IP 地址(2(32-17) = 215 = 32,768)。如果您将每个节点的 Pod 数量上限设置为 250,Google Distributed Cloud 会预配大约 500 个 IP 地址的范围,这大致相当于一个 /23
CIDR 地址块 (2(32-23) = 29 = 512)。因此,在此示例中,最大节点数为 64(215 个地址/集群除以 29 个地址/节点 = 2(15-9) ) 个节点/集群 = 26 = 64 个节点/集群)。
clusterNetwork.pods.cidrBlocks
和 nodeConfig.podDensity.maxPodsPerNode
都是不可变的,因此请仔细规划集群的未来增长,以免用尽节点容量。如需了解每个集群的 Pod 数、每个节点的 Pod 数以及每个集群的节点数(基于测试)的建议最大值,请参阅限制。
服务 CIDR
在扩展集群时,您可以更新服务 CIDR 以添加更多服务。但是,您无法缩小 Service CIDR 范围。如需了解详情,请参阅扩大服务网络范围。
为系统守护程序预留的资源
默认情况下,Google Distributed Cloud 会自动在节点上为系统守护程序预留资源,例如 sshd
或 udev
。节点上的 CPU 和内存资源为系统守护程序预留,以便这些守护程序具有所需的资源。如果没有此功能,Pod 可能会消耗节点上的大部分资源,从而使系统守护程序无法完成其任务。
具体来说,Google Distributed Cloud 会在每个节点上为系统守护程序预留 80 millicore CPU (80 mCPU) 和 280 兆比字节 (280 MiB) 内存。请注意,CPU 单位 mCPU 代表核心的千分之一,因此每个节点上的核心的 80/1000(或 8%)会预留给系统守护程序。预留资源量很小,对 Pod 性能没有显著影响。但是,如果 Pod 使用 CPU 或内存的数量超过分配给它们的数量,则节点上的 kubelet 可能会逐出 Pod。
使用 MetalLB 进行网络连接
您可能需要增加 MetalLB 发言者数量,以解决以下方面的问题:
带宽:负载均衡服务的整个集群带宽取决于扬声器的数量和每个扬声器节点的带宽。网络流量增加需要更多扬声器。
容错性:增加扬声器数量可降低单个扬声器发生故障的总体影响。
MetalLB 需要负载均衡节点之间的第 2 层连接。在这种情况下,您可能会受到具有第 2 层连接的节点数量的限制,您可以在这些节点上放置 MetalLB 发言者。
仔细规划您希望在集群中使用多少个 MetalLB speaker,并确定您需要多少个第 2 层节点。如需了解详情,请参阅 MetalLB 可扩缩性问题。
使用捆绑式负载均衡模式时,控制平面节点还需要位于同一第 2 层网络下。手动负载均衡没有此限制。如需了解详情,请参阅手动负载均衡器模式。
运行多个节点、Pod 和服务
添加节点、Pod 和 Service 是一种扩展集群的方法。以下各部分介绍了在增加集群中的节点、Pod 和 Service 数量时应考虑的一些其他设置和配置。如需了解这些维度的限制以及它们之间的关系,请参阅限制。
创建不含 kube-proxy
的集群
如需创建可扩容以使用大量服务和端点的高性能集群,我们建议您在不使用 kube-proxy
的情况下创建集群。如果没有 kube-proxy
,集群会在 kube-proxy-replacementkube-proxy-replacement 模式下使用 GKE Dataplane V2。此模式可避免维护大量 iptables 规则所需的资源消耗。
您无法为现有集群停用 kube-proxy
。必须在创建集群时设置此配置。如需查看相关说明和更多信息,请参阅在不使用 kube-proxy 的情况下创建集群。
CoreDNS 配置
本部分介绍 CoreDNS 中会影响集群的可扩缩性的各个方面。
Pod DNS
默认情况下,Google Distributed Cloud 集群使用如下所示的 resolv.conf
注入 Pod:
nameserver KUBEDNS_CLUSTER_IP
search <NAMESPACE>.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_ID.internal google.internal
options ndots:5
选项 ndots:5
表示主机名中包含的点数少于 5 个,因此不被视为完全限定的域名 (FQDN)。DNS 服务器会在查找最初请求的主机名之前附加所有指定的搜索网域,该主机名在解析 google.com
时按如下方式排序:
google.com.NAMESPACE.svc.cluster.local
google.com.svc.cluster.local
google.com.cluster.local
google.com.c.PROJECT_ID.internal
google.com.google.internal
google.com
系统会针对 IPv4(A 记录)和 IPv6(AAAA 记录)执行每次查找,从而导致每个非 FQDN 查询有 12 个 DNS 请求,从而显著放大 DNS 流量。为了缓解此问题,我们建议您通过添加尾随点 (google.com.
) 将要查找的主机名声明为 FQDN。此声明需要在应用工作负载级别完成。如需了解详情,请参阅 resolv.conf
联机帮助页。
IPv6
如果集群未使用 IPv6,则可以通过消除对上游 DNS 服务器的 AAAA
记录查找来将 DNS 请求减少一半。如果您需要帮助来停用 AAAA
查询,请与 Cloud Customer Care 联系。
专用节点池
由于 DNS 查询在应用生命周期中至关重要,我们建议您为 coredns
Deployment 使用专用节点。此部署属于与普通应用不同的故障域。如果您在为 coredns
Deployment 设置专用节点时需要帮助,请与 Cloud Customer Care 联系。
MetalLB 可伸缩性问题
MetalLB 以主动-被动模式运行,这意味着在任何时候,都只有一个 MetalLB 扬声器为特定的 LoadBalancer
VIP 提供服务。
故障切换
在 Google Distributed Cloud 1.28.0 版之前,在大规模下,MetalLB 的故障切换可能需要很长时间,并可能会给集群带来可靠性风险。
连接限制
如果有特定的 LoadBalancer
VIP(例如 Ingress Service)预计将接近或超过 30000 个并发连接,则处理 VIP 的扬声器节点可能会耗尽可用的端口。由于架构限制,MetalLB 无法缓解此问题。在创建集群之前,请考虑改用使用 BGP 进行捆绑式负载均衡,或者使用其他入站流量类。如需了解详情,请参阅 Ingress 配置。
负载均衡器发言者
默认情况下,Google Distributed Cloud 会在控制平面和数据平面使用相同的负载均衡器节点池。如果您未指定负载均衡器节点池 (loadBalancer.nodePoolSpec
),则使用控制平面节点池 (controlPlane.nodePoolSpec
)。
如需在使用控制平面节点池进行负载均衡时增加扬声器的数量,您必须增加控制平面机器的数量。对于生产部署,我们建议您使用三个控制平面节点以实现高可用性。将控制平面节点的数量增加到 3 个以容纳额外的发言者可能不是对资源的充分利用。
入站流量配置
如果您预计将近 3 万个并发连接进入单个 LoadBalancer
Service VIP 地址,MetalLB 可能无法支持它。
您可以考虑通过其他机制(例如 F5 BIG-IP)公开 VIP。或者,您可以通过使用 BGP 的捆绑式负载均衡创建新集群,该集群不存在相同的限制。
微调 Cloud Logging 和 Cloud Monitoring 组件
在大型集群中,根据应用配置文件和流量模式,Cloud Logging 和 Cloud Monitoring 组件的默认资源配置可能不足以满足要求。如需了解如何调整可观测性组件的资源请求和限制,请参阅配置 Stackdriver 组件资源。
特别是,包含大量服务和端点的集群中的 kube-state-metrics 可能会导致 kube-state-metrics
本身和同一节点上的 gke-metrics-agent
的内存用量过高。指标服务器的资源使用量也可以根据节点、Pod 和服务进行扩缩。如果您在这些组件上遇到资源问题,请与
Cloud Customer Care 联系。
使用 sysctl 配置操作系统
我们建议您微调节点的操作系统配置,以最符合您的工作负载使用场景。控制 inotify 资源数量的 fs.inotify.max_user_watches
和 fs.inotify.max_user_instances
参数通常需要进行调整。例如,如果您看到如下错误消息,则可能需要尝试查看是否需要调整这些参数:
The configured user limit (128) on the number of inotify instances has been reached
ENOSPC: System limit for number of file watchers reached...
调整通常因工作负载类型和硬件配置而异。您可以咨询操作系统供应商,了解具体的操作系统最佳实践。
最佳做法
本部分介绍集群扩容的最佳做法。
一次缩放一个维度
为了最大限度地减少问题并更轻松地回滚更改,请勿同时调整多个维度。即使在较小的集群中,同时扩展多个维度也可能会导致问题。例如,尝试将每个节点调度的 Pod 数量增加到 110 个,同时将集群中的节点数量增加到 250 个可能不会成功,因为 Pod 的数量、每个节点的 Pod 数以及节点数将扩展得太多。
分阶段扩缩集群
扩容集群可能会消耗大量资源。为了降低集群操作失败或集群工作负载中断的风险,我们建议您不要尝试在单次操作中创建包含多个节点的大型集群。
创建不含工作节点的混合集群或独立集群
如果您要创建包含超过 50 个工作器节点的大型混合集群或独立集群,最好先创建包含控制平面节点的高可用性 (HA) 集群,然后逐步扩容。集群创建操作使用非高可用性引导集群,因此可靠性较低。高可用性混合集群或独立集群创建后,您可以使用该集群扩容到更多节点。
批量增加工作器节点数量
如果您要将集群扩展到更多工作节点,最好分阶段扩展。我们建议您一次最多添加 20 个节点。对于运行关键工作负载的集群,尤其如此。
启用并行映像拉取
默认情况下,kubelet 会依次拉取映像。如果与映像注册表服务器的上游连接错误,则错误的映像拉取可能会导致给定节点池的整个队列停滞。
为缓解此问题,我们建议您在自定义 kubelet 配置中将 serializeImagePulls
设置为 false
。如需查看相关说明和更多信息,请参阅配置 kubelet 映像拉取设置。
启用并行映像拉取可能会造成网络带宽或磁盘 I/O 消耗高峰。
微调应用资源请求和限制
在密集的环境中,应用工作负载可能会被移除。Kubernetes 会在发生驱逐时使用引用的机制对 Pod 进行排序。
设置容器资源的一个良好做法是为请求和限制使用相同数量的内存,并使用更大或无界限的 CPU 限制。如需了解详情,请参阅云架构中心中的准备云端 Kubernetes 应用。
使用存储合作伙伴
我们建议您使用某个 GDC Ready 存储合作伙伴进行大规模部署。 请务必与特定存储合作伙伴确认以下信息:
- 存储部署遵循存储方面(例如高可用性、优先级设置、节点亲和性以及资源请求和限制)的最佳做法。
- 存储版本符合特定的 Google Distributed Cloud 版本。
- 存储供应商可以支持您要部署的大规模。
配置集群以实现高可用性
审核大规模部署并确保关键组件尽可能配置为高可用性非常重要。Google Distributed Cloud 支持所有集群类型的 HA 部署选项。如需了解详情,请参阅选择部署模型。例如,如需查看高可用性部署的集群配置文件,请参阅集群配置示例。
审核其他组件也很重要,包括:
- 存储供应商
- 集群 webhook
监控资源使用情况
本部分为大规模集群提供了一些基本监控建议。
密切监控利用率指标
监控节点和各个系统组件的利用率并确保它们能够轻松安全地进行监控至关重要。如需查看默认提供的标准监控功能,请参阅使用预定义信息中心。
监控带宽消耗
密切监控带宽消耗,确保网络不会饱和,从而导致集群性能下降。
提升 etcd 性能
磁盘速度对 etcd 性能和稳定性至关重要。磁盘速度缓慢会增加 etcd 请求延迟时间,这可能会导致集群稳定性问题。为了提高集群性能,Google Distributed Cloud 将事件对象存储在单独的专用 etcd 实例中。标准 etcd 实例使用 /var/lib/etcd
作为其数据目录,使用端口 2379 处理客户端请求。etcd-events 实例使用 /var/lib/etcd-events
作为其数据目录,并使用端口 2382 处理客户端请求。
我们建议您将固态磁盘 (SSD) 用于 etcd 存储区。为了获得最佳性能,请将单独的磁盘装载到 /var/lib/etcd
和 /var/lib/etcd-events
。使用专用磁盘可确保两个 etcd 实例不共享磁盘 I/O。
etcd 文档提供了其他硬件建议,以确保在生产环境中运行集群时获得最佳 etcd 性能。
如需检查 etcd 和磁盘性能,请在 Metrics Explorer 中使用以下 etcd I/O 延迟时间指标:
etcd_disk_backend_commit_duration_seconds
:第 99 百分位 (p99) 的时长应少于 25 毫秒。etcd_disk_wal_fsync_duration_seconds
:第 99 百分位 (p99) 的时长应少于 10 毫秒。
如需详细了解 etcd 性能,请参阅 etcd 警告“应用条目时间过长”意味着什么?以及 etcd 警告“未能按时发出检测信号”意味着什么?。
如果您需要其他帮助,请与 Cloud Customer Care 联系。