K8s 集群 IP 地址管理指南
概述
你是否在小型初创公司或大型企业工作,并正在为公司评估 Kubernetes?你可能正在考虑运行十几个或更多的 Kubernetes (K8s) 集群。你期望每个集群支持几百个 K8s 节点,每个节点可能有 50 到 100 个 K8s Pod。这是否足以作为你的 IP 地址管理 (IPAM) 策略的一部分?那么K8s 服务 呢?你是否有运行在 K8s 之外的应用程序需要与 K8s 上的应用程序通信?反之亦然?
为了理解 K8s 集群的 IP 地址需求,我们首先深入了解它支持的网络模型及其背后的原因。
网络模型
-
所有 Pod 可以在同一集群内相互通信,无需 NAT
-
所有 Pod 可以与服务通信,无需 NAT
-
不应有 IP 重叠
上述网络模型提供了以下优势:
-
Pod 可移动性:每个 Pod 都有自己的 IP,该 IP 不与 Pod 运行的节点绑定。这意味着 Pod 可以移动到任何节点,而无需更改其 IP 或网络身份。
-
网络效率:由于 POD IP 有独立的、不重叠的 IP 块,Pod 之间可以相互通信,无需复杂的 NAT。
-
可重用的 POD IP:Pod 是短暂的。当 Pod 被删除时,其 IP 可以重新分配给另一个 Pod。
每个 K8s 集群所需的 CIDR 块
在了解了网络模型及其优势后,我们来看看 K8s 集群中需要 IP 的所有组件:
-
K8s 节点
-
K8s Pod
-
K8s 服务
-
外部 IP
-
入口 IP
运行 Pod 的 K8s 节点需要一个 IP,同样,每个运行在节点上的 Pod 也需要自己的 IP。
由于 K8s Pod 是短暂的,它们会被随机分配 IP。K8s 服务用于为 Pod 提供稳定的 IP。K8s 服务 IP 还充当无状态 Pod 的内部负载均衡器。
如果 Pod 位于外部负载均衡器(如 AWS ELB)后面,外部负载均衡器也需要 IP,如上文第 4 点所述。
如果 Pod 位于 Ingress 后面,Ingress 也需要外部 IP 块来暴露这些 HTTP/HTTPS 服务。这些 IP 通常也通过外部负载均衡器(如 AWS ELB)分配。
K8s 集群中 CIDR 块的配置方式
本节假设你熟悉 K8s 集群的组件。我们来看看 K8s 的四个重要部分的配置,了解它们如何使用各种 CIDR:
kube-apiserver \--service-cluster-ip-range=10.96.0.0/12 \ # 服务 CIDR--service-node-port-range=30000-32767 \ # NodePort 范围--allow-privileged=true \--apiserver-count=3 \ # 用于高可用设置--bind-address=0.0.0.0 \--secure-port=6443 \--feature-gates=RemoveSelfLink=false
kube-controller-manager \--cluster-cidr=10.244.0.0/16 \ # Pod CIDR--service-cluster-ip-range=10.96.0.0/12 \ # 必须与 apiserver 匹配--node-cidr-mask-size=24 \ # 每个节点的子网大小--allocate-node-cidrs=true \--cluster-name=kubernetes \--controllers=*,bootstrapsigner,tokencleaner
kubelet \--pod-cidr=10.244.1.0/24 \ # 节点特定的 Pod CIDR--node-ip=192.168.1.10 \ # 节点的物理 IP--cluster-dns=10.96.0.10 \ # kube-dns 服务 IP--cluster-domain=cluster.local \--network-plugin=cni \--cni-conf-dir=/etc/cni/net.d \--cni-bin-dir=/opt/cni/bin
kube-proxy \--cluster-cidr=10.244.0.0/16 \ # Pod CIDR--proxy-mode=ipvs \ # 或 iptables--ipvs-min-sync-period=5s \--ipvs-sync-period=30s
你会注意到 K8s 服务 CIDR 在两个地方指定:kube-apiserver 和 kube-controller-manager,作为命令行参数 _— service-cluster-ip-range_,并且两者必须相同。这是用于分配ClusterIP 类型的 K8s 服务的 IP 地址块。
— cluster-cidr 在 kube-controller-manager 和 kube-proxy 中指定。此 CIDR 块用于分配集群中所有 K8s Pod 的 IP 地址。
此外,每个节点的 POD CIDR 作为命令行参数— pod-cidr 传递给 kubelet。kubelet 使用此 IP 地址块为运行在其所在节点上的 Pod 分配 IP。此块必须来自— cluster-cidr 指定的超块。
CNI 和 IPAM
上述讨论假设 IP 地址通过直接配置 K8s 组件来管理。通常,Kubernetes 集群使用 CNI(容器网络接口)模块来实现网络模型。CNI 主要负责:
-
POD IP 分配(接管或覆盖— pod-cidr 和 _— cluster-cidr_)
-
Pod 之间的连接
-
控制哪些 Pod 可以与哪些其他 Pod 通信的网络策略
CNI 还可以用于与企业现有的 IPAM 系统集成或创建自定义 IP 分配策略。
K8s 集群 IP 地址管理的其他注意事项
我想以一些 IP 地址管理的额外考虑结束本文,这些内容我们之前没有涵盖,但在你扩展 Kubernetes 使用时(无论是在本地还是在云中)至关重要。
-
节点本地 IPAM https://www.cni.dev/plugins/current/ipam/host-local/:Kubernetes 现在支持节点本地 IPAM,允许每个节点管理自己的 IP 池。这减少了 API 服务器负载并提高了 Pod 启动时间。这在大型集群中特别有用,因为集中式 IPAM 可能成为瓶颈。
-
双栈考虑 https://kubernetes.io/docs/concepts/services-networking/dual-stack/:每个 Pod 可以同时获得 IPv4 和 IPv6 地址。我们需要确保为两种协议提供足够的地址空间。
-
Pod IP 范围耗尽:这通常被忽视,直到成为问题。我们需要考虑 Pod 的流失率和集群扩展计划。监控 IP 地址利用率很重要。最好设置 IP 池耗尽的警报。
-
地址回收:需要为终止的 Pod 进行适当的垃圾回收。一些 CNI 插件有不同的等待期。这对于防止 IP 冲突很重要。
-
多集群考虑:我们需要确保集群之间的 Pod 和服务 CIDR 不重叠。这对于集群联邦和跨集群通信很重要。我们还应考虑未来集群合并的场景。此外,我们还没有讨论跨多个集群的网格,这带来了额外的 IP 寻址考虑。
-
云提供商集成:不同的云提供商有不同的 IPAM 限制。一些云提供商需要特定的 CIDR 范围,可能需要与云 VPC IPAM 协调。例如,EKS 支持自定义网络,并允许为节点上的 Pod 使用不同的子网。
-
安全考虑:IPAM 也可用于网络分段。考虑为不同的安全区域使用不同的 IP 范围。这对于合规性要求很重要。
这并不详尽,但希望我已经涵盖了从扩展公司 Kubernetes 策略和运行基于我过去八年运行生产就绪集群的角度来看的所有 IP 地址管理方面。