Skip to content

Commit

Permalink
Merge pull request #9951 from hashicorp/b-8284
Browse files Browse the repository at this point in the history
drivers/docker: support mapping multiple host ports to the same container port
  • Loading branch information
nickethier committed Feb 3, 2021
2 parents 4e0e33e + 9e34855 commit 434f4b4
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ BUG FIXES:
* consul: Fixed a bug where failing tasks with group services would only cause the allocation to restart once instead of respecting the `restart` field. [[GH-9869](https://github.com/hashicorp/nomad/issues/9869)]
* consul/connect: Fixed a bug where gateway proxy connection default timeout not set [[GH-9851](https://github.com/hashicorp/nomad/pull/9851)]
* consul/connect: Fixed a bug preventing more than one connect gateway per Nomad client [[GH-9849](https://github.com/hashicorp/nomad/pull/9849)]
* drivers/docker: Fixed a bug preventing multiple ports to be mapped to the same container port [[GH-9951](https://github.com/hashicorp/nomad/issues/9951)]
* scheduler: Fixed a bug where shared ports were not persisted during inplace updates for service jobs. [[GH-9830](https://github.com/hashicorp/nomad/issues/9830)]
* scheduler: Fixed a bug where job statuses and summaries where duplicated and miscalculated when registering a job. [[GH-9768](https://github.com/hashicorp/nomad/issues/9768)]
* scheduler (Enterprise): Fixed a bug where the deprecated network `mbits` field was being considered as part of quota enforcement. [[GH-9920](https://github.com/hashicorp/nomad/issues/9920)]
Expand Down
4 changes: 2 additions & 2 deletions drivers/docker/driver_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
docker "github.com/fsouza/go-dockerclient"
)

func getPortBinding(ip string, port string) []docker.PortBinding {
return []docker.PortBinding{{HostIP: ip, HostPort: port}}
func getPortBinding(ip string, port string) docker.PortBinding {
return docker.PortBinding{HostIP: ip, HostPort: port}
}

func tweakCapabilities(basics, adds, drops []string) ([]string, error) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/docker/driver_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package docker
import docker "github.com/fsouza/go-dockerclient"

//Currently Windows containers don't support host ip in port binding.
func getPortBinding(ip string, port string) []docker.PortBinding {
return []docker.PortBinding{{HostIP: "", HostPort: port}}
func getPortBinding(ip string, port string) docker.PortBinding {
return docker.PortBinding{HostIP: "", HostPort: port}
}

func tweakCapabilities(basics, adds, drops []string) ([]string, error) {
Expand Down
32 changes: 23 additions & 9 deletions drivers/docker/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
)

// publishedPorts is a utility struct to keep track of the port bindings to publish.
// After calling add for each port, the publishedPorts and exposedPorts fields can be
// used in the docker container and host configs
type publishedPorts struct {
logger hclog.Logger
publishedPorts map[docker.Port][]docker.PortBinding
Expand All @@ -22,7 +25,7 @@ func newPublishedPorts(logger hclog.Logger) *publishedPorts {
}
}

// adds the port to the structures the Docker API expects for declaring mapped ports
// addMapped adds the port to the structures the Docker API expects for declaring mapped ports
func (p *publishedPorts) addMapped(label, ip string, port int, portMap hclutils.MapStrInt) {
// By default we will map the allocated port 1:1 to the container
containerPortInt := port
Expand All @@ -35,18 +38,29 @@ func (p *publishedPorts) addMapped(label, ip string, port int, portMap hclutils.
p.add(label, ip, port, containerPortInt)
}

// add adds a port binding for the given port mapping
func (p *publishedPorts) add(label, ip string, port, to int) {
// if to is not set, use the port value per default docker functionality
if to == 0 {
to = port
}
hostPortStr := strconv.Itoa(port)
containerPort := docker.Port(strconv.Itoa(to))

p.publishedPorts[containerPort+"/tcp"] = getPortBinding(ip, hostPortStr)
p.publishedPorts[containerPort+"/udp"] = getPortBinding(ip, hostPortStr)
p.logger.Debug("allocated static port", "ip", ip, "port", port)
// two docker port bindings are created for each port for tcp and udp
cPortTCP := docker.Port(strconv.Itoa(to) + "/tcp")
cPortUDP := docker.Port(strconv.Itoa(to) + "/udp")
binding := getPortBinding(ip, strconv.Itoa(port))

p.exposedPorts[containerPort+"/tcp"] = struct{}{}
p.exposedPorts[containerPort+"/udp"] = struct{}{}
p.logger.Debug("exposed port", "port", port)
if _, ok := p.publishedPorts[cPortTCP]; !ok {
// initialize both tcp and udp binding slices since they are always created together
p.publishedPorts[cPortTCP] = []docker.PortBinding{}
p.publishedPorts[cPortUDP] = []docker.PortBinding{}
}

p.publishedPorts[cPortTCP] = append(p.publishedPorts[cPortTCP], binding)
p.publishedPorts[cPortUDP] = append(p.publishedPorts[cPortUDP], binding)
p.logger.Debug("allocated static port", "ip", ip, "port", port, "label", label)

p.exposedPorts[cPortTCP] = struct{}{}
p.exposedPorts[cPortUDP] = struct{}{}
p.logger.Debug("exposed port", "port", port, "label", label)
}
19 changes: 19 additions & 0 deletions drivers/docker/ports_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package docker

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/hashicorp/nomad/helper/testlog"
)

func TestPublishedPorts_add(t *testing.T) {
p := newPublishedPorts(testlog.HCLogger(t))
p.add("label", "10.0.0.1", 1234, 80)
p.add("label", "10.0.0.1", 5678, 80)
for _, bindings := range p.publishedPorts {
require.Len(t, bindings, 2)
}
require.Len(t, p.exposedPorts, 2)
}

0 comments on commit 434f4b4

Please sign in to comment.