为 Google Distributed Cloud 集群扩容

与任何 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 的数量由以下设置控制:

Pod CIDR 和节点数上限

为集群中的 Pod 预留的 IP 地址总数是集群纵向扩容的限制因素之一。此设置与每个节点的 Pod 数量上限设置相结合,决定了您的集群中可以拥有的节点数上限,以免 Pod 耗尽 IP 地址。

请考虑以下事项:

  • 为集群中的 Pod 预留的 IP 地址总数由 clusterNetwork.pods.cidrBlocks 指定,它接受以 CIDR 表示法指定的一系列 IP 地址。例如,预填充的值 192.168.0.0/16 指定从 192.168.0.0192.168.255.255 的 65536 个 IP 地址范围。

  • 可以在单个节点上运行的最大 Pod 数量由 nodeConfig.podDensity.maxPodsPerNode 指定。

  • 根据每个节点的最大 Pod 数量设置,Google Distributed Cloud 会为节点预配大约两倍的 IP 地址。额外的 IP 地址有助于防止在短时间内无意间重复使用 Pod IP。

  • 用 Pod IP 地址总数除以每个节点上预配的 Pod IP 地址数,即可得到集群中可以拥有的节点总数。

例如,如果您的 Pod CIDR 为 192.168.0.0/17,则您总共有 32768 个 IP 地址 (2(32-17) = 215 = 32768)。如果您将每个节点的 Pod 数上限设置为 250,则 Google Distributed Cloud 会预配约 500 个 IP 地址范围,这大致相当于 /23 CIDR 地址块 (2(32-23) = 29 = 512)。因此在本例中的最大节点数为 64(215 个地址/集群除以 29 个地址/节点 = 2(15-9) 个节点/集群 = 26 = 64 个节点/集群)。

clusterNetwork.pods.cidrBlocksnodeConfig.podDensity.maxPodsPerNode 都是不可变的,因此请仔细规划集群将来的发展,以免耗尽节点容量。如需了解基于测试建议的每个集群的 Pod 数、每个节点的 Pod 数以及每个集群的节点数上限,请参阅限制

服务 CIDR

在对集群进行纵向扩容时,可以更新 Service CIDR 以添加更多 Service。但是,您无法减小服务 CIDR 范围。如需了解详情,请参阅扩大服务网络范围

为系统守护程序预留的资源

默认情况下,Google Distributed Cloud 会在节点上自动为系统守护程序(例如 sshdudev)预留资源。CPU 和内存资源会在节点上为系统守护程序预留,以便这些守护程序获得其所需的资源。如果没有此功能,Pod 可能会使用节点上的大部分资源,导致系统守护程序无法完成其任务。

具体而言,Google Distributed Cloud 会在每个节点上为系统守护程序预留 80 millicore 的 CPU (80 mCPU) 和 280 MiB (280 MiB) 的内存。请注意,CPU 单位 mCPU 代表核心的千分之一,因此每个节点上核心的 80/1000 或 8% 会预留给系统守护程序。预留资源量很小,对 Pod 性能没有明显影响。但是,如果节点上的 kubelet 的 CPU 或内存用量超出了分配给它们的数量,则节点上的 kubelet 可能会逐出 Pod。

使用 MetalLB 连接到网络

您可能需要增加 MetalLB 音箱的数量,以解决以下问题:

  • 带宽:用于负载均衡服务的整个集群带宽取决于扬声器数量和每个扬声器节点的带宽。网络流量增加,需要更多扬声器。

  • 容错能力:扬声器越多,单个扬声器故障的整体影响就越小。

MetalLB 需要在负载均衡节点之间建立第 2 层连接。在这种情况下,您可能受具有第 2 层连接的节点数量的限制,可以在该节点上放置 MetalLB 音箱。

仔细规划您希望在集群中拥有多少个 MetalLB 音箱,并确定您需要多少个第 2 层节点。如需了解详情,请参阅 MetalLB 可伸缩性问题

另外,使用捆绑式负载均衡模式时,控制平面节点也需要位于同一第 2 层网络下。手动负载均衡没有此限制。如需了解详情,请参阅手动负载均衡器模式

运行多个节点、Pod 和服务

添加节点、Pod 和 Service 是对集群进行纵向扩容的一种方式。以下部分介绍了在增加集群中的节点、Pod 和 Service 数量时应考虑的一些其他设置和配置。如需了解这些维度的限制以及它们之间的相互关系,请参阅限制

创建不含 kube-proxy 的集群

如需创建可纵向扩容以使用大量服务和端点的高性能集群,我们建议您在不使用 kube-proxy 的情况下创建集群。如果没有 kube-proxy,集群将在 kube-proxy-replacement 模式下使用 GKE Dataplane V2。此模式可避免维护大量 iptables 规则所需的资源消耗量。

您无法为现有集群停用 kube-proxy。此配置必须在创建集群时进行设置。如需了解相关说明和更多信息,请参阅在不使用 kube-proxy 的情况下创建集群

CoreDNS 配置

本部分介绍影响集群可伸缩性的 CoreDNS 的各个方面。

Pod DNS

默认情况下,Google Distributed Cloud 集群会注入如下所示的 resolv.conf

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 时按如下方式对查询进行排序:

  1. google.com.NAMESPACE.svc.cluster.local
  2. google.com.svc.cluster.local
  3. google.com.cluster.local
  4. google.com.c.PROJECT_ID.internal
  5. google.com.google.internal
  6. 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 使用专用节点。此 Deployment 属于与普通应用不同的故障域。如果您在为 coredns Deployment 设置专用节点方面需要帮助,请与 Cloud Customer Care 联系。

MetalLB 可伸缩性问题

MetalLB 以主动-被动模式运行,这意味着在任何时候,都只有一个 MetalLB 扬声器为特定的 LoadBalancer VIP 提供服务。

故障切换

在 Google Distributed Cloud 1.28.0 版之前的大规模处理下,MetalLB 的故障切换可能需要很长时间,并可能给集群带来可靠性风险。

连接限制

如果存在预计接近或超过 3 万个并发连接的特定 LoadBalancer VIP(例如 Ingress Service),则负责处理此 VIP 的扬声器节点可能会耗尽可用端口。由于架构限制, MetalLB 无法缓解此问题。请考虑在创建集群之前切换到使用 BGP 的捆绑式负载均衡,或使用其他入站流量类。如需了解详情,请参阅 Ingress 配置

负载平衡器音箱

默认情况下,Google Distributed Cloud 为控制平面和数据平面使用相同的负载均衡器节点池。如果未指定负载均衡器节点池 (loadBalancer.nodePoolSpec),则使用控制平面节点池 (controlPlane.nodePoolSpec)。

如需在使用控制平面节点池进行负载均衡时增加音箱数量,您必须增加控制平面机器的数量。对于生产部署,我们建议您使用三个控制平面节点以实现高可用性。将控制平面节点的数量增加到三个以上来容纳更多扬声器可能并不充分地利用您的资源。

入站流量配置

如果您预计将近 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 上的同一节点上的内存用量过高。Metrics-server 的资源使用量也可以从节点、Pod 和 Service 方面扩缩。如果您在这些组件上遇到资源问题,请与 Cloud Customer Care 联系。

使用 sysctl 配置操作系统

我们建议您为节点微调操作系统配置,使其最适合您的工作负载使用场景。控制 inotify 资源数量的 fs.inotify.max_user_watchesfs.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 应用

使用存储合作伙伴

我们建议您通过某个 GDCV Ready 存储合作伙伴进行大规模部署。请务必与特定存储合作伙伴确认以下信息:

  • 存储部署遵循存储方面的最佳实践,例如高可用性、优先级设置、节点亲和性以及资源请求和限制。
  • 存储版本取决于特定的 Google Distributed Cloud 版本。
  • 存储供应商可支持您要部署的大规模应用。

配置集群以实现高可用性

请务必审核您的大规模部署,并确保尽可能对关键组件进行高可用性配置。Google Distributed Cloud 支持所有集群类型的高可用性部署选项。如需了解详情,请参阅选择部署模型。如需查看高可用性部署的集群配置文件示例,请参阅集群配置示例

审核其他组件也很重要,包括:

  • 存储服务供应商
  • 集群 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 警告“apply entries take too long”是什么意思?etcd 警告“failed to send out heartbeat on time”是什么意思?

如果您需要其他帮助,请与 Cloud Customer Care 联系。

后续步骤