Kubernetes NodePort服务如何与Service.spec.externalTrafficPolicy=本地路由流量?
How do Kubernetes NodePort services with Service.spec.externalTrafficPolicy=Local route traffic?
对于 NodePort 服务如何路由流量似乎有两种相互矛盾的解释。服务可以将流量路由到两者之一,而不是两者:
- 节点(通过 kube-proxy) 根据
kubectl explain Service.spec.externalTrafficPolicy
和 this article 添加了更多细节,进入 NodePort 服务的数据包 Service.spec.externalTrafficPolicy=Local
设置路由到 kube-proxy,然后将数据包路由到相应的 pods 它的 运行。
- 这 kube-proxy networking documentation 进一步支持了这一理论,并补充说端点在服务的 IP 表中添加了一条规则,通过 kube-proxy 将流量转发到节点。
- Pods:服务从
endpoints
更新它们的 IP 表,其中包含 pods 他们可以路由到。此外,如果您删除服务的标签选择器和 edit endpoints,您可以更改您的流量路由到的位置。
如果其中一个是正确的,那我一定是误会了什么。
- 如果服务路由到 节点 ,那么为什么我可以在不破坏 IP 表的情况下编辑
endpoints
?
- 如果服务路由到pods,那么设置
Service.spec.externalTrafficPolicy
时,为什么服务还要经过路由到节点的麻烦?
A Service 是由 kube-proxy
管理的虚拟 address/port。服务将流量转发到它们关联的端点,这些端点通常是 pods,但正如您提到的,可以设置为任何目的地 IP/Port。
A NodePort Service 不会更改服务的端点端,NodePort 允许外部流量通过节点上的端口进入服务。
服务故障
kube-proxy
可以用3 methods实现一个服务从Node到目的地的转发。
- 一个用户代理
- iptables
- ipvs
大多数集群使用iptables,这就是下面描述的。我使用术语 "forward" 而不是 "route" 因为服务使用 Network Address Translation (或代理)到 "forward" 流量而不是标准网络路由。
服务 ClusterIP
是由 kube-proxy
管理的虚拟实体。这个 address/port 组合在集群中的每个节点上都可用,并将任何本地(pod)服务流量转发到端点 IP 和端口。
/ Pod (remote node)
Pod -- ClusterIP/Port -- KUBE-SVC-NAT -- Pod
\ Pod (remote node)
带有 NodePort
的服务与上面相同,增加了一种通过节点将外部流量转发到集群的方法。 kube-proxy
管理一个额外的规则来监视外部流量并将其转发到相同的服务规则中。
Ext -- NodePort \ / Pod (remote node)
KUBE-SVC-NAT -- Pod
Pod -- ClusterIP/Port / \ Pod (remote node)
externalTrafficPolicy=Local
设置使 NodePort 服务仅使用本地 Pod 来为传入流量提供服务。这避免了网络跃点,从而无需重写数据包的源(通过 NAT)。这导致实际网络 IP 到达为连接提供服务的 pod,而不是集群节点之一作为源 IP。
Ext -- NodePort \ Pod (remote node)
KUBE-SVC-NAT -- Pod (local)
Pod -- ClusterIP/Port / Pod (remote node)
iptables
我建议尝试跟踪主机上服务或节点端口从源到目的地的连接。它需要一些 iptables 知识,但我认为这是值得的
列出所有将被转发的服务ip/ports:
iptables -vnL -t nat KUBE-SERVICES
列出所有将被转发的节点端口:
iptables -vnL -t nat KUBE-NODEPORTS
一旦你有了规则,你就可以跳过完整输出中的 KUBE-SVC-XXX
"target" 规则。
iptables -vnL -t nat | less
externalTrafficPolicy: Cluster will not used on ClusterIP, try to remove and apply it, it"ll work
对于 NodePort 服务如何路由流量似乎有两种相互矛盾的解释。服务可以将流量路由到两者之一,而不是两者:
- 节点(通过 kube-proxy) 根据
kubectl explain Service.spec.externalTrafficPolicy
和 this article 添加了更多细节,进入 NodePort 服务的数据包Service.spec.externalTrafficPolicy=Local
设置路由到 kube-proxy,然后将数据包路由到相应的 pods 它的 运行。- 这 kube-proxy networking documentation 进一步支持了这一理论,并补充说端点在服务的 IP 表中添加了一条规则,通过 kube-proxy 将流量转发到节点。
- Pods:服务从
endpoints
更新它们的 IP 表,其中包含 pods 他们可以路由到。此外,如果您删除服务的标签选择器和 edit endpoints,您可以更改您的流量路由到的位置。
如果其中一个是正确的,那我一定是误会了什么。
- 如果服务路由到 节点 ,那么为什么我可以在不破坏 IP 表的情况下编辑
endpoints
? - 如果服务路由到pods,那么设置
Service.spec.externalTrafficPolicy
时,为什么服务还要经过路由到节点的麻烦?
A Service 是由 kube-proxy
管理的虚拟 address/port。服务将流量转发到它们关联的端点,这些端点通常是 pods,但正如您提到的,可以设置为任何目的地 IP/Port。
A NodePort Service 不会更改服务的端点端,NodePort 允许外部流量通过节点上的端口进入服务。
服务故障
kube-proxy
可以用3 methods实现一个服务从Node到目的地的转发。
- 一个用户代理
- iptables
- ipvs
大多数集群使用iptables,这就是下面描述的。我使用术语 "forward" 而不是 "route" 因为服务使用 Network Address Translation (或代理)到 "forward" 流量而不是标准网络路由。
服务 ClusterIP
是由 kube-proxy
管理的虚拟实体。这个 address/port 组合在集群中的每个节点上都可用,并将任何本地(pod)服务流量转发到端点 IP 和端口。
/ Pod (remote node)
Pod -- ClusterIP/Port -- KUBE-SVC-NAT -- Pod
\ Pod (remote node)
带有 NodePort
的服务与上面相同,增加了一种通过节点将外部流量转发到集群的方法。 kube-proxy
管理一个额外的规则来监视外部流量并将其转发到相同的服务规则中。
Ext -- NodePort \ / Pod (remote node)
KUBE-SVC-NAT -- Pod
Pod -- ClusterIP/Port / \ Pod (remote node)
externalTrafficPolicy=Local
设置使 NodePort 服务仅使用本地 Pod 来为传入流量提供服务。这避免了网络跃点,从而无需重写数据包的源(通过 NAT)。这导致实际网络 IP 到达为连接提供服务的 pod,而不是集群节点之一作为源 IP。
Ext -- NodePort \ Pod (remote node)
KUBE-SVC-NAT -- Pod (local)
Pod -- ClusterIP/Port / Pod (remote node)
iptables
我建议尝试跟踪主机上服务或节点端口从源到目的地的连接。它需要一些 iptables 知识,但我认为这是值得的
列出所有将被转发的服务ip/ports:
iptables -vnL -t nat KUBE-SERVICES
列出所有将被转发的节点端口:
iptables -vnL -t nat KUBE-NODEPORTS
一旦你有了规则,你就可以跳过完整输出中的 KUBE-SVC-XXX
"target" 规则。
iptables -vnL -t nat | less
externalTrafficPolicy: Cluster will not used on ClusterIP, try to remove and apply it, it"ll work