扩展 Service IP 范围

功能状态: Kubernetes v1.31 [beta] (默认禁用:false)

本文档介绍了如何扩展分配给集群的现有服务 IP 范围。

准备开始

你需要一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群进行通信。建议在至少有两个非控制平面主机节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个集群,也可以使用以下 Kubernetes 游乐场之一

你的 Kubernetes 服务器必须是 v1.29 或更高版本。要检查版本,请输入 kubectl version

API

启用了 MultiCIDRServiceAllocator 特性门控并且激活了 networking.k8s.io/v1beta1 API 组的 kube-apiservers 的 Kubernetes 集群,将创建一个 ServiceCIDR 对象,该对象采用众所周知的名称 kubernetes,并根据 kube-apiserver 的 --service-cluster-ip-range 命令行参数的值指定 IP 地址范围。

kubectl get servicecidr
NAME         CIDRS          AGE
kubernetes   10.96.0.0/28   17d

众所周知的 kubernetes 服务,将 kube-apiserver 端点暴露给 Pods,它从默认的 ServiceCIDR 范围计算第一个 IP 地址,并将该 IP 地址用作其集群 IP 地址。

kubectl get service kubernetes
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   17d

在这种情况下,默认服务使用 ClusterIP 10.96.0.1,它具有相应的 IPAddress 对象。

kubectl get ipaddress 10.96.0.1
NAME        PARENTREF
10.96.0.1   services/default/kubernetes

ServiceCIDR 受终结器保护,以避免留下 Service ClusterIP 孤立;仅当存在包含现有 IPAddress 的另一个子网或不存在属于该子网的 IPAddress 时,才会删除终结器。

扩展可用于服务的 IP 数量

在某些情况下,用户将需要增加可用于服务的地址数量,以前,增加服务范围是一项破坏性操作,也可能导致数据丢失。有了这个新功能,用户只需要添加一个新的 ServiceCIDR 即可增加可用地址的数量。

添加新的 ServiceCIDR

在服务范围为 10.96.0.0/28 的集群上,只有 2^(32-28) - 2 = 14 个 IP 地址可用。始终创建 kubernetes.default 服务;对于此示例,这会使你只有 13 个可能的服务。

for i in $(seq 1 13); do kubectl create service clusterip "test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.11
10.96.0.5
10.96.0.12
10.96.0.13
10.96.0.14
10.96.0.2
10.96.0.3
10.96.0.4
10.96.0.6
10.96.0.7
10.96.0.8
10.96.0.9
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full

你可以通过创建新的 ServiceCIDR 来增加可用于服务的 IP 地址数量,该 ServiceCIDR 扩展或添加新的 IP 地址范围。

cat <EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: ServiceCIDR
metadata:
  name: newcidr1
spec:
  cidrs:
  - 10.96.0.0/24
EOF
servicecidr.networking.k8s.io/newcidr1 created

这将允许你创建新的服务,其 ClusterIP 将从此新范围中选择。

for i in $(seq 13 16); do kubectl create service clusterip "test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.48
10.96.0.200
10.96.0.121
10.96.0.144

删除 ServiceCIDR

如果存在依赖于 ServiceCIDR 的 IPAddress,则无法删除 ServiceCIDR。

kubectl delete servicecidr newcidr1
servicecidr.networking.k8s.io "newcidr1" deleted

Kubernetes 在 ServiceCIDR 上使用终结器来跟踪这种依赖关系。

kubectl get servicecidr newcidr1 -o yaml
apiVersion: networking.k8s.io/v1beta1
kind: ServiceCIDR
metadata:
  creationTimestamp: "2023-10-12T15:11:07Z"
  deletionGracePeriodSeconds: 0
  deletionTimestamp: "2023-10-12T15:12:45Z"
  finalizers:
  - networking.k8s.io/service-cidr-finalizer
  name: newcidr1
  resourceVersion: "1133"
  uid: 5ffd8afe-c78f-4e60-ae76-cec448a8af40
spec:
  cidrs:
  - 10.96.0.0/24
status:
  conditions:
  - lastTransitionTime: "2023-10-12T15:12:45Z"
    message: There are still IPAddresses referencing the ServiceCIDR, please remove
      them or create a new ServiceCIDR
    reason: OrphanIPAddress
    status: "False"
    type: Ready

通过删除包含阻止删除 ServiceCIDR 的 IP 地址的服务

for i in $(seq 13 16); do kubectl delete service "test-$i" ; done
service "test-13" deleted
service "test-14" deleted
service "test-15" deleted
service "test-16" deleted

控制平面会注意到该删除操作。然后,控制平面会删除其终结器,以便实际删除正在等待删除的 ServiceCIDR。

kubectl get servicecidr newcidr1
Error from server (NotFound): servicecidrs.networking.k8s.io "newcidr1" not found
上次修改时间:2024 年 11 月 30 日上午 7:15 PST: 更新 content/en/docs/tasks/network/extend-service-ip-ranges.md (96935b6d75)