本文发表时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.24:避免为 Service 分配 IP 地址时发生冲突
在 Kubernetes 中,服务是一种抽象的方式,用于暴露在 Pod 集合上运行的应用程序。服务可以使用集群范围的虚拟 IP 地址(使用 type: ClusterIP
的服务)。客户端可以使用该虚拟 IP 地址进行连接,然后 Kubernetes 将流量负载均衡到该服务的所有后端 Pod。
如何分配 Service ClusterIP?
Service ClusterIP
可以被分配为
- 动态
- 集群的控制平面会自动从为
type: ClusterIP
服务配置的 IP 范围内选择一个空闲 IP 地址。 - 静态
- 您可以从为服务配置的 IP 范围内指定您选择的 IP 地址。
在您的整个集群中,每个 Service ClusterIP
都必须是唯一的。尝试使用已分配的特定 ClusterIP
创建服务将返回错误。
为什么需要预留 Service Cluster IP?
有时,您可能希望服务在众所周知的 IP 地址中运行,以便集群中的其他组件和用户可以使用它们。
最好的例子是集群的 DNS 服务。一些 Kubernetes 安装程序将服务 IP 范围内的第 10 个地址分配给 DNS 服务。假设您使用服务 IP 范围 10.96.0.0/16 配置了集群,并且您希望您的 DNS 服务 IP 为 10.96.0.10,则您必须创建如下服务
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 尚未保留;如果在动态分配之前或同时创建了其他服务,则它们有可能分配此 IP,因此您将无法创建 DNS 服务,因为它将因冲突错误而失败。
如何避免 Service ClusterIP 冲突?
在 Kubernetes 1.24 中,您可以启用新的特性门 ServiceIPStaticSubrange
。启用此功能后,您可以使用不同的 IP 分配策略来分配服务,从而降低冲突的风险。
ClusterIP
范围将根据公式 min(max(16, cidrSize / 16), 256)
进行划分,表示为永远不小于 16 或大于 256,并且它们之间具有渐进的步长。
动态 IP 分配默认将使用上限范围,一旦此范围耗尽,它将使用下限范围。这将允许用户在下限范围中使用静态分配,而冲突的风险较低。
示例
服务 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
服务 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
服务 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
参与 SIG 网络
GitHub 上当前的 SIG-Network KEP 和 问题说明了 SIG 的重点领域。
SIG 网络会议是一个友好且受欢迎的场所,您可以与社区联系并分享您的想法。期待收到您的来信!