Kubernetes 负载均衡器服务包源 IP
Kubernetes load balancer service packet source IP
我使用 kubeadm 在裸机上设置了一个 kubernetes 1.13 版本的集群(目前只有一个节点)。该节点有 2 个网络接口连接到它用于测试目的。理想情况下,将来一个接口应该面向 Intranet,另一个接口面向 public 网络。届时节点数也将大于一个。
对于 Intranet 入口,我使用 HAProxy 的 helm chart ( https://github.com/helm/charts/tree/master/incubator/haproxy-ingress ) 设置,配置如下:
rbac:
create: true
serviceAccount:
create: true
controller:
ingressClass: "intranet-ingress"
metrics:
enabled: true
stats:
enabled: true
service:
type: LoadBalancer
externalIPs:
- 10.X.X.X # IP of one of the network interfaces
service:
externalIPs:
- 10.X.X.X # IP of the same interface
然后流量到达haproxy如下:
1. Client's browser, workstation has an IP from 172.26.X.X range
--local network, no NAT -->
2. Kubernetes server, port 443 of HAProxy's load balancer service
--magic done by kube-proxy, possibly NAT(which shoudn't have been here)-->
3. HAProxy's ingress controller pod
HAProxy访问日志显示源IP为10.32.0.1。这是来自 kubernete 网络层的 IP。 Kubernetes pod CIDR 是 10.32.0.0/12。但是,我需要访问日志来显示连接的实际源 IP。
我试过手动编辑 HAProxy 创建的负载均衡器服务并设置 externalTrafficPolicy: Local
。那没有帮助。
如何获取此配置中客户端的源IP?
我已经解决了这个问题,原来我的原始配置中存在一些问题。
首先,我没有提到我的网络提供商是什么。我正在使用 weave-net,事实证明,即使 kubernetes 文档指出为了保留源 IP,将 externalTrafficPolicy: Local
添加到负载均衡器服务就足够了,但它无法与 weave-net 一起使用,除非你专门启用它。因此,在我使用的 weave-net 版本 (2.5.1) 上,您必须将以下环境变量添加到 weave-net DeamonSet NO_MASQ_LOCAL=1
。有关详细信息,请参阅他们的 documentation.
老实说,在那之后,我的记忆有点模糊,但我认为你在这个阶段得到的是一个集群,其中:
- NodePort服务:不支持源IP保存。不知何故,这在 AWS 上有效,但 kubernetes 本身不支持裸机,weave-net 没有错。
- LoadBalancer 服务 在 IP X 绑定到另一个节点 Y 的 IP 的节点上:不支持源 IP 保留,因为流量必须在 kubernetes 网络内部路由。
- LoadBalancer 服务 在 IP X 绑定到同一个 IP X 的节点上:我记不太清楚了,但我认为这有效。
其次,开箱即用的 kubernetes 不支持真正的 LoadBalancer 服务。如果您决定坚持使用 "standard" 设置而不进行任何额外操作,则必须将 pods 限制为 运行 仅在绑定了 LB IP 地址的集群节点上。这使得管理集群变得非常痛苦,因为您变得非常依赖节点上组件的特定排列。你也失去了冗余。
要解决第二个问题,您必须为裸机设置配置负载均衡器实施提供程序。我个人用的是MetalLB。通过配置,您可以为负载均衡器服务提供一个虚拟 IP 地址列表,因为它们没有附加到特定节点。每次kubernetes启动一个pod接受来自LB服务的流量;它将其中一个虚拟 IP 地址附加到同一节点。因此,LB IP 地址始终随 pod 移动,您永远不必通过 kubernetes 网络路由外部流量。因此,您将获得 100% 的源 IP 保留。
我使用 kubeadm 在裸机上设置了一个 kubernetes 1.13 版本的集群(目前只有一个节点)。该节点有 2 个网络接口连接到它用于测试目的。理想情况下,将来一个接口应该面向 Intranet,另一个接口面向 public 网络。届时节点数也将大于一个。
对于 Intranet 入口,我使用 HAProxy 的 helm chart ( https://github.com/helm/charts/tree/master/incubator/haproxy-ingress ) 设置,配置如下:
rbac:
create: true
serviceAccount:
create: true
controller:
ingressClass: "intranet-ingress"
metrics:
enabled: true
stats:
enabled: true
service:
type: LoadBalancer
externalIPs:
- 10.X.X.X # IP of one of the network interfaces
service:
externalIPs:
- 10.X.X.X # IP of the same interface
然后流量到达haproxy如下:
1. Client's browser, workstation has an IP from 172.26.X.X range
--local network, no NAT -->
2. Kubernetes server, port 443 of HAProxy's load balancer service
--magic done by kube-proxy, possibly NAT(which shoudn't have been here)-->
3. HAProxy's ingress controller pod
HAProxy访问日志显示源IP为10.32.0.1。这是来自 kubernete 网络层的 IP。 Kubernetes pod CIDR 是 10.32.0.0/12。但是,我需要访问日志来显示连接的实际源 IP。
我试过手动编辑 HAProxy 创建的负载均衡器服务并设置 externalTrafficPolicy: Local
。那没有帮助。
如何获取此配置中客户端的源IP?
我已经解决了这个问题,原来我的原始配置中存在一些问题。
首先,我没有提到我的网络提供商是什么。我正在使用 weave-net,事实证明,即使 kubernetes 文档指出为了保留源 IP,将 externalTrafficPolicy: Local
添加到负载均衡器服务就足够了,但它无法与 weave-net 一起使用,除非你专门启用它。因此,在我使用的 weave-net 版本 (2.5.1) 上,您必须将以下环境变量添加到 weave-net DeamonSet NO_MASQ_LOCAL=1
。有关详细信息,请参阅他们的 documentation.
老实说,在那之后,我的记忆有点模糊,但我认为你在这个阶段得到的是一个集群,其中:
- NodePort服务:不支持源IP保存。不知何故,这在 AWS 上有效,但 kubernetes 本身不支持裸机,weave-net 没有错。
- LoadBalancer 服务 在 IP X 绑定到另一个节点 Y 的 IP 的节点上:不支持源 IP 保留,因为流量必须在 kubernetes 网络内部路由。
- LoadBalancer 服务 在 IP X 绑定到同一个 IP X 的节点上:我记不太清楚了,但我认为这有效。
其次,开箱即用的 kubernetes 不支持真正的 LoadBalancer 服务。如果您决定坚持使用 "standard" 设置而不进行任何额外操作,则必须将 pods 限制为 运行 仅在绑定了 LB IP 地址的集群节点上。这使得管理集群变得非常痛苦,因为您变得非常依赖节点上组件的特定排列。你也失去了冗余。
要解决第二个问题,您必须为裸机设置配置负载均衡器实施提供程序。我个人用的是MetalLB。通过配置,您可以为负载均衡器服务提供一个虚拟 IP 地址列表,因为它们没有附加到特定节点。每次kubernetes启动一个pod接受来自LB服务的流量;它将其中一个虚拟 IP 地址附加到同一节点。因此,LB IP 地址始终随 pod 移动,您永远不必通过 kubernetes 网络路由外部流量。因此,您将获得 100% 的源 IP 保留。