网络
- 1: 使用 HostAliases 向 Pod /etc/hosts 文件添加条目
- 2: 扩展 Service IP 范围
- 3: 验证 IPv4/IPv6 双协议栈
- 4: 重新配置 Kubernetes 默认的 Service CIDR
1 - 使用 HostAliases 向 Pod /etc/hosts 文件添加条目
当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts
文件中添加条目,
可以在 Pod 级别覆盖对主机名的解析。你可以通过 PodSpec 的 HostAliases
字段来添加这些自定义条目。
Kubernetes 项目建议使用 hostAliases
字段(Pod .spec
的一部分)来修改 DNS 配置,
而不是通过使用 Init 容器或其他方式直接编辑 /etc/hosts
。
以其他方式所做的更改可能会在 Pod 创建或重启过程中被 kubelet 重写。
默认 hosts 文件内容
让我们从一个 Nginx Pod 开始,该 Pod 被分配一个 IP:
kubectl run nginx --image nginx
pod/nginx created
检查 Pod IP:
kubectl get pods --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
hosts 文件的内容如下所示:
kubectl exec nginx -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.200.0.4 nginx
默认情况下,hosts
文件只包含 IPv4 和 IPv6 的样板内容,像 localhost
和主机名称。
通过 HostAliases 增加额外条目
除了默认的样板内容,你可以向 hosts
文件添加额外的条目。
例如,要将 foo.local
、bar.local
解析为 127.0.0.1
,
将 foo.remote
、 bar.remote
解析为 10.1.2.3
,你可以在
.spec.hostAliases
下为 Pod 配置 HostAliases。
apiVersion: v1
kind: Pod
metadata:
name: hostaliases-pod
spec:
restartPolicy: Never
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "foo.local"
- "bar.local"
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
containers:
- name: cat-hosts
image: busybox:1.28
command:
- cat
args:
- "/etc/hosts"
你可以使用以下命令用此配置启动 Pod:
kubectl apply -f https://k8s.io/examples/service/networking/hostaliases-pod.yaml
pod/hostaliases-pod created
检查 Pod 详情,查看其 IPv4 地址和状态:
kubectl get pod --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
hostaliases-pod 0/1 Completed 0 6s 10.200.0.5 worker0
hosts
文件的内容看起来类似如下所示:
kubectl logs hostaliases-pod
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.200.0.5 hostaliases-pod
# Entries added by HostAliases.
127.0.0.1 foo.local bar.local
10.1.2.3 foo.remote bar.remote
在最下面额外添加了一些条目。
为什么 kubelet 管理 hosts 文件?
kubelet 管理每个Pod 容器的 hosts
文件,以防止容器运行时在容器已经启动后修改文件。
由于历史原因,Kubernetes 总是使用 Docker Engine 作为其容器运行时,而 Docker Engine
将在容器启动后修改 /etc/hosts
文件。
当前的 Kubernetes 可以使用多种容器运行时;即便如此,kubelet 管理在每个容器中创建 hosts文件, 以便你使用任何容器运行时运行容器时,结果都符合预期。
注意:
请避免手工更改容器内的 hosts 文件内容。
如果你对 hosts 文件做了手工修改,这些修改都会在容器退出时丢失。
2 - 扩展 Service IP 范围
Kubernetes v1.33 [stable]
(enabled by default: true)
This is a stable feature in Kubernetes, and has been since version 1.33. It was first available in the v1.27 release.
本文将介绍如何扩展分配给集群的现有 Service IP 范围。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 v1.29.要获知版本信息,请输入 kubectl version
.
说明:
虽然你可以在更早的版本中使用此特性,但此特性只有从 v1.33 版本开始才进阶至 GA(正式发布)并获得官方支持。
扩展 Service IP 范围
如果 Kubernetes 集群的 kube-apiserver 启用了 MultiCIDRServiceAllocator
特性门控且激活了
networking.k8s.io/v1beta1
API 组,集群将创建一个新的 ServiceCIDR 对象,
该对象采用 kubernetes
这个众所周知的名称并基于 kube-apiserver 的 --service-cluster-ip-range
命令行参数的值来使用 IP 地址范围。
kubectl get servicecidr
NAME CIDRS AGE
kubernetes 10.96.0.0/28 17d
公认的 kubernetes
Service 将 kube-apiserver 的端点暴露给 Pod,
计算出默认 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
在本例中,默认 Service 使用具有对应 IPAddress 对象的 ClusterIP 10.96.0.1。
kubectl get ipaddress 10.96.0.1
NAME PARENTREF
10.96.0.1 services/default/kubernetes
ServiceCIDR 受到 终结器 的保护, 以避免留下孤立的 Service ClusterIP;只有在存在包含现有 IPAddress 的另一个子网或者没有属于此子网的 IPAddress 时,才会移除终结器。
扩展 Service 可用的 IP 数量
有时候用户需要增加可供 Service 使用的 IP 地址数量。 以前,增加 Service 范围是一个可能导致数据丢失的破坏性操作。 有了这个新的特性后,用户只需添加一个新的 ServiceCIDR 对象,便能增加可用地址的数量。
添加新的 ServiceCIDR
对于 Service 范围为 10.96.0.0/28 的集群,只有 2^(32-28) - 2 = 14 个可用的 IP 地址。
kubernetes.default
Service 始终会被创建;在这个例子中,你只剩下了 13 个可能的 Service。
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
通过创建一个扩展或新增 IP 地址范围的新 ServiceCIDR,你可以提高 Service 可用的 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
这将允许你创建新的 Service,其 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
移除一些 Service,这些 Service 包含阻止删除 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
Kubernetes Service CIDR 策略
集群管理员可以实现策略来控制集群中 ServiceCIDR 资源的创建和修改。 这允许集中管理 Service 所使用的 IP 地址范围,有助于防止意外或冲突的配置。 Kubernetes 提供如验证准入策略(Validating Admission Policy)等机制来强制执行这些规则。
使用验证准入策略阻止未授权的 ServiceCIDR 创建或更新
在某些情况下,集群管理员可能希望限制允许的 IP 范围,或完全禁止对集群 Service IP 范围的更改。
说明:
默认的 "kubernetes" ServiceCIDR 是由 kube-apiserver 创建的,用于在集群中保证一致性,
并且是集群正常运行所必需的,因此必须始终被允许。你可以通过在 ValidatingAdmissionPolicy
中添加以下条件来确保不会限制默认的 ServiceCIDR:
matchConditions:
- name: 'exclude-default-servicecidr'
expression: "object.metadata.name != 'kubernetes'"
如下例所示。
限制 Service CIDR 范围为某些特定范围
以下是一个 ValidatingAdmissionPolicy
的示例,它只允许在给定的 allowed
范围内的子范围创建 ServiceCIDR。
(因此示例的策略允许 ServiceCIDR 使用 cidrs: ['10.96.1.0/24']
或
cidrs: ['2001:db8:0:0:ffff::/80', '10.96.0.0/20']
,但不允许 cidrs: ['172.20.0.0/16']
。)
你可以复制此策略,并将 allowed
的值更改为适合你集群的取值。
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "servicecidrs.default"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1","v1beta1"]
operations: ["CREATE", "UPDATE"]
resources: ["servicecidrs"]
matchConditions:
- name: 'exclude-default-servicecidr'
expression: "object.metadata.name != 'kubernetes'"
variables:
- name: allowed
expression: "['10.96.0.0/16','2001:db8::/64']"
validations:
- expression: "object.spec.cidrs.all(newCIDR, variables.allowed.exists(allowedCIDR, cidr(allowedCIDR).containsCIDR(newCIDR)))"
# 对提交的 ServiceCIDR 对象的 spec.cidrs 中列出的所有 CIDR(newCIDR),
# 检查 VAP 的 `allowed` 列表中是否至少存在一个 CIDR(allowedCIDR),
# 使 allowedCIDR 完全包含 newCIDR。
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "servicecidrs-binding"
spec:
policyName: "servicecidrs.default"
validationActions: [Deny,Audit]
如果你想要编写自己的验证 expression
,参阅 CEL 文档以了解更多信息。
限制任何对 ServiceCIDR API 的使用
以下示例展示了如何使用 ValidatingAdmissionPolicy
及其绑定,
来限制创建任何新的 Service CIDR 范围,但不包括默认的 "kubernetes" ServiceCIDR:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "servicecidrs.deny"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1","v1beta1"]
operations: ["CREATE", "UPDATE"]
resources: ["servicecidrs"]
validations:
- expression: "object.metadata.name == 'kubernetes'"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "servicecidrs-deny-binding"
spec:
policyName: "servicecidrs.deny"
validationActions: [Deny,Audit]
3 - 验证 IPv4/IPv6 双协议栈
本文分享了如何验证 IPv4/IPv6 双协议栈的 Kubernetes 集群。
准备开始
你的 Kubernetes 服务器版本必须不低于版本 v1.23.要获知版本信息,请输入 kubectl version
.
说明:
虽然你可以使用较早的版本进行验证,但该功能是从 v1.23 版本进入 GA 状态并正式支持的。
验证寻址
验证节点寻址
每个双协议栈节点应分配一个 IPv4 块和一个 IPv6 块。
通过运行以下命令来验证是否配置了 IPv4/IPv6 Pod 地址范围。
将示例节点名称替换为集群中的有效双协议栈节点。
在此示例中,节点的名称为 k8s-linuxpool1-34450317-0
:
kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}'
10.244.1.0/24
2001:db8::/64
应该分配一个 IPv4 块和一个 IPv6 块。
验证节点是否检测到 IPv4 和 IPv6 接口。用集群中的有效节点替换节点名称。
在此示例中,节点名称为 k8s-linuxpool1-34450317-0
:
kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s\n" .type .address}}{{end}}'
Hostname: k8s-linuxpool1-34450317-0
InternalIP: 10.0.0.5
InternalIP: 2001:db8:10::5
验证 Pod 寻址
验证 Pod 已分配了 IPv4 和 IPv6 地址。用集群中的有效 Pod 替换 Pod 名称。
在此示例中,Pod 名称为 pod01
:
kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}'
10.244.1.4
2001:db8::4
你也可以通过 status.podIPs
使用 Downward API 验证 Pod IP。
以下代码段演示了如何通过容器内称为 MY_POD_IPS
的环境变量公开 Pod 的 IP 地址。
env:
- name: MY_POD_IPS
valueFrom:
fieldRef:
fieldPath: status.podIPs
使用以下命令打印出容器内部 MY_POD_IPS
环境变量的值。
该值是一个逗号分隔的列表,与 Pod 的 IPv4 和 IPv6 地址相对应。
kubectl exec -it pod01 -- set | grep MY_POD_IPS
MY_POD_IPS=10.244.1.4,2001:db8::4
Pod 的 IP 地址也将被写入容器内的 /etc/hosts
文件中。
在双栈 Pod 上执行 cat /etc/hosts
命令操作。
从输出结果中,你可以验证 Pod 的 IPv4 和 IPv6 地址。
kubectl exec -it pod01 -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.4 pod01
2001:db8::4 pod01
验证服务
创建以下未显式定义 .spec.ipFamilyPolicy
的 Service。
Kubernetes 将从首个配置的 service-cluster-ip-range
给 Service 分配集群 IP,
并将 .spec.ipFamilyPolicy
设置为 SingleStack
。
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
使用 kubectl
查看 Service 的 YAML 定义。
kubectl get svc my-service -o yaml
该 Service 通过在 kube-controller-manager 的 --service-cluster-ip-range
标志设置的第一个配置范围,将 .spec.ipFamilyPolicy
设置为 SingleStack
,
将 .spec.clusterIP
设置为 IPv4 地址。
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
clusterIP: 10.0.217.164
clusterIPs:
- 10.0.217.164
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- port: 80
protocol: TCP
targetPort: 9376
selector:
app.kubernetes.io/name: MyApp
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
创建以下显式定义 .spec.ipFamilies
数组中的第一个元素为 IPv6 的 Service。
Kubernetes 将 service-cluster-ip-range
配置的 IPv6 地址范围给 Service 分配集群 IP,
并将 .spec.ipFamilyPolicy
设置为 SingleStack
。
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
ipFamilies:
- IPv6
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
使用 kubectl
查看 Service 的 YAML 定义。
kubectl get svc my-service -o yaml
该 Service 通过在 kube-controller-manager 的 --service-cluster-ip-range
标志设置的 IPv6 地址范围,将 .spec.ipFamilyPolicy
设置为 SingleStack
,
将 .spec.clusterIP
设置为 IPv6 地址。
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: MyApp
name: my-service
spec:
clusterIP: 2001:db8:fd00::5118
clusterIPs:
- 2001:db8:fd00::5118
ipFamilies:
- IPv6
ipFamilyPolicy: SingleStack
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app.kubernetes.io/name: MyApp
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
创建以下显式定义 .spec.ipFamilyPolicy
为 PreferDualStack
的 Service。
Kubernetes 将分配 IPv4 和 IPv6 地址(因为该集群启用了双栈),
并根据 .spec.ipFamilies
数组中第一个元素的地址族,
从 .spec.ClusterIPs
列表中选择 .spec.ClusterIP
。
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
ipFamilyPolicy: PreferDualStack
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
说明:
kubectl get svc
命令将仅在 CLUSTER-IP
字段中显示主 IP。
kubectl get svc -l app.kubernetes.io/name=MyApp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP 10.0.216.242 <none> 80/TCP 5s
使用 kubectl describe
验证服务是否从 IPv4 和 IPv6 地址块中获取了集群 IP。
然后你就可以通过 IP 和端口,验证对服务的访问。
kubectl describe svc -l app.kubernetes.io/name=MyApp
Name: my-service
Namespace: default
Labels: app.kubernetes.io/name=MyApp
Annotations: <none>
Selector: app.kubernetes.io/name=MyApp
Type: ClusterIP
IP Family Policy: PreferDualStack
IP Families: IPv4,IPv6
IP: 10.0.216.242
IPs: 10.0.216.242,2001:db8:fd00::af55
Port: <unset> 80/TCP
TargetPort: 9376/TCP
Endpoints: <none>
Session Affinity: None
Events: <none>
创建双协议栈负载均衡服务
如果云提供商支持配置启用 IPv6 的外部负载均衡器,则创建如下 Service 时将
.spec.ipFamilyPolicy
设置为 PreferDualStack
, 并将 spec.ipFamilies
字段
的第一个元素设置为 IPv6
,将 type
字段设置为 LoadBalancer
:
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
ipFamilyPolicy: PreferDualStack
ipFamilies:
- IPv6
type: LoadBalancer
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
检查服务:
kubectl get svc -l app.kubernetes.io/name=MyApp
验证服务是否从 IPv6 地址块中接收到 CLUSTER-IP
地址以及 EXTERNAL-IP
。
然后,你可以通过 IP 和端口验证对服务的访问。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 2001:db8:fd00::7ebc 2603:1030:805::5 80:30790/TCP 35s
4 - 重新配置 Kubernetes 默认的 Service CIDR
Kubernetes v1.33 [stable]
(enabled by default: true)
This is a stable feature in Kubernetes, and has been since version 1.33. It was first available in the v1.27 release.
本文介绍如何重新配置集群中分配的默认 Service IP 范围。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 v1.33.要获知版本信息,请输入 kubectl version
.
重新配置 Kubernetes 默认 Service CIDR
本文解释了如何管理 Kubernetes 集群中的 Service IP 地址范围,这也会影响集群针对不同 Service 所支持的 IP 协议族。
可用于 Service ClusterIP 的 IP 协议族由传递给 kube-apiserver 的 --service-cluster-ip-range
参数决定。要更好地了解 Service IP 地址分配,请参考
Service IP 地址分配追踪文档。
自 Kubernetes 1.33 起,为集群所配置的 Service IP 协议族会通过名为 kubernetes
的 ServiceCIDR
对象反映。
这个 kubernetes
ServiceCIDR
对象由依据其配置的 --service-cluster-ip-range
参数所启动的第一个 kube-apiserver 实例创建。为了确保集群行为一致,所有 kube-apiserver 实例必须使用相同的
--service-cluster-ip-range
配置,其取值需与默认的 kubernetes ServiceCIDR 对象保持一致。
Kubernetes Service CIDR 重新配置类别
我们可以将 Service CIDR 的重新配置分为以下几种情形:
- 扩展现有的 Service CIDR: 这可以通过添加新的 ServiceCIDR 对象动态完成,无需重新配置 kube-apiserver。 请参考扩展 Service IP 范围的专门文档。
- 保留主 Service CIDR 的单栈到双栈转换: 这意味着引入次要 IP 协议族(IPv6 到仅 IPv4 集群,或 IPv4 到仅 IPv6 集群), 同时保留原 IP 协议族作为主协议族。 这需要更新 kube-apiserver 配置,并相应修改需要处理这个附加 IP 协议族的各个集群组件。 这些组件包括但不限于 kube-proxy、CNI 或网络插件、服务网格实现和 DNS 服务。
- 保留主 Service CIDR 的双栈到单栈转换: 这意味着从双栈集群中移除次要 IP 协议族,恢复为单一 IP 协议族,同时保留原主 IP 协议族。 除了重新配置这些组件以匹配新的 IP 协议族外,你还可能需要处理那些显式使用被移除 IP 协议族的 Service。
- 变更主 Service CIDR 的任何情形:
完全替换默认 ServiceCIDR 是一项复杂的操作。如果新旧 ServiceCIDR 不重叠,
则需要重新编号所有现有 Service 并更改
kubernetes.default
Service。 如果主 IP 协议族也发生变化,则更为复杂,可能需要修改多个集群组件(如 kubelet、网络插件等)以匹配新的主 IP 协议族。
替换默认 Service CIDR 的手动操作
重新配置默认 Service CIDR 需要集群运维人员、管理员或管理集群生命周期的软件执行一系列手动步骤。 这些通常包括:
- 更新 kube-apiserver 配置:
使用新的 IP 范围修改
--service-cluster-ip-range
参数。
- 重新配置网络组件:这一步至关重要,具体步骤取决于正在使用的联网组件。 这可能包括更新配置文件、重启代理 Pod,或更新组件以处理新的 Service CIDR 和期望的 Pod IP 协议族配置。 典型组件可以是 Kubernetes Service(例如 kube-proxy)的实现、 所配置的网络插件以及服务网格控制器和 DNS 服务器等潜在的其他联网组件, 以确保它们能够正确处理流量并使用新的 IP 协议族配置来执行服务发现。
- 管理现有 Service: 如果某些 Service 所使用的 IP 不在新配置的范围内,则需处理这些服务。 你可以选择重新创建(会造成停机并重新分配 IP),或者采取更复杂的重新配置策略。
- 重新创建 Kubernetes 内部服务:
如果主 IP 协议族发生变化,或者被替换为另一个不同的网络,
则必须删除并重新创建
kubernetes.default
Service,以便从新的 Service CIDR 获取 IP 地址。
示例重新配置步骤
以下步骤描述了受控的重新配置过程,重点是完全替换默认 Service CIDR 并重新创建 kubernetes.default
Service:
- 使用初始的
--service-cluster-ip-range
启动 kube-apiserver。 - 创建初始 Service,使其从该范围获取 IP。
- 引入新的 Service CIDR,作为重新配置的临时目标。
- 将默认的
kubernetes
Service CIDR 标记为删除(由于存在 IP 和 Finalizer,会处于 Pending 状态)。 这将阻止从旧的范围分配新的 IP。
- 重新创建现有 Service。这些 Service 应从新的临时 Service CIDR 分配 IP。
- 使用配置的新 Service CIDR 重新启动 kube-apiserver,并关闭旧实例。
- 删除
kubernetes.default
Service。新的 kube-apiserver 将在新的 Service CIDR 范围内重新创建此 Service。