本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.24:避免为服务分配 IP 地址时发生冲突

在 Kubernetes 中,Service 是一种抽象方式,用于暴露在一组 Pod 上运行的应用程序。Service 可以拥有集群范围的虚拟 IP 地址(使用 type: ClusterIP 的 Service)。客户端可以使用该虚拟 IP 地址连接,然后 Kubernetes 会将流量负载均衡到该 Service 的不同后端 Pod。

Service ClusterIP 如何分配?

Service ClusterIP 可以被分配

动态地
集群的控制平面会自动从为 type: ClusterIP Service 配置的 IP 范围内选择一个空闲的 IP 地址。
静态地
您从为 Service 配置的 IP 范围内指定一个您选择的 IP 地址。

在整个集群中,每个 Service ClusterIP 都必须是唯一的。尝试创建具有已分配特定 ClusterIP 的 Service 将返回错误。

为什么需要保留 Service Cluster IP?

有时您可能希望 Service 在众所周知的 IP 地址上运行,以便集群中的其他组件和用户可以使用它们。

最好的例子是集群的 DNS Service。一些 Kubernetes 安装程序会将 Service IP 范围中的第 10 个地址分配给 DNS 服务。假设您为集群配置的 Service IP 范围是 10.96.0.0/16,并且您希望 DNS Service IP 是 10.96.0.10,那么您必须像这样创建 Service

apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: CoreDNS
  name: kube-dns
  namespace: kube-system
spec:
  clusterIP: 10.96.0.10
  ports:
  - name: dns
    port: 53
    protocol: UDP
    targetPort: 53
  - name: dns-tcp
    port: 53
    protocol: TCP
    targetPort: 53
  selector:
    k8s-app: kube-dns
  type: ClusterIP

但正如我之前解释的,IP 地址 10.96.0.10 并未被保留;如果在动态分配之前或同时创建其他 Service,它们有可能分配此 IP,因此,您将无法创建 DNS Service,因为它将因冲突错误而失败。

如何避免 Service ClusterIP 冲突?

在 Kubernetes 1.24 中,您可以启用一个新的特性门控 ServiceIPStaticSubrange。启用此功能允许您对 Service 使用不同的 IP 分配策略,从而降低冲突风险。

ClusterIP 范围将根据公式 min(max(16, cidrSize / 16), 256) 进行划分,描述为*永不小于 16 或大于 256,两者之间有分级步长*。

动态 IP 分配将默认使用高位段,一旦高位段用尽,将使用低位段。这将允许用户在低位段使用静态分配,从而降低冲突风险。

示例

Service IP CIDR 块:10.96.0.0/24

范围大小:28 - 2 = 254
分段偏移:min(max(16, 256/16), 256) = min(16, 256) = 16
静态段起始:10.96.0.1
静态段结束:10.96.0.16
范围结束:10.96.0.254

饼图显示数据 标题 10.96.0.0/24 "静态":16 "动态":238

Service IP CIDR 块:10.96.0.0/20

范围大小:212 - 2 = 4094
分段偏移:min(max(16, 4096/16), 256) = min(256, 256) = 256
静态段起始:10.96.0.1
静态段结束:10.96.1.0
范围结束:10.96.15.254

饼图显示数据 标题 10.96.0.0/20 "静态":256 "动态":3838

Service IP CIDR 块:10.96.0.0/16

范围大小:216 - 2 = 65534
分段偏移:min(max(16, 65536/16), 256) = min(4096, 256) = 256
静态段起始:10.96.0.1
静态段结束:10.96.1.0
范围结束:10.96.255.254

饼图显示数据 标题 10.96.0.0/16 "静态":256 "动态":65278

参与 SIG Network

当前的 SIG-Network KEPs 和 GitHub 上的议题展示了 SIG 的重点领域。

SIG Network 会议是一个友好、开放的平台,供您与社区联系并分享您的想法。期待您的加入!