Skip to content

Commit 38585b4

Browse files
committed
manager/allocator: lift portAllocator out of CNM
The port allocation logic does not depend on the network allocator implementation in any meaningful way. It has no knowledge of the CNM network allocator's state, and it does not need to change if the network allocator changes. Allocating node ports is fundamentally a seaparate concern from allocating network resources for services and tasks. Therefore the low-level network allocator should not be responsible for allocating both. Lift the port allocator into the Allocator's network context as a sibling of the low-level network allocator. Signed-off-by: Cory Snider <[email protected]>
1 parent 196c38f commit 38585b4

File tree

6 files changed

+59
-45
lines changed

6 files changed

+59
-45
lines changed

manager/allocator/cnmallocator/networkallocator.go

-24
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ type cnmNetworkAllocator struct {
4040
// The driver registry for all internal and external network drivers.
4141
networkRegistry drvregistry.Networks
4242

43-
// The port allocator instance for allocating node ports
44-
portAllocator *portAllocator
45-
4643
// Local network state used by cnmNetworkAllocator to do network management.
4744
networks map[string]*network
4845

@@ -108,8 +105,6 @@ func New(pg plugingetter.PluginGetter, netConfig *NetworkConfig) (networkallocat
108105
tasks: make(map[string]struct{}),
109106
nodes: make(map[string]map[string]struct{}),
110107
pg: pg,
111-
112-
portAllocator: newPortAllocator(),
113108
}
114109

115110
for ntype, i := range initializers {
@@ -207,9 +202,6 @@ func (na *cnmNetworkAllocator) Deallocate(n *api.Network) error {
207202
// AllocateService allocates all the network resources such as virtual
208203
// IP and ports needed by the service.
209204
func (na *cnmNetworkAllocator) AllocateService(s *api.Service) (err error) {
210-
if err = na.portAllocator.serviceAllocatePorts(s); err != nil {
211-
return err
212-
}
213205
defer func() {
214206
if err != nil {
215207
na.DeallocateService(s)
@@ -312,7 +304,6 @@ func (na *cnmNetworkAllocator) DeallocateService(s *api.Service) error {
312304
}
313305
s.Endpoint.VirtualIPs = nil
314306

315-
na.portAllocator.serviceDeallocatePorts(s)
316307
delete(na.services, s.ID)
317308

318309
return nil
@@ -369,19 +360,8 @@ func (na *cnmNetworkAllocator) IsTaskAllocated(t *api.Task) bool {
369360
return true
370361
}
371362

372-
// HostPublishPortsNeedUpdate returns true if the passed service needs
373-
// allocations for its published ports in host (non ingress) mode
374-
func (na *cnmNetworkAllocator) HostPublishPortsNeedUpdate(s *api.Service) bool {
375-
return na.portAllocator.hostPublishPortsNeedUpdate(s)
376-
}
377-
378363
// IsServiceAllocated returns false if the passed service needs to have network resources allocated/updated.
379364
func (na *cnmNetworkAllocator) IsServiceAllocated(s *api.Service, flags ...func(*networkallocator.ServiceAllocationOpts)) bool {
380-
var options networkallocator.ServiceAllocationOpts
381-
for _, flag := range flags {
382-
flag(&options)
383-
}
384-
385365
specNetworks := serviceNetworks(s)
386366

387367
// If endpoint mode is VIP and allocator does not have the
@@ -443,10 +423,6 @@ func (na *cnmNetworkAllocator) IsServiceAllocated(s *api.Service, flags ...func(
443423
}
444424
}
445425

446-
if (s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0) ||
447-
(s.Endpoint != nil && len(s.Endpoint.Ports) != 0) {
448-
return na.portAllocator.isPortsAllocatedOnInit(s, options.OnInit)
449-
}
450426
return true
451427
}
452428

manager/allocator/cnmallocator/networkallocator_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,11 @@ func TestAllocateService(t *testing.T) {
564564
err = na.AllocateService(s)
565565
assert.NoError(t, err)
566566
assert.Equal(t, 2, len(s.Endpoint.Ports))
567-
assert.True(t, s.Endpoint.Ports[0].PublishedPort >= dynamicPortStart &&
568-
s.Endpoint.Ports[0].PublishedPort <= dynamicPortEnd)
569-
assert.True(t, s.Endpoint.Ports[1].PublishedPort >= dynamicPortStart &&
570-
s.Endpoint.Ports[1].PublishedPort <= dynamicPortEnd)
567+
assert.True(t, s.Endpoint.Ports[0].PublishedPort >= 1 &&
568+
s.Endpoint.Ports[0].PublishedPort <= 65535)
569+
assert.True(t, s.Endpoint.Ports[1].PublishedPort >= 1 &&
570+
s.Endpoint.Ports[1].PublishedPort <= 65535)
571+
assert.NotEqual(t, s.Endpoint.Ports[0].PublishedPort, s.Endpoint.Ports[1].PublishedPort)
571572

572573
assert.Equal(t, 1, len(s.Endpoint.VirtualIPs))
573574

manager/allocator/network.go

+52-11
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ type networkContext struct {
3737
// the actual network allocation.
3838
nwkAllocator networkallocator.NetworkAllocator
3939

40+
// The port allocator instance for allocating node ports
41+
portAllocator *portAllocator
42+
4043
// A set of tasks which are ready to be allocated as a batch. This is
4144
// distinct from "unallocatedTasks" which are tasks that failed to
4245
// allocate on the first try, being held for a future retry.
@@ -95,6 +98,7 @@ func (a *Allocator) doNetworkInit(ctx context.Context) (err error) {
9598

9699
nc := &networkContext{
97100
nwkAllocator: na,
101+
portAllocator: newPortAllocator(),
98102
pendingTasks: make(map[string]*api.Task),
99103
unallocatedTasks: make(map[string]*api.Task),
100104
unallocatedServices: make(map[string]*api.Service),
@@ -233,7 +237,7 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) {
233237
break
234238
}
235239

236-
if nc.nwkAllocator.IsServiceAllocated(s) {
240+
if nc.isServiceAllocated(s) {
237241
break
238242
}
239243

@@ -261,8 +265,8 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) {
261265
break
262266
}
263267

264-
if nc.nwkAllocator.IsServiceAllocated(s) {
265-
if !nc.nwkAllocator.HostPublishPortsNeedUpdate(s) {
268+
if nc.isServiceAllocated(s) {
269+
if !nc.portAllocator.hostPublishPortsNeedUpdate(s) {
266270
break
267271
}
268272
updatePortsInHostPublishMode(s)
@@ -284,7 +288,7 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) {
284288
case api.EventDeleteService:
285289
s := v.Service.Copy()
286290

287-
if err := nc.nwkAllocator.DeallocateService(s); err != nil {
291+
if err := nc.deallocateService(s); err != nil {
288292
log.G(ctx).WithError(err).Errorf("Failed deallocation during delete of service %s", s.ID)
289293
} else {
290294
nc.somethingWasDeallocated = true
@@ -681,7 +685,7 @@ func (a *Allocator) allocateServices(ctx context.Context, existingAddressesOnly
681685

682686
var allocatedServices []*api.Service
683687
for _, s := range services {
684-
if nc.nwkAllocator.IsServiceAllocated(s, networkallocator.OnInit) {
688+
if nc.isServiceAllocated(s, networkallocator.OnInit) {
685689
continue
686690
}
687691
if existingAddressesOnly &&
@@ -713,6 +717,23 @@ func (a *Allocator) allocateServices(ctx context.Context, existingAddressesOnly
713717
return nil
714718
}
715719

720+
// isServiceAllocated returns false if the passed service needs to have network resources allocated/updated.
721+
func (nc *networkContext) isServiceAllocated(s *api.Service, flags ...func(*networkallocator.ServiceAllocationOpts)) bool {
722+
if !nc.nwkAllocator.IsServiceAllocated(s, flags...) {
723+
return false
724+
}
725+
726+
var options networkallocator.ServiceAllocationOpts
727+
for _, flag := range flags {
728+
flag(&options)
729+
}
730+
if (s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0) ||
731+
(s.Endpoint != nil && len(s.Endpoint.Ports) != 0) {
732+
return nc.portAllocator.isPortsAllocatedOnInit(s, options.OnInit)
733+
}
734+
return true
735+
}
736+
716737
// allocateTasks allocates tasks in the store so far before we started watching.
717738
func (a *Allocator) allocateTasks(ctx context.Context, existingAddressesOnly bool) error {
718739
var (
@@ -815,7 +836,7 @@ func taskReadyForNetworkVote(t *api.Task, s *api.Service, nc *networkContext) bo
815836
// network configured or service endpoints have been
816837
// allocated.
817838
return (len(t.Networks) == 0 || nc.nwkAllocator.IsTaskAllocated(t)) &&
818-
(s == nil || nc.nwkAllocator.IsServiceAllocated(s))
839+
(s == nil || nc.isServiceAllocated(s))
819840
}
820841

821842
func taskUpdateNetworks(t *api.Task, networks []*api.NetworkAttachment) {
@@ -1200,13 +1221,13 @@ func (a *Allocator) allocateService(ctx context.Context, s *api.Service, existin
12001221
// is not there
12011222
// service has no user-defined endpoints while has already allocated network resources,
12021223
// need deallocated.
1203-
if err := nc.nwkAllocator.DeallocateService(s); err != nil {
1224+
if err := nc.deallocateService(s); err != nil {
12041225
return err
12051226
}
12061227
nc.somethingWasDeallocated = true
12071228
}
12081229

1209-
if err := nc.nwkAllocator.AllocateService(s); err != nil {
1230+
if err := nc.allocateService(s); err != nil {
12101231
nc.unallocatedServices[s.ID] = s
12111232
return err
12121233
}
@@ -1229,6 +1250,26 @@ func (a *Allocator) allocateService(ctx context.Context, s *api.Service, existin
12291250
return nil
12301251
}
12311252

1253+
func (nc *networkContext) allocateService(s *api.Service) error {
1254+
if err := nc.portAllocator.serviceAllocatePorts(s); err != nil {
1255+
return err
1256+
}
1257+
if err := nc.nwkAllocator.AllocateService(s); err != nil {
1258+
nc.portAllocator.serviceDeallocatePorts(s)
1259+
return err
1260+
}
1261+
1262+
return nil
1263+
}
1264+
1265+
func (nc *networkContext) deallocateService(s *api.Service) error {
1266+
if err := nc.nwkAllocator.DeallocateService(s); err != nil {
1267+
return err
1268+
}
1269+
nc.portAllocator.serviceDeallocatePorts(s)
1270+
return nil
1271+
}
1272+
12321273
func (a *Allocator) commitAllocatedService(ctx context.Context, batch *store.Batch, s *api.Service) error {
12331274
if err := batch.Update(func(tx store.Tx) error {
12341275
err := store.UpdateService(tx, s)
@@ -1241,7 +1282,7 @@ func (a *Allocator) commitAllocatedService(ctx context.Context, batch *store.Bat
12411282

12421283
return errors.Wrapf(err, "failed updating state in store transaction for service %s", s.ID)
12431284
}); err != nil {
1244-
if err := a.netCtx.nwkAllocator.DeallocateService(s); err != nil {
1285+
if err := a.netCtx.deallocateService(s); err != nil {
12451286
log.G(ctx).WithError(err).Errorf("failed rolling back allocation of service %s", s.ID)
12461287
}
12471288

@@ -1298,7 +1339,7 @@ func (a *Allocator) allocateTask(ctx context.Context, t *api.Task) (err error) {
12981339
return
12991340
}
13001341

1301-
if !nc.nwkAllocator.IsServiceAllocated(s) {
1342+
if !nc.isServiceAllocated(s) {
13021343
err = fmt.Errorf("service %s to which task %s belongs has pending allocations", s.ID, t.ID)
13031344
return
13041345
}
@@ -1423,7 +1464,7 @@ func (a *Allocator) procUnallocatedServices(ctx context.Context) {
14231464
nc := a.netCtx
14241465
var allocatedServices []*api.Service
14251466
for _, s := range nc.unallocatedServices {
1426-
if !nc.nwkAllocator.IsServiceAllocated(s) {
1467+
if !nc.isServiceAllocated(s) {
14271468
if err := a.allocateService(ctx, s, false); err != nil {
14281469
log.G(ctx).WithError(err).Debugf("Failed allocation of unallocated service %s", s.ID)
14291470
continue

manager/allocator/networkallocator/networkallocator.go

-4
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ type NetworkAllocator interface {
6161
// virtual IP and ports associated with the service.
6262
DeallocateService(s *api.Service) error
6363

64-
// HostPublishPortsNeedUpdate returns true if the passed service needs
65-
// allocations for its published ports in host (non ingress) mode
66-
HostPublishPortsNeedUpdate(s *api.Service) bool
67-
6864
//
6965
// Task Allocation
7066
//

manager/allocator/cnmallocator/portallocator.go manager/allocator/portallocator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package cnmallocator
1+
package allocator
22

33
import (
44
"github.com/moby/swarmkit/v2/api"

manager/allocator/cnmallocator/portallocator_test.go manager/allocator/portallocator_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package cnmallocator
1+
package allocator
22

33
import (
44
"testing"

0 commit comments

Comments
 (0)