Hosting Externally Accessible Services
Overview
Nodes can host services that are accessible from the internet. The experimenter adds an ingress
to a node
when modeling the experiment topology and Merge will build the network plumbing required to expose the node’s
service to the outside world when the experiment is created (materialized).
The ingress has two parts, a protocol and a port. The port is the network port on which the service on the node listens. The protocol is the expected protocol of the traffic. Depending on the protocol given, the ingress is expressed differently. There are four protocols supported and two ingress expressions. These are listed below.
Type | Hosted Service | External Access |
---|---|---|
http | web server | reverse proxy |
https | web server | reverse proxy |
tcp | port based tcp | dynamic port |
udp | port based udp | dynamic port |
The http
and https
protocols generate reverse proxy
access which is URI based. The access is via an HTTP URL.
It is deterministic (based on names given in the model and during experiment realization), thus experimenters know exactly
how to reach the node service once the experiment is realized. How to do this is explained below.
The tcp
and udp
ingresses are assigned a random gateway port at materialization time.
So experimenters do not know the exact ingress details prior to experiment materialization and the external port will
change for every materialization. Experimenters will need to ask Merge what the assigned external port is after materialization
completes.
The format of the reverse proxy path is http://[gateway]/[rid.eid.pid]/[node]/[port]
where:
Name | Description | Example |
---|---|---|
gateway | the fully qualified domain name of the testbed site gateway | ifr0.mod.deterlab.net |
rid | the name of the realization | myreal |
eid | the name of the experiment | myexperiment |
pid | the name of the project | myproject |
node | the experiment name of the node hosting the service | server1 |
port | the port on the experiment node on which the host listens | 8080 |
So given the examples in the table above, the path will be http://ifr0.mod.deterlab.net/myreal.myexperiment.myproject/server1/8080
.
Site Gateways
The fully qualified domain name of the experiment gateway may be different across realizations of an experiment depending on node and network availability at realization time. Once realized though, the domain name will not change. Always check the realization details of your experiment to confirm the name.The tcp
and udp
ingresses do not have a URL path as these services are not HTTP based. The ingress
specifies the port the service listens on. As there is no path, Merge assigns a random external port
which is then routed to the given experiment node port. This means that the experimenter needs to check
which port was assigned after experiment materialization completes.
Creating an Ingress
To create an ingress use the ingress
function on a declared node in the experiment model. The ingress
function takes two arguments: the protocol and port. The protocol type is declared by the mergexp
package
and is one of http
, https
, tcp
, or udp
. The port is a positive number and is the port on which the
host’s service will listen for connections.
Here is an example of a web server ingress on port 8080 and a tcp server on port 1234:
from mergexp import *
net = Network('ingress example')
web = net.node("webserver")
web.ingress(http, 8080)
netcat = net.node("netcat")
netcat.ingress(tcp, 1234)
net.connect([web, netcat])
experiment(net)
Note that the protocol identifiers http
, https
, tcp
, and udp
are in scope as we’ve exported *
from the
mergexp
package.
Once materialized, the http
can be accessed via the proxy path. Assuming details above the following
will work:
> curl http://ifr0.mod.deterlab.net/rlz.exp.proj/webserver/8080
And assume Merge has assigned port 8134 to the tcp
ingress. Then that service can be reached like so:
> nc -z ifr0.mod.deterlab.net 8134
Ingress Networking
The ingresses in an experiment enter the node on the infranet network as the service is reached from networks external to your experiment. So your service should bind to the infranet address of the experiment node.Ingress Details Location
The ingress details are given by the Portal is a few places. The Launch dashboard materialization synopsis, the Launch
materialization details page, or the output of the mrg show materialization
command.
The Launch dashboard gives a summary of ingresses for the materialization. http
and https
ingresses are direct links to the experiment node, The tcp
and udp
ingresses are just text.
Example:
The materialization details tab shows more information:
In the example above, the tcp
service can be reached by accessing ifr0.mod.deterlab.net
on port 8193
. The Gateway Port
field in the table is the random port chosen by Merge on the testbed gateway. This is the external port of the ingress that
routes to your experiment node service.
The http
service is at the given (and linked) URL.
The mrg
command line utility also shows ingress details of a materialization. Use the
mrg show materialization
command. It is suggested that you give the -j
option to the command to
get JSON output and parse that with jq
. The ingresses
details are in the top level of the JSON under
the “ingresses” key. Here is an example:
[glawler ~]$ mrg show materialization rlz.ingress.glawler -j | jq -r .ingresses
{
"ingresses": [
{
"mzid": "rlz.ingress.glawler",
"protocol": "http",
"hostname": "nodea",
"hostport": 8080,
"hostaddr": "172.30.0.11",
"gateway": "ifr0.mod.deterlab.net",
"gatewayport": 80,
"ingress": "http://ifr0.mod.deterlab.net:80/rlz.ingress.glawler/nodea/8080"
},
{
"mzid": "rlz.ingress.glawler",
"protocol": "tcp",
"hostname": "nodeb",
"hostport": 21234,
"hostaddr": "172.30.0.12",
"gateway": "ifr0.mod.deterlab.net",
"gatewayport": 8193,
"ingress": "ifr0.mod.deterlab.net:8193"
}
]
}
[glawler ~] $
This example shows the same two ingresses as above.
JSON output is not required of course but is easier to read in the current mrg
version. Here
is the output for the same materialization, using grep to trim to just the ingress information:
[glawler@ma0 ~]$ mrg show materialization rlz.ingress.glawler | grep ^Ingresses -A 1000
Ingresses:
nodea:8080 [http] --> http://ifr0.mod.deterlab.net:80/rlz.ingress.glawler/nodea/8080
nodeb:21234 [tcp] --> ifr0.mod.deterlab.net:8193
[glawler@ma0 ~]$
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.