问题
There seems to be two contradictory explanations of how NodePort services route traffic. Services can route traffic to one of the two, not both:
- Nodes (through the kube-proxy) According to
kubectl explain Service.spec.externalTrafficPolicy
and this article that adds more detail, packets incoming to NodePort services withService.spec.externalTrafficPolicy=Local
set get routed to a kube-proxy, which then routes the packets to the corresponding pods its running.- This kube-proxy networking documentation further supports this theory adding that endpoints add a rule in the service's IPtable that forwards traffic to nodes through the kube-proxy.
- Pods: services update their IPtables from
endpoints
, which contain the IP addresses for the pods they can route to. Furthermore, if you remove your service's label selectors and edit endpoints you can change where your traffic is routed to.
If one of these is right, then I must be misunderstanding something.
- If services route to nodes, then why can I edit
endpoints
without breaking the IPtables? - If services route to pods, then why would services go through the trouble of routing to nodes when
Service.spec.externalTrafficPolicy
is set?
回答1:
A Service is a virtual address/port managed by kube-proxy
. Services forward traffic to their associated endpoints, which are usually pods but as you mentioned, can be set to any destination IP/Port.
A NodePort Service doesn't change the endpoint side of the service, the NodePort allows external traffic into Service via a port on a node.
Breakdown of a Service
kube-proxy
can use 3 methods to implement the forwarding of a service from Node to destination.
- a user proxy
- iptables
- ipvs
Most clusters use iptables, which is what is described below. I use the term "forward" instead of "route" because services use Network Address Translation (or the proxy) to "forward" traffic rather than standard network routing.
The service ClusterIP
is a virtual entity managed by kube-proxy
. This address/port combination is available on every node in the cluster and forwards any local (pod) service traffic to the endpoints IP and port.
/ Pod (remote node)
Pod -- ClusterIP/Port -- KUBE-SVC-NAT -- Pod
\ Pod (remote node)
A service with a NodePort
is the same as above, with the addition of a way to forward external traffic into the cluster via a Node. kube-proxy
manages an additional rule to watch for external traffic and forward it into the same service rules.
Ext -- NodePort \ / Pod (remote node)
KUBE-SVC-NAT -- Pod
Pod -- ClusterIP/Port / \ Pod (remote node)
The externalTrafficPolicy=Local
setting makes a NodePort service use only a local Pod to service the incoming traffic. This avoids a network hop which removes the need to rewrite the source of the packet (via NAT). This results in the real network IP arriving at the pod servicing the connection, rather than one of the cluster nodes being the source IP.
Ext -- NodePort \ Pod (remote node)
KUBE-SVC-NAT -- Pod (local)
Pod -- ClusterIP/Port / Pod (remote node)
iptables
I recommend attempting to trace a connection from source to destination for a service or nodeport on a host. It requires a bit of iptables knowledge but I think it's worthwhile
To list all the services ip/ports that will be forwarded:
iptables -vnL -t nat KUBE-SERVICES
To list all the nodeports that will be forwarded:
iptables -vnL -t nat KUBE-NODEPORTS
Once you have the rule you can jump through KUBE-SVC-XXX
"target" rules in the full output.
iptables -vnL -t nat | less
来源:https://stackoverflow.com/questions/60067188/how-do-kubernetes-nodeport-services-with-service-spec-externaltrafficpolicy-loca