Skip to content
This repository was archived by the owner on May 18, 2026. It is now read-only.

Commit e6c5543

Browse files
committed
Give each overlay container its own designated IP from the band
Instead of all containers trying the same candidate list and competing (causing allocation failures), each container now gets only its specific IP based on its overlay index within the config.
1 parent 7f45979 commit e6c5543

1 file changed

Lines changed: 18 additions & 8 deletions

File tree

main.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ func (m *manager) run(config *Config) {
220220
}
221221
m.l.WithField("networks", networkNames).Debugf("Networks: %s", networkNames)
222222

223+
overlayIndex := 0
223224
for _, c := range config.Containers {
224225

225226
var networks []string = nil
@@ -229,14 +230,19 @@ func (m *manager) run(config *Config) {
229230
}
230231
networks = lo.Ternary(len(networks) > 0, networks, []string{"bridge"})
231232

232-
err = m.ensureContainer(c, networks)
233+
currentIndex := overlayIndex
234+
if c.AttachAllNetwork {
235+
overlayIndex++
236+
}
237+
238+
err = m.ensureContainer(c, networks, currentIndex)
233239
if err != nil {
234240
m.l.WithField("name", c.Name).WithError(err).Errorf("failed to enure container %s", c.Name)
235241
}
236242
}
237243
}
238244

239-
func (m *manager) ensureContainer(config Container, networks []string) error {
245+
func (m *manager) ensureContainer(config Container, networks []string, overlayIndex int) error {
240246
containers, err := m.cli.ContainerList(m.ctx, container.ListOptions{All: true, Filters: filters.NewArgs(filters.Arg("name", fmt.Sprintf("^/%s$", config.Name)))})
241247
if err != nil {
242248
return err
@@ -282,7 +288,7 @@ func (m *manager) ensureContainer(config Container, networks []string) error {
282288
return e.Name == config.Name
283289
})
284290
if !alreadyAttached {
285-
m.connectNetworkHighIP(n, config.Name, config.Name)
291+
m.connectNetworkHighIP(n, config.Name, config.Name, overlayIndex)
286292
}
287293
}
288294

@@ -409,7 +415,7 @@ func (m *manager) ensureContainer(config Container, networks []string) error {
409415
// Connect networks after start so overlay handshakes happen immediately
410416
// and NetworkConnect returns the real error on IP conflict
411417
for _, n := range networks {
412-
m.connectNetworkHighIP(n, c.ID, config.Name)
418+
m.connectNetworkHighIP(n, c.ID, config.Name, overlayIndex)
413419
}
414420

415421
return nil
@@ -509,8 +515,8 @@ func (m *manager) detachNetwork(network string, container string) {
509515
// connectNetworkHighIP connects a container to a network using an IP from the
510516
// upper end of the subnet. If the chosen IP conflicts, it falls back to
511517
// Docker-assigned.
512-
func (m *manager) connectNetworkHighIP(networkName string, containerID string, containerName string) {
513-
candidates := m.highIPCandidates(networkName)
518+
func (m *manager) connectNetworkHighIP(networkName string, containerID string, containerName string, overlayIndex int) {
519+
candidates := m.highIPCandidates(networkName, overlayIndex)
514520
if candidates == nil {
515521
err := m.cli.NetworkConnect(m.ctx, networkName, containerID, nil)
516522
if err != nil {
@@ -542,7 +548,7 @@ func (m *manager) connectNetworkHighIP(networkName string, containerID string, c
542548

543549
// highIPCandidates returns IPs from a tight band at the top of the network's
544550
// subnet, using the overlay Peers list for deterministic per-node positioning.
545-
func (m *manager) highIPCandidates(networkName string) []net.IP {
551+
func (m *manager) highIPCandidates(networkName string, overlayIndex int) []net.IP {
546552
networkInfo, err := m.cli.NetworkInspect(m.ctx, networkName, types.NetworkInspectOptions{})
547553
if err != nil {
548554
return nil
@@ -574,7 +580,11 @@ func (m *manager) highIPCandidates(networkName string) []net.IP {
574580
peerIPs[i] = p.IP
575581
}
576582

577-
return computeIPCandidates(ipNet, peerIPs, m.nodeAddr, m.overlayContainers)
583+
candidates := computeIPCandidates(ipNet, peerIPs, m.nodeAddr, m.overlayContainers)
584+
if overlayIndex >= len(candidates) {
585+
return nil
586+
}
587+
return []net.IP{candidates[overlayIndex]}
578588
}
579589

580590
func computeIPCandidates(ipNet *net.IPNet, peerIPs []string, nodeAddr string, overlayContainers int) []net.IP {

0 commit comments

Comments
 (0)