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)
// +optional
Hostname string
// RouteType specifies the type of route to use for this ingress
// Defaults to `VIP`
// +optional
RouteType LoadBalancerRouteType
}
const (
@ -3515,6 +3520,16 @@ const (
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
// to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies).
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)
}
}
for _, lbIP := range svcInfo.LoadBalancerIPStrings() {
err := conntrack.ClearEntriesForNAT(proxier.exec, lbIP, endpointIP, svcProto)
for _, lbIngress := range svcInfo.LoadBalancerIngress() {
err := conntrack.ClearEntriesForNAT(proxier.exec, lbIngress.IP, endpointIP, svcProto)
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.
fwChain := svcInfo.serviceFirewallChainName
for _, ingress := range svcInfo.LoadBalancerIPStrings() {
if ingress != "" {
for _, ingress := range svcInfo.LoadBalancerIngress() {
if ingress.IP != "" {
if hasEndpoints {
// create service firewall chain
if chain, ok := existingNATChains[fwChain]; ok {
@ -1175,15 +1175,17 @@ func (proxier *Proxier) syncProxyRules() {
// This currently works for loadbalancers that preserves source ips.
// For loadbalancers which direct traffic to service NodePort, the firewall rules will not apply.
args = append(args[:0],
"-A", string(kubeServicesChain),
"-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString),
"-m", protocol, "-p", protocol,
"-d", utilproxy.ToCIDR(net.ParseIP(ingress)),
"--dport", strconv.Itoa(svcInfo.Port()),
)
// jump to service firewall chain
writeLine(proxier.natRules, append(args, "-j", string(fwChain))...)
if ingress.RouteType != v1.LoadBalancerRouteTypeProxy {
args = append(args[:0],
"-A", string(kubeServicesChain),
"-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString),
"-m", protocol, "-p", protocol,
"-d", utilproxy.ToCIDR(net.ParseIP(ingress.IP)),
"--dport", strconv.Itoa(svcInfo.Port()),
)
// jump to service firewall chain
writeLine(proxier.natRules, append(args, "-j", string(fwChain))...)
}
args = append(args[:0],
"-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.
// Need to add the following rule to allow request on host.
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),
"-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString),
"-m", protocol, "-p", protocol,
"-d", utilproxy.ToCIDR(net.ParseIP(ingress)),
"-d", utilproxy.ToCIDR(net.ParseIP(ingress.IP)),
"--dport", strconv.Itoa(svcInfo.Port()),
"-j", "REJECT",
)

View File

@ -1332,11 +1332,11 @@ func (proxier *Proxier) syncProxyRules() {
}
// Capture load-balancer ingress.
for _, ingress := range svcInfo.LoadBalancerIPStrings() {
if ingress != "" {
for _, ingress := range svcInfo.LoadBalancerIngress() {
if ingress.IP != "" && ingress.RouteType != v1.LoadBalancerRouteTypeProxy {
// ipset call
entry = &utilipset.Entry{
IP: ingress,
IP: ingress.IP,
Port: svcInfo.Port(),
Protocol: protocol,
SetType: utilipset.HashIPPort,
@ -1371,7 +1371,7 @@ func (proxier *Proxier) syncProxyRules() {
for _, src := range svcInfo.LoadBalancerSourceRanges() {
// ipset call
entry = &utilipset.Entry{
IP: ingress,
IP: ingress.IP,
Port: svcInfo.Port(),
Protocol: protocol,
Net: src,
@ -1395,10 +1395,10 @@ func (proxier *Proxier) syncProxyRules() {
// Need to add the following rule to allow request on host.
if allowFromNode {
entry = &utilipset.Entry{
IP: ingress,
IP: ingress.IP,
Port: svcInfo.Port(),
Protocol: protocol,
IP2: ingress,
IP2: ingress.IP,
SetType: utilipset.HashIPPortIP,
}
// enumerate all white list source ip
@ -1412,7 +1412,7 @@ func (proxier *Proxier) syncProxyRules() {
// ipvs call
serv := &utilipvs.VirtualServer{
Address: net.ParseIP(ingress),
Address: net.ParseIP(ingress.IP),
Port: uint16(svcInfo.Port()),
Protocol: string(svcInfo.Protocol()),
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)
}
}
for _, lbIP := range svcInfo.LoadBalancerIPStrings() {
err := conntrack.ClearEntriesForNAT(proxier.exec, lbIP, endpointIP, svcProto)
for _, lbIngress := range svcInfo.LoadBalancerIngress() {
err := conntrack.ClearEntriesForNAT(proxier.exec, lbIngress.IP, endpointIP, svcProto)
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
}
// LoadBalancerIPStrings is part of ServicePort interface.
func (info *BaseServiceInfo) LoadBalancerIPStrings() []string {
var ips []string
for _, ing := range info.loadBalancerStatus.Ingress {
ips = append(ips, ing.IP)
}
return ips
// LoadBalancerIngress is part of ServicePort interface.
func (info *BaseServiceInfo) LoadBalancerIngress() []v1.LoadBalancerIngress {
return info.loadBalancerStatus.Ingress
}
// OnlyNodeLocalEndpoints is part of ServicePort interface.

View File

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

View File

@ -3971,6 +3971,11 @@ type LoadBalancerIngress struct {
// (typically AWS load-balancers)
// +optional
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 (
@ -3978,6 +3983,16 @@ const (
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
// to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies).
type IPFamily string