Metallb Kubernetes 安装:创建 IPAddresspool 时调用 webhook“ipaddresspoolvalidationwebhook.metalb.io”失败

Axd*_*der 5 kubernetes metallb

我正在使用 kubeadm 设置本地 kubernetes 集群。

这是 Kubernetes 版本

clientVersion:
  buildDate: "2022-10-12T10:57:26Z"
  compiler: gc
  gitCommit: 434bfd82814af038ad94d62ebe59b133fcb50506
  gitTreeState: clean
  gitVersion: v1.25.3
  goVersion: go1.19.2
  major: "1"
  minor: "25"
  platform: linux/amd64
kustomizeVersion: v4.5.7
serverVersion:
  buildDate: "2022-10-12T10:49:09Z"
  compiler: gc
  gitCommit: 434bfd82814af038ad94d62ebe59b133fcb50506
  gitTreeState: clean
  gitVersion: v1.25.3
  goVersion: go1.19.2
  major: "1"
  minor: "25"
  platform: linux/amd64
Run Code Online (Sandbox Code Playgroud)

我已经安装了metallb版本0.13.7

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
Run Code Online (Sandbox Code Playgroud)

一切都在运行

$ kubectl get all -n metallb-system
 
NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-84d6d4db45-l2r55   1/1     Running   0          35s
pod/speaker-48qn4                 1/1     Running   0          35s
pod/speaker-ds8hh                 1/1     Running   0          35s
pod/speaker-pfbcp                 1/1     Running   0          35s
pod/speaker-st7n2                 1/1     Running   0          35s

NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/webhook-service   ClusterIP   10.104.14.119   <none>        443/TCP   35s

NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker   4         4         4       4            4           kubernetes.io/os=linux   35s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           35s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-84d6d4db45   1         1         1       35s
Run Code Online (Sandbox Code Playgroud)

但是当我尝试应用 IPaddressPool CRD 时出现错误

kubectl apply -f ipaddresspool.yaml
Run Code Online (Sandbox Code Playgroud)

ipaddresspool.yaml 文件内容

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.2.100-192.168.2.199
Run Code Online (Sandbox Code Playgroud)

错误是无法调用验证 webhook 没有到主机的路由

Error from server (InternalError): error when creating "ipaddresspool.yaml": Internal error occurred: failed calling webhook "ipaddresspoolvalidationwebhook.metallb.io": failed to call webhook: Post "https://webhook-service.metallb-system.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s": dial tcp 10.104.14.119:443: connect: no route to host
Run Code Online (Sandbox Code Playgroud)

这是与线制动器相同的错误

Error from server (InternalError): 
error when creating "ipaddresspool.yaml": 
Internal error occurred: failed calling webhook "ipaddresspoolvalidationwebhook.metallb.io": 
failed to call webhook: 
Post "https://webhook-service.metallb-system.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s": 
dial tcp 10.104.14.119:443: connect: no route to host
Run Code Online (Sandbox Code Playgroud)

IP 地址正确

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
webhook-service   ClusterIP   10.104.14.119   <none>        443/TCP   18m
Run Code Online (Sandbox Code Playgroud)

我也尝试使用 helm 安装 Metallb v 0.13.7 但结果相同

有人知道为什么无法调用 webhook 吗?

编辑

作为托马斯问题的答案,这里是 webhook-service 的描述。请注意,这是来自另一个具有相同问题的集群,因为我删除了最后一个集群,因此 IP 与上次不同

$ kubectl describe svc webhook-service -n metallb-system

Name:              webhook-service
Namespace:         metallb-system
Labels:            <none>
Annotations:       <none>
Selector:          component=controller
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.105.157.72
IPs:               10.105.157.72
Port:              <unset>  443/TCP
TargetPort:        9443/TCP
Endpoints:         172.17.0.3:9443
Session Affinity:  None
Events:            <none>
Run Code Online (Sandbox Code Playgroud)

F1k*_*1ko 3

一旦理解了这个问题就相当简单了。

上面描述的 metallb 设置按预期工作。然而,Kubernetes 设置却没有。最有可能是由于网络配置错误造成的。


了解错误

理解正在发生的事情的关键是以下错误:

Error from server (InternalError): error when creating "ipaddresspool.yaml": Internal error occurred: failed calling webhook "ipaddresspoolvalidationwebhook.metallb.io": failed to call webhook: Post "https://webhook-service.metallb-system.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s": dial tcp 10.104.14.119:443: connect: no route to host
Run Code Online (Sandbox Code Playgroud)

所应用的 Metallb 清单的一部分将部署所谓的ValidatingWebhookConfiguration.

在此输入图像描述

对于 Metallb,此验证 Webhook 将强制 kube-apiserver:

  1. 每当有人创建或更新此类对象时,都会将与 metallb 相关的对象发送IPAddressPool到 webhook
  2. 等待 webhook 对对象执行一些检查(例如,验证 CIDR 和 IP 是否有效,而不是类似的内容481.9.141.12.27
  3. 最后从 webhook 收到答案,判断该对象是否满足 Metallb 的要求并允许创建(保存到 etcd)

上面的错误非常清楚地表明三个概述步骤中的第一个失败了。


调试

要修复此错误,必须调试当前设置,特别是从 kube-apiserver 到webhook-service.metallb-system.svc:443.

有多种可能的网络配置错误可能导致该错误。然而,根据我们现有的信息,很可能是配置的 CNI 出现错误。

了解这里有一些关于进一步调试过程的帮助和指导:

由于 kube-apiserver 默认情况下是经过强化的,因此无法在其中执行 shell。因此,应该在控制平面节点之一上部署与 kube-apiserver 具有相同网络配置的调试应用程序。这可以通过执行以下命令来实现:

kubectl debug -n kube-system node/<control-plane-node> -it --image=nicolaka/netshoot
Run Code Online (Sandbox Code Playgroud)

现在可以使用常用工具在交互式 shell 中重现错误。以下命令预计会失败(与 kube-apiserver 类似):

curl -m 10 -k https://<webhook-service-ip>:443/
Run Code Online (Sandbox Code Playgroud)

鉴于上述错误消息,它应该由于节点上的错误路由而失败。要检查路由表,请执行以下命令:

routel
Run Code Online (Sandbox Code Playgroud)

有人知道为什么无法调用 webhook 吗?

输出应显示配置的多个 CIDR 范围,其中之一应包含之前查询的 IP。最有可能的是相关 CIDR 范围丢失或配置了错误的网关,从而导致错误no route to host。CNI 的工作是更新所有节点上的路由表并确保节点可以到达这些地址,因此不建议手动向路由表添加或编辑新的 Kubernetes 相关条目。进一步的调试取决于确切的设置。根据设置和选择的 CNI,kube-proxy 可能也可能不涉及该问题。不过,下一步应该检查 CNI 配置和日志。


一些奖金信息

某些 CNI 要求用户更加关注某些功能和配置,否则可能会出现问题。以下是属于此类别的一些流行的 CNI: