Compare commits

...

8 commits
v0.0.2 ... main

Author SHA1 Message Date
4361c1eb11 add transparenz background 2024-03-19 22:45:43 +01:00
616572fab8 fix README 2024-03-19 21:50:55 +01:00
56ee3e242f fix README 2024-03-19 21:50:03 +01:00
c0035c2b89 change README 2024-03-19 21:14:09 +01:00
9b0c4efe56 fix get random color 2024-03-19 20:57:48 +01:00
MuratovAS
84387e105d
Update docker-network-graph.py 2024-01-14 03:28:30 +05:00
MuratovAS
e13dcacb0a
add example 2024-01-14 03:19:45 +05:00
MuratovAS
2492ba0646
visualization of ports 2024-01-14 03:18:42 +05:00
5 changed files with 271 additions and 23 deletions

2
.gitignore vendored
View file

@ -1,6 +1,4 @@
*.gv
*.pdf
*.png
*.svg
.idea
/output

View file

@ -3,15 +3,16 @@
Visualize the relationship between Docker networks and containers
as a neat graphviz graph.
This repository fork [e-dant/docker-network-graph](https://github.com/e-dant/docker-network-graph)
This repository fork [MuratovAS/docker-network-graph](https://github.com/MuratovAS/docker-network-graph)
Changes:
- Improved design
- Added the ability to generate url
- Added display of connections with the host
- Visualization of ports
- Github package
## Example
![example graph](./example.png)
![example graph](./example.svg)
## Usage
```bash
@ -28,8 +29,22 @@ Changes:
If you want to generate a graph for a remote system you can also easily
run this script inside a pre-built docker container:
build container
```bash
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/muratovas/docker-network-graph:latest -u
docker build . -t code.brothertec.eu/simono41/docker-network-graph:latest
```
and create a PNG
```bash
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock code.brothertec.eu/simono41/docker-network-graph:latest | dot -Tpng -o out.png
```
or as SVG
```bash
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock code.brothertec.eu/simono41/docker-network-graph:latest | dot -Tsvg -o out.svg
```
For more advanced use cases you can append arguments to the `docker run`
@ -39,7 +54,7 @@ command as if you were running it in a local shell.
In most cases what you want to run are the following couple commands:
```bash
git clone https://github.com/muratovas/docker-network-graph.git
git clone https://code.brothertec.eu/simono41/docker-network-graph.git
cd docker-network-graph
pipenv install
pipenv run python docker-network-graph.py -o output.svg

View file

@ -23,6 +23,14 @@ services:
- network_b
- network_c
- no_gateway
service_4:
container_name: service_4
image: leoverto/dummy-image
ports:
- "1234:1234"
- "0.0.0.0:5678:5678/udp"
networks:
- internet
host_service:
container_name: host_service
image: leoverto/dummy-image
@ -33,6 +41,9 @@ services:
network_mode: none
networks:
internet:
driver_opts:
com.docker.network.bridge.enable_icc: "false"
network_a:
network_b:
network_c:

View file

@ -23,7 +23,7 @@ COLORS = [
"#b2df8a",
"#fdbf6f",
"#cab2d6",
"#ffff99",
"#90f530",
"#0d8bad",
"#e98420",
"#0e9997",
@ -50,12 +50,16 @@ class Interface:
address: str
aliases: typing.List[str]
@dataclass
class Port:
port: str
@dataclass
class Container:
container_id: str
name: str
interfaces: typing.List[Interface]
ports: typing.List[Interface]
@dataclass
@ -73,11 +77,10 @@ def get_unique_color() -> str:
i += 1
else:
# Generate random color if we've already used the 12 preset ones
c = '#'.join([f"{random.randint(0, 255):02x}" for _ in range(3)])
c = "#{:06x}".format(random.randint(0, 0xFFFFFF))
return c
def get_networks(
client: docker.DockerClient, verbose: bool
) -> typing.Dict[str, Network]:
@ -86,7 +89,7 @@ def get_networks(
for net in sorted(client.networks.list(), key=lambda k: k.name):
try:
gateway = net.attrs["IPAM"]["Config"][0]["Subnet"]
except (KeyError, IndexError):
except (KeyError, IndexError, TypeError):
# This network doesn't seem to be used, skip it
continue
@ -125,11 +128,13 @@ def get_containers(
for container in client.containers.list():
interfaces: typing.List[Interface] = []
ports: typing.List[Port] = []
for port_name, port_info in container.attrs["NetworkSettings"]["Ports"].items():
ports.append(Port(port_name))
# Iterate over container interfaces
for net_name, net_info in container.attrs["NetworkSettings"][
"Networks"
].items():
for net_name, net_info in container.attrs["NetworkSettings"]["Networks"].items():
endpoint_id = net_info["EndpointID"]
aliases = []
@ -143,11 +148,9 @@ def get_containers(
links.append(Link(container.id, endpoint_id, net_name))
if verbose:
print(
f"Container: {container.name} {''.join([iface.address for iface in interfaces])}"
)
print(f"Container: {container.name} {ports} {''.join([iface.address for iface in interfaces])}")
containers.append(Container(container.id, container.name, interfaces))
containers.append(Container(container.id, container.name, interfaces, ports))
return containers, links
@ -172,6 +175,12 @@ def draw_network(g: Graph, net: Network):
def draw_container(g: Graph, c: Container):
iface_labels = []
port_labels = []
for iport in c.ports:
port_label = "{"
port_label += f"{iport.port} }}"
port_labels.append(port_label)
for iface in c.interfaces:
iface_label = "{"
@ -181,8 +190,11 @@ def draw_container(g: Graph, c: Container):
iface_label += f"<{iface.endpoint_id}> {iface.address} }}"
iface_labels.append(iface_label)
label = f"{{ {c.name} | {{ {' | '.join(iface_labels)} }} }}"
label =f"{{ {c.name} "
if port_labels:
label = label + f"| {{ {' | '.join(port_labels)} }} "
label = label + f"| {{ {' | '.join(iface_labels)} }} }}"
g.node(
f"container_{c.container_id}",
@ -221,13 +233,13 @@ def generate_graph(verbose: bool, file: str, url: str):
comment="Docker Network Graph",
engine="sfdp",
format=ext[1:],
graph_attr=dict(splines="true"),
graph_attr=dict(splines="true", rankdir="LR", bgcolor="transparent"),
)
else:
g = Graph(
comment="Docker Network Graph",
engine="sfdp",
graph_attr=dict(splines="true"),
graph_attr=dict(splines="true", rankdir="LR", bgcolor="transparent"),
)
for _, network in networks.items():
@ -273,4 +285,4 @@ if __name__ == "__main__":
parser.add_argument("-u", "--url", help="generate link for GraphvizOnline", action="store_true")
args = parser.parse_args()
generate_graph(args.verbose, args.out, args.url)
generate_graph(args.verbose, args.out, args.url)

212
example.svg Normal file
View file

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
-->
<!-- Title: %0 Pages: 1 -->
<svg width="1304pt" height="243pt" viewBox="0.00 0.00 1304.31 243.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 239)">
<title>%0</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-239 1300.3072,-239 1300.3072,4 -4,4"/>
<!-- network_bridge -->
<g id="node1" class="node">
<title>network_bridge</title>
<path fill="#1f78b4" fill-opacity="0.376471" stroke="#1f78b4" stroke-opacity="0.376471" d="M30.3198,-80.3C30.3198,-80.3 60.3198,-80.3 60.3198,-80.3 66.3198,-80.3 72.3198,-86.3 72.3198,-92.3 72.3198,-92.3 72.3198,-104.3 72.3198,-104.3 72.3198,-110.3 66.3198,-116.3 60.3198,-116.3 60.3198,-116.3 30.3198,-116.3 30.3198,-116.3 24.3198,-116.3 18.3198,-110.3 18.3198,-104.3 18.3198,-104.3 18.3198,-92.3 18.3198,-92.3 18.3198,-86.3 24.3198,-80.3 30.3198,-80.3"/>
<text text-anchor="middle" x="45.2027" y="-94.2" font-family="Times,serif" font-size="14.00" fill="#000000">bridge</text>
</g>
<!-- network_host -->
<g id="node7" class="node">
<title>network_host</title>
<path fill="#808080" fill-opacity="0.376471" stroke="#808080" stroke-opacity="0.376471" d="M613.3198,-.5C613.3198,-.5 643.3198,-.5 643.3198,-.5 649.3198,-.5 655.3198,-6.5 655.3198,-12.5 655.3198,-12.5 655.3198,-24.5 655.3198,-24.5 655.3198,-30.5 649.3198,-36.5 643.3198,-36.5 643.3198,-36.5 613.3198,-36.5 613.3198,-36.5 607.3198,-36.5 601.3198,-30.5 601.3198,-24.5 601.3198,-24.5 601.3198,-12.5 601.3198,-12.5 601.3198,-6.5 607.3198,-.5 613.3198,-.5"/>
<text text-anchor="middle" x="627.9874" y="-14.4" font-family="Times,serif" font-size="14.00" fill="#000000">host</text>
</g>
<!-- network_bridge&#45;&#45;network_host -->
<g id="edge12" class="edge">
<title>network_bridge--network_host</title>
<path fill="none" stroke="#808080" stroke-dasharray="1,5" d="M67.5657,-80.0812C71.9122,-77.2896 76.5941,-74.757 81.3198,-73 178.4884,-36.8744 504.6733,-22.8138 601.1943,-19.385"/>
</g>
<!-- network_docker&#45;network&#45;graph_internet -->
<g id="node2" class="node">
<title>network_docker-network-graph_internet</title>
<path fill="#33a02c" fill-opacity="0.376471" stroke="#33a02c" stroke-opacity="0.376471" d="M101.8597,-73.5C101.8597,-73.5 268.7799,-73.5 268.7799,-73.5 274.7799,-73.5 280.7799,-79.5 280.7799,-85.5 280.7799,-85.5 280.7799,-111.1 280.7799,-111.1 280.7799,-117.1 274.7799,-123.1 268.7799,-123.1 268.7799,-123.1 101.8597,-123.1 101.8597,-123.1 95.8597,-123.1 89.8597,-117.1 89.8597,-111.1 89.8597,-111.1 89.8597,-85.5 89.8597,-85.5 89.8597,-79.5 95.8597,-73.5 101.8597,-73.5"/>
<text text-anchor="middle" x="185.3198" y="-106.5" font-family="Times,serif" font-size="14.00" fill="#000000">docker-network-graph_internet</text>
<polyline fill="none" stroke="#33a02c" stroke-opacity="0.376471" points="89.8597,-98.3 280.7799,-98.3 "/>
<text text-anchor="middle" x="185.3198" y="-81.7" font-family="Times,serif" font-size="14.00" fill="#000000">Containers isolated</text>
</g>
<!-- network_docker&#45;network&#45;graph_internet&#45;&#45;network_host -->
<g id="edge13" class="edge">
<title>network_docker-network-graph_internet--network_host</title>
<path fill="none" stroke="#808080" stroke-dasharray="1,5" d="M281.026,-74.7156C283.8183,-74.1244 286.5875,-73.5511 289.3198,-73 404.4333,-49.7829 543.1284,-30.0247 600.9438,-22.1505"/>
</g>
<!-- network_docker&#45;network&#45;graph_network_a -->
<g id="node3" class="node">
<title>network_docker-network-graph_network_a</title>
<path fill="#e31a1c" fill-opacity="0.376471" stroke="#e31a1c" stroke-opacity="0.376471" d="M310.697,-80.3C310.697,-80.3 493.9426,-80.3 493.9426,-80.3 499.9426,-80.3 505.9426,-86.3 505.9426,-92.3 505.9426,-92.3 505.9426,-104.3 505.9426,-104.3 505.9426,-110.3 499.9426,-116.3 493.9426,-116.3 493.9426,-116.3 310.697,-116.3 310.697,-116.3 304.697,-116.3 298.697,-110.3 298.697,-104.3 298.697,-104.3 298.697,-92.3 298.697,-92.3 298.697,-86.3 304.697,-80.3 310.697,-80.3"/>
<text text-anchor="middle" x="402.3198" y="-94.2" font-family="Times,serif" font-size="14.00" fill="#000000">docker-network-graph_network_a</text>
</g>
<!-- network_docker&#45;network&#45;graph_network_a&#45;&#45;network_host -->
<g id="edge14" class="edge">
<title>network_docker-network-graph_network_a--network_host</title>
<path fill="none" stroke="#808080" stroke-dasharray="1,5" d="M453.3204,-80.2918C499.1467,-64.1107 564.6764,-40.9723 601.1572,-28.091"/>
</g>
<!-- network_docker&#45;network&#45;graph_network_b -->
<g id="node4" class="node">
<title>network_docker-network-graph_network_b</title>
<path fill="#ff7f00" fill-opacity="0.376471" stroke="#ff7f00" stroke-opacity="0.376471" d="M536.3043,-80.3C536.3043,-80.3 720.3353,-80.3 720.3353,-80.3 726.3353,-80.3 732.3353,-86.3 732.3353,-92.3 732.3353,-92.3 732.3353,-104.3 732.3353,-104.3 732.3353,-110.3 726.3353,-116.3 720.3353,-116.3 720.3353,-116.3 536.3043,-116.3 536.3043,-116.3 530.3043,-116.3 524.3043,-110.3 524.3043,-104.3 524.3043,-104.3 524.3043,-92.3 524.3043,-92.3 524.3043,-86.3 530.3043,-80.3 536.3043,-80.3"/>
<text text-anchor="middle" x="628.3198" y="-94.2" font-family="Times,serif" font-size="14.00" fill="#000000">docker-network-graph_network_b</text>
</g>
<!-- network_docker&#45;network&#45;graph_network_b&#45;&#45;network_host -->
<g id="edge15" class="edge">
<title>network_docker-network-graph_network_b--network_host</title>
<path fill="none" stroke="#808080" stroke-dasharray="1,5" d="M628.3198,-80.1921C628.3198,-67.1324 628.3198,-49.5795 628.3198,-36.5362"/>
</g>
<!-- network_docker&#45;network&#45;graph_network_c -->
<g id="node5" class="node">
<title>network_docker-network-graph_network_c</title>
<path fill="#6a3d9a" fill-opacity="0.376471" stroke="#6a3d9a" stroke-opacity="0.376471" d="M762.697,-80.3C762.697,-80.3 945.9426,-80.3 945.9426,-80.3 951.9426,-80.3 957.9426,-86.3 957.9426,-92.3 957.9426,-92.3 957.9426,-104.3 957.9426,-104.3 957.9426,-110.3 951.9426,-116.3 945.9426,-116.3 945.9426,-116.3 762.697,-116.3 762.697,-116.3 756.697,-116.3 750.697,-110.3 750.697,-104.3 750.697,-104.3 750.697,-92.3 750.697,-92.3 750.697,-86.3 756.697,-80.3 762.697,-80.3"/>
<text text-anchor="middle" x="854.3198" y="-94.2" font-family="Times,serif" font-size="14.00" fill="#000000">docker-network-graph_network_c</text>
</g>
<!-- network_docker&#45;network&#45;graph_network_c&#45;&#45;network_host -->
<g id="edge16" class="edge">
<title>network_docker-network-graph_network_c--network_host</title>
<path fill="none" stroke="#808080" stroke-dasharray="1,5" d="M803.3192,-80.2918C757.4929,-64.1107 691.9632,-40.9723 655.4824,-28.091"/>
</g>
<!-- network_docker&#45;network&#45;graph_no_gateway -->
<g id="node6" class="node">
<title>network_docker-network-graph_no_gateway</title>
<path fill="#b15928" fill-opacity="0.376471" stroke="#b15928" stroke-opacity="0.376471" d="M988.42,-80.3C988.42,-80.3 1180.2196,-80.3 1180.2196,-80.3 1186.2196,-80.3 1192.2196,-86.3 1192.2196,-92.3 1192.2196,-92.3 1192.2196,-104.3 1192.2196,-104.3 1192.2196,-110.3 1186.2196,-116.3 1180.2196,-116.3 1180.2196,-116.3 988.42,-116.3 988.42,-116.3 982.42,-116.3 976.42,-110.3 976.42,-104.3 976.42,-104.3 976.42,-92.3 976.42,-92.3 976.42,-86.3 982.42,-80.3 988.42,-80.3"/>
<text text-anchor="middle" x="1084.3198" y="-94.2" font-family="Times,serif" font-size="14.00" fill="#000000">docker-network-graph_no_gateway</text>
</g>
<!-- network_docker&#45;network&#45;graph_no_gateway&#45;&#45;network_host -->
<g id="edge17" class="edge">
<title>network_docker-network-graph_no_gateway--network_host</title>
<path fill="none" stroke="#808080" stroke-dasharray="1,5" d="M1003.557,-80.2455C991.4334,-77.7067 979.0629,-75.212 967.3198,-73 851.9177,-51.2625 713.3782,-30.7067 655.6498,-22.3863"/>
</g>
<!-- container_42e6eb67bb0da8991f3c4783d294ff2acc2e823906878904fb1fff3d2d8b3b3c -->
<g id="node8" class="node">
<title>container_42e6eb67bb0da8991f3c4783d294ff2acc2e823906878904fb1fff3d2d8b3b3c</title>
<polygon fill="#cdcdcd" stroke="#000000" points="0,-172.5 0,-222.1 90.6396,-222.1 90.6396,-172.5 0,-172.5"/>
<text text-anchor="middle" x="45.3198" y="-205.5" font-family="Times,serif" font-size="14.00" fill="#000000">lucid_banach</text>
<polyline fill="none" stroke="#000000" points="0,-197.3 90.6396,-197.3 "/>
<text text-anchor="middle" x="45.25" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.17.0.2</text>
</g>
<!-- container_42e6eb67bb0da8991f3c4783d294ff2acc2e823906878904fb1fff3d2d8b3b3c&#45;&#45;network_bridge -->
<g id="edge1" class="edge">
<title>container_42e6eb67bb0da8991f3c4783d294ff2acc2e823906878904fb1fff3d2d8b3b3c:8fdec3d891cec12f1fa9490dc3648a6546d49b39d6a4edb770bdd77b8ae2a144--network_bridge</title>
<path fill="none" stroke="#1f78b4" d="M45.3198,-172.3C45.3198,-153.2861 45.3198,-131.5241 45.3198,-116.5465"/>
</g>
<!-- container_7b5d4b5a8288ae9e728681845c115da2f3785c5dd758a1e519fc2d48cc9374a2 -->
<g id="node9" class="node">
<title>container_7b5d4b5a8288ae9e728681845c115da2f3785c5dd758a1e519fc2d48cc9374a2</title>
<polygon fill="#cdcdcd" stroke="#000000" points="118.3766,-160.1 118.3766,-234.5 252.263,-234.5 252.263,-160.1 118.3766,-160.1"/>
<text text-anchor="middle" x="185.3198" y="-217.9" font-family="Times,serif" font-size="14.00" fill="#000000">service_4</text>
<polyline fill="none" stroke="#000000" points="118.3766,-209.7 252.263,-209.7 "/>
<text text-anchor="middle" x="150.8745" y="-193.1" font-family="Times,serif" font-size="14.00" fill="#000000">1234/tcp</text>
<polyline fill="none" stroke="#000000" points="183.3724,-184.9 183.3724,-209.7 "/>
<text text-anchor="middle" x="217.8177" y="-193.1" font-family="Times,serif" font-size="14.00" fill="#000000">5678/udp</text>
<polyline fill="none" stroke="#000000" points="118.3766,-184.9 252.263,-184.9 "/>
<text text-anchor="middle" x="185.1266" y="-168.3" font-family="Times,serif" font-size="14.00" fill="#000000">172.20.0.2</text>
</g>
<!-- container_7b5d4b5a8288ae9e728681845c115da2f3785c5dd758a1e519fc2d48cc9374a2&#45;&#45;network_docker&#45;network&#45;graph_internet -->
<g id="edge2" class="edge">
<title>container_7b5d4b5a8288ae9e728681845c115da2f3785c5dd758a1e519fc2d48cc9374a2:539637b24463fc2f401b553afd44a420bbf73a9d48a19c7b3d7a7ea7b8756b81--network_docker-network-graph_internet</title>
<path fill="none" stroke="#33a02c" stroke-dasharray="5,2" d="M185.3198,-160.3C185.3198,-148.1368 185.3198,-134.6314 185.3198,-123.3385"/>
</g>
<!-- container_8685a8dab43025e96c9ef3e77b9cdbfbace7aafc7b9d91e1ea27c463c3c1c9f6 -->
<g id="node10" class="node">
<title>container_8685a8dab43025e96c9ef3e77b9cdbfbace7aafc7b9d91e1ea27c463c3c1c9f6</title>
<polygon fill="#cdcdcd" stroke="#000000" points="1210.3324,-73.5 1210.3324,-123.1 1296.3072,-123.1 1296.3072,-73.5 1210.3324,-73.5"/>
<text text-anchor="middle" x="1253.3198" y="-106.5" font-family="Times,serif" font-size="14.00" fill="#000000">host_service</text>
<polyline fill="none" stroke="#000000" points="1210.3324,-98.3 1296.3072,-98.3 "/>
<text text-anchor="middle" x="1253.0824" y="-81.7" font-family="Times,serif" font-size="14.00" fill="#000000"> </text>
</g>
<!-- container_8685a8dab43025e96c9ef3e77b9cdbfbace7aafc7b9d91e1ea27c463c3c1c9f6&#45;&#45;network_host -->
<g id="edge3" class="edge">
<title>container_8685a8dab43025e96c9ef3e77b9cdbfbace7aafc7b9d91e1ea27c463c3c1c9f6:166c04ea9a7e49c63a6b7739361510aa70f0014260e6b1b03b0ec9347d76ab54--network_host</title>
<path fill="none" stroke="#808080" stroke-width="2" d="M1210.3198,-86.3C1203.1825,-86.3 1207.4585,-76.6411 1201.3198,-73 1153.9416,-44.8983 763.079,-24.7734 655.5868,-19.7322"/>
</g>
<!-- container_3a39e0a8fdb79e342ecb663a52353c7d58b6cb63f0ec7d27d051f48ed5f8b61f -->
<g id="node11" class="node">
<title>container_3a39e0a8fdb79e342ecb663a52353c7d58b6cb63f0ec7d27d051f48ed5f8b61f</title>
<polygon fill="#cdcdcd" stroke="#000000" points="575.8198,-160.1 575.8198,-234.5 726.8198,-234.5 726.8198,-160.1 575.8198,-160.1"/>
<text text-anchor="middle" x="651.3198" y="-217.9" font-family="Times,serif" font-size="14.00" fill="#000000">service_2</text>
<polyline fill="none" stroke="#000000" points="575.8198,-209.7 726.8198,-209.7 "/>
<text text-anchor="middle" x="613.5698" y="-181.1" font-family="Times,serif" font-size="14.00" fill="#000000">172.18.0.3</text>
<polyline fill="none" stroke="#000000" points="651.3198,-160.1 651.3198,-209.7 "/>
<text text-anchor="middle" x="689.0698" y="-193.1" font-family="Times,serif" font-size="14.00" fill="#000000">s2.netc</text>
<polyline fill="none" stroke="#000000" points="651.3198,-184.9 726.8198,-184.9 "/>
<text text-anchor="middle" x="689.0698" y="-168.3" font-family="Times,serif" font-size="14.00" fill="#000000">172.19.0.2</text>
</g>
<!-- container_3a39e0a8fdb79e342ecb663a52353c7d58b6cb63f0ec7d27d051f48ed5f8b61f&#45;&#45;network_docker&#45;network&#45;graph_network_b -->
<g id="edge4" class="edge">
<title>container_3a39e0a8fdb79e342ecb663a52353c7d58b6cb63f0ec7d27d051f48ed5f8b61f:94b8eee245436859b87a0c20d17a1655878a8f7fc041cb66814c69e16d771a17--network_docker-network-graph_network_b</title>
<path fill="none" stroke="#ff7f00" d="M613.3198,-161.3C613.3198,-145.8968 617.6157,-128.9371 621.6095,-116.4982"/>
</g>
<!-- container_3a39e0a8fdb79e342ecb663a52353c7d58b6cb63f0ec7d27d051f48ed5f8b61f&#45;&#45;network_docker&#45;network&#45;graph_network_c -->
<g id="edge5" class="edge">
<title>container_3a39e0a8fdb79e342ecb663a52353c7d58b6cb63f0ec7d27d051f48ed5f8b61f:e46bd03cb25afb2c3447f32c6a0ea9ae1d32e94c5bc2c1c5de70641a0bdaf81d--network_docker-network-graph_network_c</title>
<path fill="none" stroke="#6a3d9a" d="M727.3198,-172.3C734.2379,-172.3 731.1037,-164.1445 736.3198,-159.6 757.2069,-141.4022 784.4401,-126.7956 807.4805,-116.4119"/>
</g>
<!-- container_09536a22736bb178d3013c3cdb91b361f71b128c9f768d9ce7c86398a280db1b -->
<g id="node12" class="node">
<title>container_09536a22736bb178d3013c3cdb91b361f71b128c9f768d9ce7c86398a280db1b</title>
<polygon fill="#cdcdcd" stroke="#000000" points="378.8198,-172.5 378.8198,-222.1 529.8198,-222.1 529.8198,-172.5 378.8198,-172.5"/>
<text text-anchor="middle" x="454.3198" y="-205.5" font-family="Times,serif" font-size="14.00" fill="#000000">service_1</text>
<polyline fill="none" stroke="#000000" points="378.8198,-197.3 529.8198,-197.3 "/>
<text text-anchor="middle" x="416.5698" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.21.0.3</text>
<polyline fill="none" stroke="#000000" points="454.3198,-172.5 454.3198,-197.3 "/>
<text text-anchor="middle" x="492.0698" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.18.0.2</text>
</g>
<!-- container_09536a22736bb178d3013c3cdb91b361f71b128c9f768d9ce7c86398a280db1b&#45;&#45;network_docker&#45;network&#45;graph_network_a -->
<g id="edge6" class="edge">
<title>container_09536a22736bb178d3013c3cdb91b361f71b128c9f768d9ce7c86398a280db1b:eadfb1979c37a6bbb31e06ddf4a3eaff6aa00fb6a4a0158361e727e20db355ad--network_docker-network-graph_network_a</title>
<path fill="none" stroke="#e31a1c" d="M416.3198,-172.3C416.3198,-152.9488 411.6406,-131.2395 407.6925,-116.3664"/>
</g>
<!-- container_09536a22736bb178d3013c3cdb91b361f71b128c9f768d9ce7c86398a280db1b&#45;&#45;network_docker&#45;network&#45;graph_network_b -->
<g id="edge7" class="edge">
<title>container_09536a22736bb178d3013c3cdb91b361f71b128c9f768d9ce7c86398a280db1b:5d78b06ddda5fdbb00cfcc6bc77e95fef1b73215643c4bec5403502357ec71e2--network_docker-network-graph_network_b</title>
<path fill="none" stroke="#ff7f00" d="M530.3198,-185.3C540.6146,-185.3 585.3415,-141.8093 610.665,-116.3265"/>
</g>
<!-- container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560 -->
<g id="node13" class="node">
<title>container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560</title>
<polygon fill="#cdcdcd" stroke="#000000" points="745.3198,-172.5 745.3198,-222.1 1047.3198,-222.1 1047.3198,-172.5 745.3198,-172.5"/>
<text text-anchor="middle" x="896.3198" y="-205.5" font-family="Times,serif" font-size="14.00" fill="#000000">service_3</text>
<polyline fill="none" stroke="#000000" points="745.3198,-197.3 1047.3198,-197.3 "/>
<text text-anchor="middle" x="783.0698" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.21.0.2</text>
<polyline fill="none" stroke="#000000" points="820.8198,-172.5 820.8198,-197.3 "/>
<text text-anchor="middle" x="858.5698" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.18.0.4</text>
<polyline fill="none" stroke="#000000" points="896.3198,-172.5 896.3198,-197.3 "/>
<text text-anchor="middle" x="934.0698" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.19.0.3</text>
<polyline fill="none" stroke="#000000" points="971.8198,-172.5 971.8198,-197.3 "/>
<text text-anchor="middle" x="1009.5698" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000">172.22.1.2</text>
</g>
<!-- container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560&#45;&#45;network_docker&#45;network&#45;graph_network_a -->
<g id="edge8" class="edge">
<title>container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560:f45658e99b5dde0e6cd56b73501cb2a090e01c39e3931f183eb4d51065518b72--network_docker-network-graph_network_a</title>
<path fill="none" stroke="#e31a1c" d="M745.3198,-185.3C733.0634,-185.3 744.8427,-167.3159 735.3198,-159.6 658.339,-97.2265 612.5919,-142.4315 515.3198,-123.6 503.8722,-121.3838 491.8114,-118.8731 480.0029,-116.3152"/>
</g>
<!-- container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560&#45;&#45;network_docker&#45;network&#45;graph_network_b -->
<g id="edge9" class="edge">
<title>container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560:a367aad35e5a35474486791b9d09671e4914d85fd9ae4c8eb3c90cab0a297296--network_docker-network-graph_network_b</title>
<path fill="none" stroke="#ff7f00" d="M858.3198,-172.3C858.3198,-156.0982 774.5466,-132.4994 708.1172,-116.3332"/>
</g>
<!-- container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560&#45;&#45;network_docker&#45;network&#45;graph_network_c -->
<g id="edge10" class="edge">
<title>container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560:691ab484a711d0310f08857c455bc7544b5cb57c709b97576ce4f8909a4f9671--network_docker-network-graph_network_c</title>
<path fill="none" stroke="#6a3d9a" d="M934.3198,-172.3C934.3198,-147.7045 913.6899,-129.0061 893.3824,-116.5582"/>
</g>
<!-- container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560&#45;&#45;network_docker&#45;network&#45;graph_no_gateway -->
<g id="edge11" class="edge">
<title>container_01b9dd47c89b732a8791369dd2df8bdbfa05e1267fedf01190e680bb449f8560:3d6f4f72c482ab4cac97ac9a30793ff81e073b496123c93a74f53c6354c02dfa--network_docker-network-graph_no_gateway</title>
<path fill="none" stroke="#b15928" d="M1047.3198,-185.3C1059.4222,-185.3 1051.8009,-170.8271 1056.3198,-159.6 1062.2612,-144.8388 1069.7922,-128.4609 1075.547,-116.35"/>
</g>
<!-- container_1f3ce68cf416e1aa17096362a691c217ae582713a2406c61cadf5c110e998587 -->
<g id="node14" class="node">
<title>container_1f3ce68cf416e1aa17096362a691c217ae582713a2406c61cadf5c110e998587</title>
<polygon fill="#cdcdcd" stroke="#000000" points="1065.2272,-172.5 1065.2272,-222.1 1171.4124,-222.1 1171.4124,-172.5 1065.2272,-172.5"/>
<text text-anchor="middle" x="1118.3198" y="-205.5" font-family="Times,serif" font-size="14.00" fill="#000000">isolated_service</text>
<polyline fill="none" stroke="#000000" points="1065.2272,-197.3 1171.4124,-197.3 "/>
<text text-anchor="middle" x="1117.9772" y="-180.7" font-family="Times,serif" font-size="14.00" fill="#000000"> </text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB