Compare commits
10 commits
8a1870dbcd
...
84387e105d
Author | SHA1 | Date | |
---|---|---|---|
|
84387e105d | ||
|
e13dcacb0a | ||
|
2492ba0646 | ||
|
212a082af3 | ||
|
e8c090b3be | ||
|
a93f185969 | ||
|
b503fb7bb9 | ||
|
739a7a1527 | ||
|
bb23b21806 | ||
|
a9dd1728c9 |
15 changed files with 395 additions and 156 deletions
|
@ -1,3 +1,4 @@
|
||||||
.*
|
.*
|
||||||
test/
|
test/
|
||||||
example.png
|
example.png
|
||||||
|
docker-compose.yml
|
12
.github/dependabot.yml
vendored
12
.github/dependabot.yml
vendored
|
@ -1,12 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
# Maintain dependencies for GitHub Actions
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
ignore:
|
|
||||||
- dependency-name: "*"
|
|
||||||
update-types: ["version-update:semver-patch"]
|
|
||||||
- dependency-name: "*"
|
|
||||||
update-types: ["version-update:semver-minor"]
|
|
53
.github/workflows/docker-build-push.yml
vendored
Normal file
53
.github/workflows/docker-build-push.yml
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
name: Docker (Build and Push)
|
||||||
|
|
||||||
|
# Controls when the workflow will run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
|
||||||
|
# permissions are needed if pushing to ghcr.io
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_push:
|
||||||
|
name: Build and Push
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Get the repository's code
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
# https://github.com/docker/setup-qemu-action
|
||||||
|
- uses: docker/setup-qemu-action@v3
|
||||||
|
# https://github.com/docker/setup-buildx-action
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
# list of Docker images to use as base name for tags
|
||||||
|
images: |
|
||||||
|
ghcr.io/muratovas/docker-network-graph
|
||||||
|
# Docker tags based on the following events/attributes
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=sha
|
||||||
|
|
||||||
|
- name: Build and Push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
60
.github/workflows/docker.yml
vendored
60
.github/workflows/docker.yml
vendored
|
@ -1,60 +0,0 @@
|
||||||
name: Publish Docker image
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '**'
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
jobs:
|
|
||||||
push_to_registry:
|
|
||||||
name: Build and push docker image
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Docker meta
|
|
||||||
id: docker_meta
|
|
||||||
uses: docker/metadata-action@v4
|
|
||||||
with:
|
|
||||||
images: ${{ secrets.DOCKERHUB_USERNAME }}/docker-network-graph,ghcr.io/${{ github.repository_owner }}/docker-network-graph
|
|
||||||
tags: |
|
|
||||||
type=ref,event=branch
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v1
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v1
|
|
||||||
- name: Cache Docker layers
|
|
||||||
if: github.event_name != 'pull_request'
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: /tmp/.buildx-cache
|
|
||||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-buildx-
|
|
||||||
- name: Login to DockerHub
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: Login to GitHub Container Registry
|
|
||||||
if: github.event_name != 'pull_request'
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.repository_owner }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v2
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
platforms: linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64
|
|
||||||
push: True
|
|
||||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
|
||||||
cache-from: type=local,src=/tmp/.buildx-cache
|
|
||||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
||||||
*.gv
|
*.gv
|
||||||
*.pdf
|
*.pdf
|
||||||
*.png
|
|
||||||
*.svg
|
|
||||||
.idea
|
.idea
|
||||||
|
/output
|
||||||
|
|
1
LICENSE
1
LICENSE
|
@ -1,5 +1,6 @@
|
||||||
Copyright (c) 2018 Eugene Agafonov
|
Copyright (c) 2018 Eugene Agafonov
|
||||||
Copyright (c) 2023 e-dant (github.com/e-dant)
|
Copyright (c) 2023 e-dant (github.com/e-dant)
|
||||||
|
Copyright (c) 2024 MuratovAS
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
4
Pipfile
4
Pipfile
|
@ -4,10 +4,10 @@ verify_ssl = true
|
||||||
name = "pypi"
|
name = "pypi"
|
||||||
|
|
||||||
[packages]
|
[packages]
|
||||||
docker = "~=3.7"
|
|
||||||
graphviz = "*"
|
graphviz = "*"
|
||||||
|
docker = "==6.*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
|
|
||||||
[requires]
|
[requires]
|
||||||
python_version = "3"
|
python_version = ">=3.6,<4"
|
||||||
|
|
33
Pipfile.lock
generated
33
Pipfile.lock
generated
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "7a973891b61a2778ab0989c6d5b6d0507ac7977cce469307bfd06903240b6449"
|
"sha256": "f30fb7db8567fcb899359e73c438a98a395302efa3ae741a9a181778bfaf8f39"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {
|
"requires": {
|
||||||
"python_version": "3"
|
"python_version": ">=3.6,<4"
|
||||||
},
|
},
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
|
@ -107,18 +107,11 @@
|
||||||
},
|
},
|
||||||
"docker": {
|
"docker": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2434b396e616a5ef682fbf80e04839a59e8b81880ece5662c33dff34b8863519",
|
"sha256:aa6d17830045ba5ef0168d5eaa34d37beeb113948c413affe1d5991fc11f9a20",
|
||||||
"sha256:a062a9f82dff025f79c2097c46f49f143f8898274db7e66041f78cafee66b962"
|
"sha256:aecd2277b8bf8e506e484f6ab7aec39abe0038e29fa4a6d3ba86c3fe01844ed9"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.7.3"
|
"version": "==6.1.3"
|
||||||
},
|
|
||||||
"docker-pycreds": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:6ce3270bcaf404cc4c3e27e4b6c70d3521deae82fb508767870fdbf772d584d4",
|
|
||||||
"sha256:7266112468627868005106ec19cd0d722702d2b7d5912a28e19b826c3d37af49"
|
|
||||||
],
|
|
||||||
"version": "==0.4.0"
|
|
||||||
},
|
},
|
||||||
"graphviz": {
|
"graphviz": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -136,6 +129,14 @@
|
||||||
"markers": "python_version >= '3.5'",
|
"markers": "python_version >= '3.5'",
|
||||||
"version": "==3.4"
|
"version": "==3.4"
|
||||||
},
|
},
|
||||||
|
"packaging": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61",
|
||||||
|
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.7'",
|
||||||
|
"version": "==23.1"
|
||||||
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
|
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
|
||||||
|
@ -144,14 +145,6 @@
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==2.31.0"
|
"version": "==2.31.0"
|
||||||
},
|
},
|
||||||
"six": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
|
||||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
|
||||||
"version": "==1.16.0"
|
|
||||||
},
|
|
||||||
"urllib3": {
|
"urllib3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1",
|
"sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1",
|
||||||
|
|
66
README.md
66
README.md
|
@ -3,34 +3,50 @@
|
||||||
Visualize the relationship between Docker networks and containers
|
Visualize the relationship between Docker networks and containers
|
||||||
as a neat graphviz graph.
|
as a neat graphviz graph.
|
||||||
|
|
||||||
|
This repository fork [e-dant/docker-network-graph](https://github.com/e-dant/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
|
||||||
![example graph](https://raw.githubusercontent.com/e-dant/docker-network-graph/release/example.png)
|
![example graph](./example.svg)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
usage: docker-network-graph.py [-h] [-v] [-o OUT]
|
```bash
|
||||||
|
usage: docker-network-graph.py [-h] [-v] [-o OUT] [-u]
|
||||||
Visualize docker networks.
|
Visualize docker networks.
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help Show this help message and exit
|
||||||
-v, --verbose Verbose output
|
-v, --verbose Verbose output
|
||||||
-o OUT, --out OUT Write output to file
|
-o OUT, --out OUT Write output to file [not supported by container]
|
||||||
|
-u, --url Generate link for GraphvizOnline
|
||||||
In most cases what you want to run are the following couple commands:
|
```
|
||||||
|
|
||||||
git clone https://github.com/e-dant/docker-network-graph.git
|
|
||||||
cd docker-network-graph
|
|
||||||
pipenv install
|
|
||||||
pipenv run python docker-network-graph.py -o output.svg
|
|
||||||
|
|
||||||
This will generate an .svg file containing the graph.
|
|
||||||
|
|
||||||
## Running inside docker
|
## Running inside docker
|
||||||
If you want to generate a graph for a remote system you can also easily
|
If you want to generate a graph for a remote system you can also easily
|
||||||
run this script inside a pre-built docker container:
|
run this script inside a pre-built docker container:
|
||||||
|
|
||||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock e-dant/docker-network-graph
|
```bash
|
||||||
|
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/muratovas/docker-network-graph:latest -u
|
||||||
|
```
|
||||||
|
|
||||||
|
For more advanced use cases you can append arguments to the `docker run`
|
||||||
|
command as if you were running it in a local shell.
|
||||||
|
|
||||||
|
## Running local
|
||||||
|
In most cases what you want to run are the following couple commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/muratovas/docker-network-graph.git
|
||||||
|
cd docker-network-graph
|
||||||
|
pipenv install
|
||||||
|
pipenv run python docker-network-graph.py -o output.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate an .svg file containing the graph.
|
||||||
|
|
||||||
This will just generate and output the graph in the [DOT Language][dot].
|
This will just generate and output the graph in the [DOT Language][dot].
|
||||||
You can then paste that code into [GraphvizOnline][gvonline]
|
You can then paste that code into [GraphvizOnline][gvonline]
|
||||||
|
@ -41,15 +57,17 @@ Alternatively, if you prefer to render locally, you can run
|
||||||
paste the previous output there, press enter and finally CTRL+C to
|
paste the previous output there, press enter and finally CTRL+C to
|
||||||
generate the file.
|
generate the file.
|
||||||
|
|
||||||
|
|
||||||
For more advanced use cases you can append arguments to the `docker run`
|
|
||||||
command as if you were running it in a local shell.
|
|
||||||
|
|
||||||
[dot]: https://www.graphviz.org/doc/info/lang.html
|
|
||||||
[gvonline]: https://dreampuf.github.io/GraphvizOnline/
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
If you'd like to contribute to this project, there is a sample docker-compose file
|
If you'd like to contribute to this project, there is a sample docker-compose file
|
||||||
using dummy containers in `test`.
|
using dummy containers in `test`.
|
||||||
|
|
||||||
You can deploy it using `docker-compose -f test/docker-compose.yml up -d`.
|
You can deploy it using
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Credit
|
||||||
|
|
||||||
|
[dot lang](https://www.graphviz.org/doc/info/lang.html)
|
||||||
|
|
||||||
|
[gvonline](https://dreampuf.github.io/GraphvizOnline/)
|
||||||
|
|
|
@ -23,6 +23,14 @@ services:
|
||||||
- network_b
|
- network_b
|
||||||
- network_c
|
- network_c
|
||||||
- no_gateway
|
- 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:
|
host_service:
|
||||||
container_name: host_service
|
container_name: host_service
|
||||||
image: leoverto/dummy-image
|
image: leoverto/dummy-image
|
||||||
|
@ -33,6 +41,9 @@ services:
|
||||||
network_mode: none
|
network_mode: none
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
internet:
|
||||||
|
driver_opts:
|
||||||
|
com.docker.network.bridge.enable_icc: "false"
|
||||||
network_a:
|
network_a:
|
||||||
network_b:
|
network_b:
|
||||||
network_c:
|
network_c:
|
|
@ -5,6 +5,7 @@ import argparse
|
||||||
import random
|
import random
|
||||||
import docker
|
import docker
|
||||||
import typing
|
import typing
|
||||||
|
import urllib.parse
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from graphviz import Graph
|
from graphviz import Graph
|
||||||
from graphviz.parameters.formats import FORMATS
|
from graphviz.parameters.formats import FORMATS
|
||||||
|
@ -22,7 +23,7 @@ COLORS = [
|
||||||
"#b2df8a",
|
"#b2df8a",
|
||||||
"#fdbf6f",
|
"#fdbf6f",
|
||||||
"#cab2d6",
|
"#cab2d6",
|
||||||
"#ffff99",
|
"#90f530",
|
||||||
"#0d8bad",
|
"#0d8bad",
|
||||||
"#e98420",
|
"#e98420",
|
||||||
"#0e9997",
|
"#0e9997",
|
||||||
|
@ -49,12 +50,16 @@ class Interface:
|
||||||
address: str
|
address: str
|
||||||
aliases: typing.List[str]
|
aliases: typing.List[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Port:
|
||||||
|
port: str
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Container:
|
class Container:
|
||||||
container_id: str
|
container_id: str
|
||||||
name: str
|
name: str
|
||||||
interfaces: typing.List[Interface]
|
interfaces: typing.List[Interface]
|
||||||
|
ports: typing.List[Interface]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -124,11 +129,13 @@ def get_containers(
|
||||||
|
|
||||||
for container in client.containers.list():
|
for container in client.containers.list():
|
||||||
interfaces: typing.List[Interface] = []
|
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
|
# Iterate over container interfaces
|
||||||
for net_name, net_info in container.attrs["NetworkSettings"][
|
for net_name, net_info in container.attrs["NetworkSettings"]["Networks"].items():
|
||||||
"Networks"
|
|
||||||
].items():
|
|
||||||
endpoint_id = net_info["EndpointID"]
|
endpoint_id = net_info["EndpointID"]
|
||||||
|
|
||||||
aliases = []
|
aliases = []
|
||||||
|
@ -142,17 +149,16 @@ def get_containers(
|
||||||
links.append(Link(container.id, endpoint_id, net_name))
|
links.append(Link(container.id, endpoint_id, net_name))
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(
|
print(f"Container: {container.name} {ports} {''.join([iface.address for iface in interfaces])}")
|
||||||
f"Container: {container.name} {''.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
|
return containers, links
|
||||||
|
|
||||||
|
|
||||||
def draw_network(g: Graph, net: Network):
|
def draw_network(g: Graph, net: Network):
|
||||||
label = f"{{<gw_iface> {net.gateway} | {net.name}"
|
# <gw_iface> {net.gateway} |
|
||||||
|
label = f"{{{net.name}"
|
||||||
if net.internal:
|
if net.internal:
|
||||||
label += " | Internal"
|
label += " | Internal"
|
||||||
if net.isolated:
|
if net.isolated:
|
||||||
|
@ -163,13 +169,19 @@ def draw_network(g: Graph, net: Network):
|
||||||
f"network_{net.name}",
|
f"network_{net.name}",
|
||||||
shape="record",
|
shape="record",
|
||||||
label=label,
|
label=label,
|
||||||
fillcolor=net.color,
|
color=net.color + "60",
|
||||||
style="filled",
|
style="filled,rounded",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw_container(g: Graph, c: Container):
|
def draw_container(g: Graph, c: Container):
|
||||||
iface_labels = []
|
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:
|
for iface in c.interfaces:
|
||||||
iface_label = "{"
|
iface_label = "{"
|
||||||
|
@ -180,26 +192,37 @@ def draw_container(g: Graph, c: Container):
|
||||||
iface_label += f"<{iface.endpoint_id}> {iface.address} }}"
|
iface_label += f"<{iface.endpoint_id}> {iface.address} }}"
|
||||||
iface_labels.append(iface_label)
|
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(
|
g.node(
|
||||||
f"container_{c.container_id}",
|
f"container_{c.container_id}",
|
||||||
shape="record",
|
shape="record",
|
||||||
label=label,
|
label=label,
|
||||||
fillcolor="#ff9999",
|
fillcolor="#cdcdcd",
|
||||||
style="filled",
|
style="filled",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw_link(g: Graph, networks: typing.Dict[str, Network], link: Link):
|
def draw_link(g: Graph, networks: typing.Dict[str, Network], link: Link):
|
||||||
|
if networks[link.network_name].isolated:
|
||||||
|
style="dashed"
|
||||||
|
elif networks[link.network_name].name == "host":
|
||||||
|
style="bold"
|
||||||
|
else:
|
||||||
|
style="solid"
|
||||||
|
|
||||||
g.edge(
|
g.edge(
|
||||||
f"container_{link.container_id}:{link.endpoint_id}",
|
f"container_{link.container_id}:{link.endpoint_id}",
|
||||||
f"network_{link.network_name}",
|
f"network_{link.network_name}",
|
||||||
color=networks[link.network_name].color,
|
color=networks[link.network_name].color,
|
||||||
|
style=style,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def generate_graph(verbose: bool, file: str):
|
def generate_graph(verbose: bool, file: str, url: str):
|
||||||
docker_client = docker.from_env()
|
docker_client = docker.from_env()
|
||||||
|
|
||||||
networks = get_networks(docker_client, verbose)
|
networks = get_networks(docker_client, verbose)
|
||||||
|
@ -230,8 +253,21 @@ def generate_graph(verbose: bool, file: str):
|
||||||
if link.network_name != "none":
|
if link.network_name != "none":
|
||||||
draw_link(g, networks, link)
|
draw_link(g, networks, link)
|
||||||
|
|
||||||
|
for _, network in networks.items():
|
||||||
|
if network.internal != True:
|
||||||
|
if network.name != "host":
|
||||||
|
g.edge(
|
||||||
|
f"network_{network.name}",
|
||||||
|
f"network_host",
|
||||||
|
color="#808080",
|
||||||
|
style="dotted",
|
||||||
|
)
|
||||||
|
|
||||||
if file:
|
if file:
|
||||||
g.render(base)
|
g.render(base)
|
||||||
|
else:
|
||||||
|
if url:
|
||||||
|
print("https://dreampuf.github.io/GraphvizOnline/#" + urllib.parse.quote(g.source))
|
||||||
else:
|
else:
|
||||||
print(g.source)
|
print(g.source)
|
||||||
|
|
||||||
|
@ -245,10 +281,9 @@ def graphviz_output_file(filename: str):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Visualize docker networks.")
|
parser = argparse.ArgumentParser(description="Visualize docker networks.")
|
||||||
parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true")
|
parser.add_argument("-v", "--verbose", help="verbose output", action="store_true")
|
||||||
parser.add_argument(
|
parser.add_argument("-o", "--out", help="write output to file", type=graphviz_output_file)
|
||||||
"-o", "--out", help="Write output to file", type=graphviz_output_file
|
parser.add_argument("-u", "--url", help="generate link for GraphvizOnline", action="store_true")
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
generate_graph(args.verbose, args.out)
|
generate_graph(args.verbose, args.out, args.url)
|
BIN
example.png
BIN
example.png
Binary file not shown.
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 85 KiB |
212
example.svg
Normal file
212
example.svg
Normal 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--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-network-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-network-graph_internet--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-network-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-network-graph_network_a--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-network-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-network-graph_network_b--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-network-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-network-graph_network_c--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-network-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-network-graph_no_gateway--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--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--network_docker-network-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--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--network_docker-network-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--network_docker-network-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--network_docker-network-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--network_docker-network-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--network_docker-network-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--network_docker-network-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--network_docker-network-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--network_docker-network-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 |
|
@ -1,6 +0,0 @@
|
||||||
#! /usr/bin/env bash
|
|
||||||
|
|
||||||
(
|
|
||||||
cd "$(dirname "$0")/.." \
|
|
||||||
&& pipenv install
|
|
||||||
)
|
|
6
tool/run
6
tool/run
|
@ -1,6 +0,0 @@
|
||||||
#! /usr/bin/env bash
|
|
||||||
|
|
||||||
(
|
|
||||||
cd "$(dirname "$0")/.." \
|
|
||||||
&& pipenv run python docker-network-graph.py -o output.svg
|
|
||||||
)
|
|
Loading…
Reference in a new issue