Merge pull request #9951 from hashicorp/b-8284
drivers/docker: support mapping multiple host ports to the same container port
This commit is contained in:
commit
8c4481287b
|
@ -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: 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 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)]
|
* 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 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: 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)]
|
* 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)]
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getPortBinding(ip string, port string) []docker.PortBinding {
|
func getPortBinding(ip string, port string) docker.PortBinding {
|
||||||
return []docker.PortBinding{{HostIP: ip, HostPort: port}}
|
return docker.PortBinding{HostIP: ip, HostPort: port}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tweakCapabilities(basics, adds, drops []string) ([]string, error) {
|
func tweakCapabilities(basics, adds, drops []string) ([]string, error) {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package docker
|
||||||
import docker "github.com/fsouza/go-dockerclient"
|
import docker "github.com/fsouza/go-dockerclient"
|
||||||
|
|
||||||
//Currently Windows containers don't support host ip in port binding.
|
//Currently Windows containers don't support host ip in port binding.
|
||||||
func getPortBinding(ip string, port string) []docker.PortBinding {
|
func getPortBinding(ip string, port string) docker.PortBinding {
|
||||||
return []docker.PortBinding{{HostIP: "", HostPort: port}}
|
return docker.PortBinding{HostIP: "", HostPort: port}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tweakCapabilities(basics, adds, drops []string) ([]string, error) {
|
func tweakCapabilities(basics, adds, drops []string) ([]string, error) {
|
||||||
|
|
|
@ -8,6 +8,9 @@ import (
|
||||||
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
|
"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 {
|
type publishedPorts struct {
|
||||||
logger hclog.Logger
|
logger hclog.Logger
|
||||||
publishedPorts map[docker.Port][]docker.PortBinding
|
publishedPorts map[docker.Port][]docker.PortBinding
|
||||||
|
@ -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) {
|
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
|
// By default we will map the allocated port 1:1 to the container
|
||||||
containerPortInt := port
|
containerPortInt := port
|
||||||
|
@ -35,18 +38,29 @@ func (p *publishedPorts) addMapped(label, ip string, port int, portMap hclutils.
|
||||||
p.add(label, ip, port, containerPortInt)
|
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) {
|
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 {
|
if to == 0 {
|
||||||
to = port
|
to = port
|
||||||
}
|
}
|
||||||
hostPortStr := strconv.Itoa(port)
|
|
||||||
containerPort := docker.Port(strconv.Itoa(to))
|
|
||||||
|
|
||||||
p.publishedPorts[containerPort+"/tcp"] = getPortBinding(ip, hostPortStr)
|
// two docker port bindings are created for each port for tcp and udp
|
||||||
p.publishedPorts[containerPort+"/udp"] = getPortBinding(ip, hostPortStr)
|
cPortTCP := docker.Port(strconv.Itoa(to) + "/tcp")
|
||||||
p.logger.Debug("allocated static port", "ip", ip, "port", port)
|
cPortUDP := docker.Port(strconv.Itoa(to) + "/udp")
|
||||||
|
binding := getPortBinding(ip, strconv.Itoa(port))
|
||||||
|
|
||||||
p.exposedPorts[containerPort+"/tcp"] = struct{}{}
|
if _, ok := p.publishedPorts[cPortTCP]; !ok {
|
||||||
p.exposedPorts[containerPort+"/udp"] = struct{}{}
|
// initialize both tcp and udp binding slices since they are always created together
|
||||||
p.logger.Debug("exposed port", "port", port)
|
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
drivers/docker/ports_test.go
Normal file
19
drivers/docker/ports_test.go
Normal file
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in a new issue