Skip to content

Commit ef2628d

Browse files
committed
Adding support for ModifyLoadbalancer in windows kubeproxy.
1 parent e31d2ce commit ef2628d

File tree

5 files changed

+628
-84
lines changed

5 files changed

+628
-84
lines changed

pkg/proxy/winkernel/hcnutils.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ limitations under the License.
2020
package winkernel
2121

2222
import (
23-
"github.com/Microsoft/hcsshim"
2423
"github.com/Microsoft/hcsshim/hcn"
2524
"k8s.io/klog/v2"
2625
)
@@ -41,6 +40,7 @@ type HcnService interface {
4140
ListLoadBalancers() ([]hcn.HostComputeLoadBalancer, error)
4241
GetLoadBalancerByID(loadBalancerId string) (*hcn.HostComputeLoadBalancer, error)
4342
CreateLoadBalancer(loadBalancer *hcn.HostComputeLoadBalancer) (*hcn.HostComputeLoadBalancer, error)
43+
UpdateLoadBalancer(loadBalancer *hcn.HostComputeLoadBalancer, hnsID string) (*hcn.HostComputeLoadBalancer, error)
4444
DeleteLoadBalancer(loadBalancer *hcn.HostComputeLoadBalancer) error
4545
// Features functions
4646
GetSupportedFeatures() hcn.SupportedFeatures
@@ -104,6 +104,10 @@ func (hcnObj hcnImpl) CreateLoadBalancer(loadBalancer *hcn.HostComputeLoadBalanc
104104
return loadBalancer.Create()
105105
}
106106

107+
func (hcnObj hcnImpl) UpdateLoadBalancer(loadBalancer *hcn.HostComputeLoadBalancer, hnsID string) (*hcn.HostComputeLoadBalancer, error) {
108+
return loadBalancer.Update(hnsID)
109+
}
110+
107111
func (hcnObj hcnImpl) DeleteLoadBalancer(loadBalancer *hcn.HostComputeLoadBalancer) error {
108112
return loadBalancer.Delete()
109113
}
@@ -121,15 +125,16 @@ func (hcnObj hcnImpl) DsrSupported() error {
121125
}
122126

123127
func (hcnObj hcnImpl) DeleteAllHnsLoadBalancerPolicy() {
124-
plists, err := hcsshim.HNSListPolicyListRequest()
128+
lbs, err := hcnObj.ListLoadBalancers()
125129
if err != nil {
130+
klog.V(2).ErrorS(err, "Deleting all existing loadbalancers failed.")
126131
return
127132
}
128-
for _, plist := range plists {
129-
klog.V(3).InfoS("Remove policy", "policies", plist)
130-
_, err = plist.Delete()
133+
klog.V(3).InfoS("Deleting all existing loadbalancers", "lbCount", len(lbs))
134+
for _, lb := range lbs {
135+
err = lb.Delete()
131136
if err != nil {
132-
klog.ErrorS(err, "Failed to delete policy list")
137+
klog.V(2).ErrorS(err, "Error deleting existing loadbalancer", "lb", lb)
133138
}
134139
}
135140
}

pkg/proxy/winkernel/hns.go

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type HostNetworkService interface {
4040
deleteEndpoint(hnsID string) error
4141
getLoadBalancer(endpoints []endpointInfo, flags loadBalancerFlags, sourceVip string, vip string, protocol uint16, internalPort uint16, externalPort uint16, previousLoadBalancers map[loadBalancerIdentifier]*loadBalancerInfo) (*loadBalancerInfo, error)
4242
getAllLoadBalancers() (map[loadBalancerIdentifier]*loadBalancerInfo, error)
43+
updateLoadBalancer(hnsID string, sourceVip, vip string, endpoints []endpointInfo, flags loadBalancerFlags, protocol, internalPort, externalPort uint16, previousLoadBalancers map[loadBalancerIdentifier]*loadBalancerInfo) (*loadBalancerInfo, error)
4344
deleteLoadBalancer(hnsID string) error
4445
}
4546

@@ -54,6 +55,33 @@ var (
5455
LoadBalancerPortMappingFlagsVipExternalIP hcn.LoadBalancerPortMappingFlags = 16
5556
)
5657

58+
func getLoadBalancerPolicyFlags(flags loadBalancerFlags) (lbPortMappingFlags hcn.LoadBalancerPortMappingFlags, lbFlags hcn.LoadBalancerFlags) {
59+
lbPortMappingFlags = hcn.LoadBalancerPortMappingFlagsNone
60+
if flags.isILB {
61+
lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsILB
62+
}
63+
if flags.useMUX {
64+
lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsUseMux
65+
}
66+
if flags.preserveDIP {
67+
lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsPreserveDIP
68+
}
69+
if flags.localRoutedVIP {
70+
lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsLocalRoutedVIP
71+
}
72+
if flags.isVipExternalIP {
73+
lbPortMappingFlags |= LoadBalancerPortMappingFlagsVipExternalIP
74+
}
75+
lbFlags = hcn.LoadBalancerFlagsNone
76+
if flags.isDSR {
77+
lbFlags |= hcn.LoadBalancerFlagsDSR
78+
}
79+
if flags.isIPv6 {
80+
lbFlags |= LoadBalancerFlagsIPv6
81+
}
82+
return
83+
}
84+
5785
func (hns hns) getNetworkByName(name string) (*hnsNetworkInfo, error) {
5886
hnsnetwork, err := hns.hcn.GetNetworkByName(name)
5987
if err != nil {
@@ -406,6 +434,84 @@ func (hns hns) getLoadBalancer(endpoints []endpointInfo, flags loadBalancerFlags
406434
return lbInfo, err
407435
}
408436

437+
func (hns hns) updateLoadBalancer(hnsID string,
438+
sourceVip,
439+
vip string,
440+
endpoints []endpointInfo,
441+
flags loadBalancerFlags,
442+
protocol,
443+
internalPort,
444+
externalPort uint16,
445+
previousLoadBalancers map[loadBalancerIdentifier]*loadBalancerInfo) (*loadBalancerInfo, error) {
446+
klog.V(3).InfoS("Updating existing loadbalancer called", "hnsLbID", hnsID, "endpointCount", len(endpoints), "vip", vip, "sourceVip", sourceVip, "internalPort", internalPort, "externalPort", externalPort)
447+
448+
var id loadBalancerIdentifier
449+
vips := []string{}
450+
// Compute hash from backends (endpoint IDs)
451+
hash, err := hashEndpoints(endpoints)
452+
if err != nil {
453+
klog.V(2).ErrorS(err, "Error hashing endpoints", "endpoints", endpoints)
454+
return nil, err
455+
}
456+
if len(vip) > 0 {
457+
id = loadBalancerIdentifier{protocol: protocol, internalPort: internalPort, externalPort: externalPort, vip: vip, endpointsHash: hash}
458+
vips = append(vips, vip)
459+
} else {
460+
id = loadBalancerIdentifier{protocol: protocol, internalPort: internalPort, externalPort: externalPort, endpointsHash: hash}
461+
}
462+
463+
if lb, found := previousLoadBalancers[id]; found {
464+
klog.V(1).InfoS("Found cached Hns loadbalancer policy resource", "policies", lb)
465+
return lb, nil
466+
}
467+
468+
lbPortMappingFlags, lbFlags := getLoadBalancerPolicyFlags(flags)
469+
470+
lbDistributionType := hcn.LoadBalancerDistributionNone
471+
472+
if flags.sessionAffinity {
473+
lbDistributionType = hcn.LoadBalancerDistributionSourceIP
474+
}
475+
476+
loadBalancer := &hcn.HostComputeLoadBalancer{
477+
SourceVIP: sourceVip,
478+
PortMappings: []hcn.LoadBalancerPortMapping{
479+
{
480+
Protocol: uint32(protocol),
481+
InternalPort: internalPort,
482+
ExternalPort: externalPort,
483+
DistributionType: lbDistributionType,
484+
Flags: lbPortMappingFlags,
485+
},
486+
},
487+
FrontendVIPs: vips,
488+
SchemaVersion: hcn.SchemaVersion{
489+
Major: 2,
490+
Minor: 0,
491+
},
492+
Flags: lbFlags,
493+
}
494+
495+
for _, ep := range endpoints {
496+
loadBalancer.HostComputeEndpoints = append(loadBalancer.HostComputeEndpoints, ep.hnsID)
497+
}
498+
499+
lb, err := hns.hcn.UpdateLoadBalancer(loadBalancer, hnsID)
500+
501+
if err != nil {
502+
klog.V(2).ErrorS(err, "Error updating existing loadbalancer", "hnsLbID", hnsID, "error", err, "endpoints", endpoints)
503+
return nil, err
504+
}
505+
506+
klog.V(1).InfoS("Update loadbalancer is successful", "loadBalancer", lb)
507+
lbInfo := &loadBalancerInfo{
508+
hnsID: lb.Id,
509+
}
510+
// Add to map of load balancers
511+
previousLoadBalancers[id] = lbInfo
512+
return lbInfo, err
513+
}
514+
409515
func (hns hns) deleteLoadBalancer(hnsID string) error {
410516
lb, err := hns.hcn.GetLoadBalancerByID(hnsID)
411517
if err != nil {
@@ -440,7 +546,7 @@ func hashEndpoints[T string | endpointInfo](endpoints []T) (hash [20]byte, err e
440546
case endpointInfo:
441547
id = strings.ToUpper(x.hnsID)
442548
case string:
443-
id = x
549+
id = strings.ToUpper(x)
444550
}
445551
if len(id) > 0 {
446552
// We XOR the hashes of endpoints, since they are an unordered set.

0 commit comments

Comments
 (0)