proxy/iptables: fix internal-vs-external traffic policy handling

Fix internal and external traffic policy to be handled separately (so
that, in particular, services with Local internal traffic policy and
Cluster external traffic policy do not behave as though they had Local
external traffic policy as well.

Additionally, traffic to an `internalTrafficPolicy: Local` service on
a node with no endpoints is now dropped rather than being rejected
(which, as in the external case, may prevent traffic from being lost
when endpoints are in flux).
This commit is contained in:
Dan Winship
2021-11-16 10:49:55 -05:00
parent 2e780ecd99
commit 548cf9d5de
7 changed files with 494 additions and 215 deletions

View File

@@ -139,6 +139,24 @@ func (info *BaseServiceInfo) HintsAnnotation() string {
return info.hintsAnnotation
}
// ExternallyAccessible is part of ServicePort interface.
func (info *BaseServiceInfo) ExternallyAccessible() bool {
return info.nodePort != 0 || len(info.loadBalancerStatus.Ingress) != 0 || len(info.externalIPs) != 0
}
// UsesClusterEndpoints is part of ServicePort interface.
func (info *BaseServiceInfo) UsesClusterEndpoints() bool {
// The service port uses Cluster endpoints if the internal traffic policy is "Cluster",
// or if it accepts external traffic at all. (Even if the external traffic policy is
// "Local", we need Cluster endpoints to implement short circuiting.)
return !info.nodeLocalInternal || info.ExternallyAccessible()
}
// UsesLocalEndpoints is part of ServicePort interface.
func (info *BaseServiceInfo) UsesLocalEndpoints() bool {
return info.nodeLocalInternal || (info.nodeLocalExternal && info.ExternallyAccessible())
}
func (sct *ServiceChangeTracker) newBaseServiceInfo(port *v1.ServicePort, service *v1.Service) *BaseServiceInfo {
nodeLocalExternal := false
if apiservice.RequestsOnlyLocalTraffic(service) {