问题描述
我的设置是运行Kubernetes 1.17的裸机集群。我将Traefik 2(.3.2)用作反向代理,并且为了对我的机器进行故障转移,我使用了kube-keepalive-vip
[1]。
---
apiVersion: v1
kind: ConfigMap
Metadata:
name: kube-keepalived-vip-config
namespace: kube-system
data:
172.111.222.33: kube-system/traefik2-ingress-controller
因此,我的traefik服务是默认类型的群集IP,并且引用了kube-keepalive-vip
服务提供的外部IP:
---
apiVersion: v1
kind: Service
Metadata:
name: traefik2-ingress-controller
namespace: kube-system
spec:
selector:
app: traefik2-ingress-controller
ports:
- protocol: TCP
name: web
port: 80
- protocol: TCP
name: webs
port: 443
externalIPs:
- 172.111.222.33
按原样工作。现在,我希望限制某些应用程序只能从网络内部的特定子网访问。由于我的请求由kube-keepalive-vip
和kube-proxy
处理,因此我的请求中的客户端IP不再是实际的客户端之一。但据我所知,kube-proxy
正在X-Forwarded-For
标头中设置真实IP。所以我的中间件看起来像这样:
internal-ip-whitelist:
ipwhiteList:
sourceRange:
- 10.0.0.0/8 # my subnet
- 60.120.180.240 # my public ip
ipStrategy:
depth: 2 # take second entry from X-Forwarded-For header
现在,对该中间件所附加的入口的每个请求都将被拒绝。我查看了Traefik日志,发现请求包含一些X-Forwarded-*
标头,但没有X-Forwarded-For
:(
有人对此有任何经验,可以指出我的错误吗?我的Kubernetes设置可能有问题吗?还是我的kube-keepalive-vip
配置中缺少某些内容?
谢谢!
[1] https://github.com/aledbf/kube-keepalived-vip
解决方法
对于遇到此问题的每个人,我设法在此期间解决了我的问题。
主要问题是kube-proxy
。默认情况下,所有服务都通过它路由。而且,根据您的 CNI 提供程序(我使用 flannel
),您的调用客户端的信息会在那里丢失。
K8s 通过将 .spec.externalTrafficPolicy
设置为 Local
(https://kubernetes.io/docs/concepts/services-networking/service/#aws-nlb-support) 提供了一种解决方法。但这不适用于 ClusterIP
服务。
所以我通过使用为裸机集群提供负载平衡的 MetalLB (https://metallb.universe.tf/) 解决了这个问题。在使用我之前分配给 keepalived 容器的虚拟 IP 进行设置后,我使用类型 LoadBalancer
配置了 traefik 服务并请求了我在 MetalLB 中的一个 IP。