Add route type field to loadbalancer status ingress

Signed-off-by: Patrik Cyvoct <patrik@ptrk.io>
This commit is contained in:
Patrik Cyvoct 2020-06-19 19:04:49 +02:00
parent 9253aa9309
commit 47ae7cbf52
No known key found for this signature in database
GPG Key ID: 4334D82B950FB63A
6 changed files with 63 additions and 35 deletions

View File

@ -3508,6 +3508,11 @@ type LoadBalancerIngress struct {
// (typically AWS load-balancers) // (typically AWS load-balancers)
// +optional // +optional
Hostname string Hostname string
// RouteType specifies the type of route to use for this ingress
// Defaults to `VIP`
// +optional
RouteType LoadBalancerRouteType
} }
const ( const (
@ -3515,6 +3520,16 @@ const (
MaxServiceTopologyKeys = 16 MaxServiceTopologyKeys = 16
) )
// LoadBalancerRouteType represents the type of route available for a LoadBalancer ingress
type LoadBalancerRouteType string
const (
// LoadBalancerRouteTypeVIP is the type of route used by a LoadBalancer where dstIP = lbIP
LoadBalancerRouteTypeVIP LoadBalancerRouteType = "VIP"
// LoadBalancerRouteTypeProxy is the type of route used by a proxy like LoadBalancer
LoadBalancerRouteTypeProxy LoadBalancerRouteType = "Proxy"
)
// IPFamily represents the IP Family (IPv4 or IPv6). This type is used // IPFamily represents the IP Family (IPv4 or IPv6). This type is used
// to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). // to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies).
type IPFamily string type IPFamily string

View File

@ -782,10 +782,10 @@ func (proxier *Proxier) deleteEndpointConnections(connectionMap []proxy.ServiceE
klog.Errorf("Failed to delete %s endpoint connections for externalIP %s, error: %v", epSvcPair.ServicePortName.String(), extIP, err) klog.Errorf("Failed to delete %s endpoint connections for externalIP %s, error: %v", epSvcPair.ServicePortName.String(), extIP, err)
} }
} }
for _, lbIP := range svcInfo.LoadBalancerIPStrings() { for _, lbIngress := range svcInfo.LoadBalancerIngress() {
err := conntrack.ClearEntriesForNAT(proxier.exec, lbIP, endpointIP, svcProto) err := conntrack.ClearEntriesForNAT(proxier.exec, lbIngress.IP, endpointIP, svcProto)
if err != nil { if err != nil {
klog.Errorf("Failed to delete %s endpoint connections for LoabBalancerIP %s, error: %v", epSvcPair.ServicePortName.String(), lbIP, err) klog.Errorf("Failed to delete %s endpoint connections for LoabBalancerIP %s, error: %v", epSvcPair.ServicePortName.String(), lbIngress.IP, err)
} }
} }
} }
@ -1161,8 +1161,8 @@ func (proxier *Proxier) syncProxyRules() {
// Capture load-balancer ingress. // Capture load-balancer ingress.
fwChain := svcInfo.serviceFirewallChainName fwChain := svcInfo.serviceFirewallChainName
for _, ingress := range svcInfo.LoadBalancerIPStrings() { for _, ingress := range svcInfo.LoadBalancerIngress() {
if ingress != "" { if ingress.IP != "" {
if hasEndpoints { if hasEndpoints {
// create service firewall chain // create service firewall chain
if chain, ok := existingNATChains[fwChain]; ok { if chain, ok := existingNATChains[fwChain]; ok {
@ -1175,15 +1175,17 @@ func (proxier *Proxier) syncProxyRules() {
// This currently works for loadbalancers that preserves source ips. // This currently works for loadbalancers that preserves source ips.
// For loadbalancers which direct traffic to service NodePort, the firewall rules will not apply. // For loadbalancers which direct traffic to service NodePort, the firewall rules will not apply.
if ingress.RouteType != v1.LoadBalancerRouteTypeProxy {
args = append(args[:0], args = append(args[:0],
"-A", string(kubeServicesChain), "-A", string(kubeServicesChain),
"-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString), "-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString),
"-m", protocol, "-p", protocol, "-m", protocol, "-p", protocol,
"-d", utilproxy.ToCIDR(net.ParseIP(ingress)), "-d", utilproxy.ToCIDR(net.ParseIP(ingress.IP)),
"--dport", strconv.Itoa(svcInfo.Port()), "--dport", strconv.Itoa(svcInfo.Port()),
) )
// jump to service firewall chain // jump to service firewall chain
writeLine(proxier.natRules, append(args, "-j", string(fwChain))...) writeLine(proxier.natRules, append(args, "-j", string(fwChain))...)
}
args = append(args[:0], args = append(args[:0],
"-A", string(fwChain), "-A", string(fwChain),
@ -1218,7 +1220,7 @@ func (proxier *Proxier) syncProxyRules() {
// loadbalancer's backend hosts. In this case, request will not hit the loadbalancer but loop back directly. // loadbalancer's backend hosts. In this case, request will not hit the loadbalancer but loop back directly.
// Need to add the following rule to allow request on host. // Need to add the following rule to allow request on host.
if allowFromNode { if allowFromNode {
writeLine(proxier.natRules, append(args, "-s", utilproxy.ToCIDR(net.ParseIP(ingress)), "-j", string(chosenChain))...) writeLine(proxier.natRules, append(args, "-s", utilproxy.ToCIDR(net.ParseIP(ingress.IP)), "-j", string(chosenChain))...)
} }
} }
@ -1231,7 +1233,7 @@ func (proxier *Proxier) syncProxyRules() {
"-A", string(kubeExternalServicesChain), "-A", string(kubeExternalServicesChain),
"-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString), "-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString),
"-m", protocol, "-p", protocol, "-m", protocol, "-p", protocol,
"-d", utilproxy.ToCIDR(net.ParseIP(ingress)), "-d", utilproxy.ToCIDR(net.ParseIP(ingress.IP)),
"--dport", strconv.Itoa(svcInfo.Port()), "--dport", strconv.Itoa(svcInfo.Port()),
"-j", "REJECT", "-j", "REJECT",
) )

View File

@ -1332,11 +1332,11 @@ func (proxier *Proxier) syncProxyRules() {
} }
// Capture load-balancer ingress. // Capture load-balancer ingress.
for _, ingress := range svcInfo.LoadBalancerIPStrings() { for _, ingress := range svcInfo.LoadBalancerIngress() {
if ingress != "" { if ingress.IP != "" && ingress.RouteType != v1.LoadBalancerRouteTypeProxy {
// ipset call // ipset call
entry = &utilipset.Entry{ entry = &utilipset.Entry{
IP: ingress, IP: ingress.IP,
Port: svcInfo.Port(), Port: svcInfo.Port(),
Protocol: protocol, Protocol: protocol,
SetType: utilipset.HashIPPort, SetType: utilipset.HashIPPort,
@ -1371,7 +1371,7 @@ func (proxier *Proxier) syncProxyRules() {
for _, src := range svcInfo.LoadBalancerSourceRanges() { for _, src := range svcInfo.LoadBalancerSourceRanges() {
// ipset call // ipset call
entry = &utilipset.Entry{ entry = &utilipset.Entry{
IP: ingress, IP: ingress.IP,
Port: svcInfo.Port(), Port: svcInfo.Port(),
Protocol: protocol, Protocol: protocol,
Net: src, Net: src,
@ -1395,10 +1395,10 @@ func (proxier *Proxier) syncProxyRules() {
// Need to add the following rule to allow request on host. // Need to add the following rule to allow request on host.
if allowFromNode { if allowFromNode {
entry = &utilipset.Entry{ entry = &utilipset.Entry{
IP: ingress, IP: ingress.IP,
Port: svcInfo.Port(), Port: svcInfo.Port(),
Protocol: protocol, Protocol: protocol,
IP2: ingress, IP2: ingress.IP,
SetType: utilipset.HashIPPortIP, SetType: utilipset.HashIPPortIP,
} }
// enumerate all white list source ip // enumerate all white list source ip
@ -1412,7 +1412,7 @@ func (proxier *Proxier) syncProxyRules() {
// ipvs call // ipvs call
serv := &utilipvs.VirtualServer{ serv := &utilipvs.VirtualServer{
Address: net.ParseIP(ingress), Address: net.ParseIP(ingress.IP),
Port: uint16(svcInfo.Port()), Port: uint16(svcInfo.Port()),
Protocol: string(svcInfo.Protocol()), Protocol: string(svcInfo.Protocol()),
Scheduler: proxier.ipvsScheduler, Scheduler: proxier.ipvsScheduler,
@ -1957,10 +1957,10 @@ func (proxier *Proxier) deleteEndpointConnections(connectionMap []proxy.ServiceE
klog.Errorf("Failed to delete %s endpoint connections for externalIP %s, error: %v", epSvcPair.ServicePortName.String(), extIP, err) klog.Errorf("Failed to delete %s endpoint connections for externalIP %s, error: %v", epSvcPair.ServicePortName.String(), extIP, err)
} }
} }
for _, lbIP := range svcInfo.LoadBalancerIPStrings() { for _, lbIngress := range svcInfo.LoadBalancerIngress() {
err := conntrack.ClearEntriesForNAT(proxier.exec, lbIP, endpointIP, svcProto) err := conntrack.ClearEntriesForNAT(proxier.exec, lbIngress.IP, endpointIP, svcProto)
if err != nil { if err != nil {
klog.Errorf("Failed to delete %s endpoint connections for LoadBalancerIP %s, error: %v", epSvcPair.ServicePortName.String(), lbIP, err) klog.Errorf("Failed to delete %s endpoint connections for LoadBalancerIP %s, error: %v", epSvcPair.ServicePortName.String(), lbIngress.IP, err)
} }
} }
} }

View File

@ -105,13 +105,9 @@ func (info *BaseServiceInfo) ExternalIPStrings() []string {
return info.externalIPs return info.externalIPs
} }
// LoadBalancerIPStrings is part of ServicePort interface. // LoadBalancerIngress is part of ServicePort interface.
func (info *BaseServiceInfo) LoadBalancerIPStrings() []string { func (info *BaseServiceInfo) LoadBalancerIngress() []v1.LoadBalancerIngress {
var ips []string return info.loadBalancerStatus.Ingress
for _, ing := range info.loadBalancerStatus.Ingress {
ips = append(ips, ing.IP)
}
return ips
} }
// OnlyNodeLocalEndpoints is part of ServicePort interface. // OnlyNodeLocalEndpoints is part of ServicePort interface.

View File

@ -73,8 +73,8 @@ type ServicePort interface {
StickyMaxAgeSeconds() int StickyMaxAgeSeconds() int
// ExternalIPStrings returns service ExternalIPs as a string array. // ExternalIPStrings returns service ExternalIPs as a string array.
ExternalIPStrings() []string ExternalIPStrings() []string
// LoadBalancerIPStrings returns service LoadBalancerIPs as a string array. // LoadBalancerIngress returns service an array of LoadBalancerIngress.
LoadBalancerIPStrings() []string LoadBalancerIngress() []v1.LoadBalancerIngress
// GetProtocol returns service protocol. // GetProtocol returns service protocol.
Protocol() v1.Protocol Protocol() v1.Protocol
// LoadBalancerSourceRanges returns service LoadBalancerSourceRanges if present empty array if not // LoadBalancerSourceRanges returns service LoadBalancerSourceRanges if present empty array if not

View File

@ -3971,6 +3971,11 @@ type LoadBalancerIngress struct {
// (typically AWS load-balancers) // (typically AWS load-balancers)
// +optional // +optional
Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"` Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"`
// RouteType specifies the type of route to use for this ingress
// Defaults to `VIP`
// +optional
RouteType LoadBalancerRouteType `json:"routeType,omitempty" protobuf:"bytes,3,opt,name=routeType"`
} }
const ( const (
@ -3978,6 +3983,16 @@ const (
MaxServiceTopologyKeys = 16 MaxServiceTopologyKeys = 16
) )
// LoadBalancerRouteType represents the type of route available for a LoadBalancer ingress
type LoadBalancerRouteType string
const (
// LoadBalancerRouteTypeVIP is the type of route used by a LoadBalancer where dstIP = lbIP
LoadBalancerRouteTypeVIP LoadBalancerRouteType = "VIP"
// LoadBalancerRouteTypeProxy is the type of route used by a proxy like LoadBalancer
LoadBalancerRouteTypeProxy LoadBalancerRouteType = "Proxy"
)
// IPFamily represents the IP Family (IPv4 or IPv6). This type is used // IPFamily represents the IP Family (IPv4 or IPv6). This type is used
// to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). // to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies).
type IPFamily string type IPFamily string