In a Marathon config you can specify a block like the following to create a
port mapping to a fixed port inside of a Docker container:

...
"network": "BRIDGE",
  "portMappings": [
     { "containerPort": 8080, "hostPort": 0, "servicePort": 9000,
"protocol": "tcp" },
...
(from https://mesosphere.github.io/marathon/docs/native-docker.html)

In Marathon, the 0 for the hostPort indicates that Marathon should replace
that parameter with a random port from the available ports on a slave,
effectively passing `-p $RANDOM_PORT:8080` to the Docker cli.

AURORA-1396 gives us the ability to specify a known mapping in a config
such as:

proc = Process(cmdline = 'echo {{thermos.ports[service_name}} &&
$docker_run_command', name= ...
...
Container(docker = Docker(image = 'test/image', networking_mode='BRIDGED',
port_mappings=[DockerPortMapping(host_port = 35671, container_port = 80,
protocol = "tcp")]))
...

However, what that doesn't let you do is have a random port be substituted
in for either the host or container ports. Adding in
{{thermos.ports[service_name]}} in the Process at least allocates more
ephemeral ports as part of an offer and can be exposed through the
announcer, but right now there isn't a way to link that to the
DockerPortMapping.

The quickest way I can see to solve this is to follow the Marathon
convention and interpret a 0 in the host_port field as a request to assign
an ephemeral port to the host port and a 0 in the container_port to set the
container port equal to the host port.

proc = Process(cmdline = '$docker_run_command', name= ...
...
 Container(docker = Docker(image = 'test/image', networking_mode='BRIDGED',
port_mappings=[DockerPortMapping(host_port = 0, container_port = 80,
protocol = "tcp")]), announce = Announcer())


This eliminates the need to add an unnecessary Thermos port assignment but
at the cost of having to generate a name to use in the ServerSet, so I'd
like to get some feedback before I start working on it.

Reply via email to