|
|
|
|
@@ -5,19 +5,24 @@
|
|
|
|
|
# - Alle Netzwerke auflisten
|
|
|
|
|
# - Details zu einem spezifischen Docker-Netzwerk anzeigen
|
|
|
|
|
# - Belegte IPs je Netzwerk und netzwerkuebergreifend ausgeben
|
|
|
|
|
# - Ungenutzte Netzwerke (ohne Container) anzeigen
|
|
|
|
|
# - Netzwerke interaktiv auswaehlen und loeschen
|
|
|
|
|
# Verwendung: bash ./dockernet-inspector.v1.sh [BEFEHL] [OPTIONS]
|
|
|
|
|
# Befehle:
|
|
|
|
|
# networks - Alle Docker Netzwerke auflisten
|
|
|
|
|
# inspect - Details zu einem Netzwerk anzeigen (Standard)
|
|
|
|
|
# ips - Belegte IPs in einem Netzwerk
|
|
|
|
|
# ips-all - Belegte IPs in allen Netzwerken
|
|
|
|
|
# networks - Alle Docker Netzwerke auflisten
|
|
|
|
|
# inspect - Details zu einem Netzwerk anzeigen (Standard)
|
|
|
|
|
# ips - Belegte IPs in einem Netzwerk
|
|
|
|
|
# ips-all - Belegte IPs in allen Netzwerken
|
|
|
|
|
# unused-networks - Netzwerke ohne verbundene Container
|
|
|
|
|
# delete-networks - Netzwerke interaktiv auswaehlen und loeschen
|
|
|
|
|
# help, -h, --help - Diese Hilfe anzeigen
|
|
|
|
|
# Autor: Patrick Asmus
|
|
|
|
|
# Web: https://www.cleveradmin.de
|
|
|
|
|
# Git-Reposit.: https://git.techniverse.net/scriptos/dockernet-inspector.git
|
|
|
|
|
# Version: 1.3.0
|
|
|
|
|
# Datum: 22.02.2026
|
|
|
|
|
# Modifikation: Ineraktives Menü hinzugefügt, Fehlerbehandlung verbessert, Ausgabe formatiert, Kompatibilität erweitert
|
|
|
|
|
# Version: 1.6.0
|
|
|
|
|
# Datum: 10.04.2026
|
|
|
|
|
# Modifikation: Schutz fuer Docker-Standardnetzwerke (bridge, host, none) hinzugefuegt;
|
|
|
|
|
# Detailansicht zeigt Hinweis statt Bridge-Daten, Loeschen wird blockiert
|
|
|
|
|
#####################################################
|
|
|
|
|
|
|
|
|
|
set -uo pipefail
|
|
|
|
|
@@ -39,7 +44,7 @@ print_table_title() {
|
|
|
|
|
# Hilfe-Funktion
|
|
|
|
|
show_help() {
|
|
|
|
|
cat <<HELP
|
|
|
|
|
Dockernet Inspector v1.2.0 - Docker Netzwerk Verwaltungstool
|
|
|
|
|
Dockernet Inspector v1.6.0 - Docker Netzwerk Verwaltungstool
|
|
|
|
|
|
|
|
|
|
VERWENDUNG:
|
|
|
|
|
$0 - Interaktiver Modus (Menü)
|
|
|
|
|
@@ -47,6 +52,8 @@ VERWENDUNG:
|
|
|
|
|
$0 inspect <netzwerk> - Details zu einem Netzwerk anzeigen
|
|
|
|
|
$0 ips <netzwerk> - Belegte IPs in einem Netzwerk anzeigen
|
|
|
|
|
$0 ips-all - Belegte IPs in allen Netzwerken anzeigen
|
|
|
|
|
$0 unused-networks - Ungenutzte Netzwerke (ohne Container) anzeigen
|
|
|
|
|
$0 delete-networks - Netzwerke interaktiv auswaehlen und loeschen
|
|
|
|
|
$0 <netzwerk> - Alias fuer 'inspect <netzwerk>'
|
|
|
|
|
$0 help - Diese Hilfe anzeigen
|
|
|
|
|
|
|
|
|
|
@@ -54,6 +61,9 @@ BEFEHLE:
|
|
|
|
|
networks Listet alle verfuegbaren Docker Netzwerke auf
|
|
|
|
|
ips <netzwerk> Zeigt Containername und IPv4-Adresse im angegebenen Netzwerk
|
|
|
|
|
ips-all Zeigt alle belegten IPv4-Adressen in allen Netzwerken (aufsteigend)
|
|
|
|
|
unused-networks Zeigt alle Docker Netzwerke ohne verbundene Container
|
|
|
|
|
delete-networks Netzwerk per Nummer auswaehlen und loeschen;
|
|
|
|
|
Docker-Standardnetzwerke (bridge, host, none) sind geschuetzt
|
|
|
|
|
inspect <netzwerk> Zeigt detaillierte Informationen zu einem Netzwerk:
|
|
|
|
|
- Netzwerktyp (Driver)
|
|
|
|
|
- Bridge-Interface
|
|
|
|
|
@@ -66,6 +76,8 @@ BEISPIELE:
|
|
|
|
|
$0 networks
|
|
|
|
|
$0 ips mynetwork
|
|
|
|
|
$0 ips-all
|
|
|
|
|
$0 unused-networks
|
|
|
|
|
$0 delete-networks
|
|
|
|
|
$0 inspect mynetwork
|
|
|
|
|
$0 mynetwork
|
|
|
|
|
$0 -h
|
|
|
|
|
@@ -157,6 +169,92 @@ list_ips_all_networks() {
|
|
|
|
|
print_dynamic_table "$table_data"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_unused_networks() {
|
|
|
|
|
local nets net containers table_data has_unused
|
|
|
|
|
|
|
|
|
|
nets="$(docker network ls --format '{{.Name}}' 2>/dev/null || true)"
|
|
|
|
|
[[ -z "$nets" ]] && {
|
|
|
|
|
echo "Fehler: Docker Netzwerke konnten nicht abgerufen werden."
|
|
|
|
|
exit 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table_data=$'NAME\tDRIVER\tSCOPE\n'
|
|
|
|
|
has_unused=false
|
|
|
|
|
|
|
|
|
|
while read -r net; do
|
|
|
|
|
[[ -z "${net:-}" ]] && continue
|
|
|
|
|
containers="$(docker network inspect "$net" --format '{{len .Containers}}' 2>/dev/null || true)"
|
|
|
|
|
if [[ "${containers:-0}" -eq 0 ]]; then
|
|
|
|
|
local driver scope
|
|
|
|
|
driver="$(docker network inspect "$net" --format '{{.Driver}}' 2>/dev/null || true)"
|
|
|
|
|
scope="$(docker network inspect "$net" --format '{{.Scope}}' 2>/dev/null || true)"
|
|
|
|
|
table_data+="${net}"$'\t'"${driver}"$'\t'"${scope}"$'\n'
|
|
|
|
|
has_unused=true
|
|
|
|
|
fi
|
|
|
|
|
done < <(printf "%s\n" "$nets")
|
|
|
|
|
|
|
|
|
|
if ! $has_unused; then
|
|
|
|
|
echo "Alle Docker Netzwerke haben mindestens einen verbundenen Container."
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
print_table_title "Ungenutzte Docker Netzwerke (keine Container verbunden):"
|
|
|
|
|
print_dynamic_table "$table_data"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete_networks() {
|
|
|
|
|
local nets
|
|
|
|
|
nets="$(docker network ls --format '{{.Name}}' 2>/dev/null || true)"
|
|
|
|
|
if [[ -z "$nets" ]]; then
|
|
|
|
|
echo "Fehler: Keine Docker Netzwerke gefunden."
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local -a net_array
|
|
|
|
|
mapfile -t net_array <<< "$nets"
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Verfuegbare Docker Netzwerke:"
|
|
|
|
|
echo ""
|
|
|
|
|
local i
|
|
|
|
|
for ((i=0; i<${#net_array[@]}; i++)); do
|
|
|
|
|
local suffix=""
|
|
|
|
|
[[ "${net_array[$i]}" == "bridge" || "${net_array[$i]}" == "host" || "${net_array[$i]}" == "none" ]] && suffix=" (Standard - nicht loeschbar)"
|
|
|
|
|
printf " %d. %s%s\n" "$((i+1))" "${net_array[$i]}" "$suffix"
|
|
|
|
|
done
|
|
|
|
|
echo ""
|
|
|
|
|
read -rp "Nummer des Netzwerks eingeben (0 = Abbrechen): " choice
|
|
|
|
|
|
|
|
|
|
if [[ "$choice" == "0" || -z "$choice" ]]; then
|
|
|
|
|
echo "Abgebrochen."
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! [[ "$choice" =~ ^[0-9]+$ ]] || ((choice < 1 || choice > ${#net_array[@]})); then
|
|
|
|
|
echo "Fehler: Ungueltige Nummer."
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local selected_net="${net_array[$((choice-1))]}"
|
|
|
|
|
if [[ "$selected_net" == "bridge" || "$selected_net" == "host" || "$selected_net" == "none" ]]; then
|
|
|
|
|
echo "FEHLER: '$selected_net' ist ein Docker-Standardnetzwerk und kann nicht geloescht werden."
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
echo ""
|
|
|
|
|
read -rp "Netzwerk '$selected_net' wirklich loeschen? [j/N]: " confirm
|
|
|
|
|
if [[ "$confirm" != "j" && "$confirm" != "J" ]]; then
|
|
|
|
|
echo "Abgebrochen."
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
if docker network rm "$selected_net" 2>/dev/null; then
|
|
|
|
|
echo "OK: Netzwerk '$selected_net' erfolgreich geloescht."
|
|
|
|
|
else
|
|
|
|
|
echo "FEHLER: Netzwerk '$selected_net' konnte nicht geloescht werden (wird moeglicherweise noch genutzt)."
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Interaktive Menü-Funktion
|
|
|
|
|
interactive_menu() {
|
|
|
|
|
while true; do
|
|
|
|
|
@@ -169,9 +267,11 @@ interactive_menu() {
|
|
|
|
|
echo "2. Detaillierte Infos zu einem Netzwerk"
|
|
|
|
|
echo "3. IPs eines Netzwerks anzeigen"
|
|
|
|
|
echo "4. Alle belegten IPs anzeigen"
|
|
|
|
|
echo "5. Ungenutzte Netzwerke anzeigen"
|
|
|
|
|
echo "6. Netzwerke loeschen"
|
|
|
|
|
echo "0. Beenden"
|
|
|
|
|
echo ""
|
|
|
|
|
read -p "Bitte waehlen Sie eine Option (0-4): " choice
|
|
|
|
|
read -rp "Bitte waehlen Sie eine Option (0-6): " choice
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
case "$choice" in
|
|
|
|
|
@@ -203,12 +303,18 @@ interactive_menu() {
|
|
|
|
|
4)
|
|
|
|
|
list_ips_all_networks
|
|
|
|
|
;;
|
|
|
|
|
5)
|
|
|
|
|
list_unused_networks
|
|
|
|
|
;;
|
|
|
|
|
6)
|
|
|
|
|
delete_networks
|
|
|
|
|
;;
|
|
|
|
|
0)
|
|
|
|
|
echo "Auf Wiedersehen!"
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
echo "FEHLER: Ungueltige Eingabe '$choice'. Bitte geben Sie eine Nummer zwischen 0 und 4 ein."
|
|
|
|
|
echo "FEHLER: Ungueltige Eingabe '$choice'. Bitte geben Sie eine Nummer zwischen 0 und 6 ein."
|
|
|
|
|
sleep 1
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
@@ -240,26 +346,44 @@ select_and_inspect_network() {
|
|
|
|
|
# Separate Funktion fuer Netzwerk-Inspektion
|
|
|
|
|
inspect_network() {
|
|
|
|
|
local NET="$1"
|
|
|
|
|
|
|
|
|
|
# 1) Netzwerk-ID und Bridge-Name separat holen
|
|
|
|
|
|
|
|
|
|
local DRIVER
|
|
|
|
|
DRIVER="$(docker network inspect "$NET" --format '{{.Driver}}' 2>/dev/null || true)"
|
|
|
|
|
[[ -z "$DRIVER" ]] && { echo "Fehler: Netzwerk '$NET' nicht gefunden."; return 2; }
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
print_rule "="
|
|
|
|
|
echo "Detaillerte Informationen fuer Netzwerk: $NET"
|
|
|
|
|
print_rule "="
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
# Sonderbehandlung fuer Docker-Standardnetzwerke
|
|
|
|
|
if [[ "$NET" == "none" || "$NET" == "host" || "$NET" == "bridge" ]]; then
|
|
|
|
|
cat <<OUT
|
|
|
|
|
Docker-Netzwerk : $NET
|
|
|
|
|
Driver : $DRIVER
|
|
|
|
|
Hinweis : Dies ist ein Docker-Standardnetzwerk und kann nicht geloescht werden.
|
|
|
|
|
OUT
|
|
|
|
|
echo ""
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 1) Netzwerk-ID und Bridge-Name
|
|
|
|
|
local ID BR_RAW IF SUBNET GATEWAY state rxb txb rxp txp
|
|
|
|
|
ID="$(docker network inspect "$NET" --format '{{.Id}}' 2>/dev/null || true)"
|
|
|
|
|
[[ -z "$ID" ]] && { echo "Fehler: Netzwerk '$NET' nicht gefunden."; return 2; }
|
|
|
|
|
|
|
|
|
|
BR_RAW="$(docker network inspect "$NET" --format '{{index .Options "com.docker.network.bridge.name"}}' 2>/dev/null || true)"
|
|
|
|
|
|
|
|
|
|
# 2) Falls kein eigener Bridge-Name: Standardname br-<ID[:12]>
|
|
|
|
|
if [[ -z "$BR_RAW" || "$BR_RAW" == "<no value>" ]]; then
|
|
|
|
|
IF="br-${ID:0:12}"
|
|
|
|
|
else
|
|
|
|
|
IF="$BR_RAW"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 3) Subnet/Gateway
|
|
|
|
|
# 2) Subnet/Gateway
|
|
|
|
|
SUBNET="$(docker network inspect "$NET" --format '{{(index .IPAM.Config 0).Subnet}}' 2>/dev/null || true)"
|
|
|
|
|
GATEWAY="$(docker network inspect "$NET" --format '{{(index .IPAM.Config 0).Gateway}}' 2>/dev/null || true)"
|
|
|
|
|
|
|
|
|
|
# 4) Interface-Status & Stats
|
|
|
|
|
# 3) Interface-Status & Stats
|
|
|
|
|
state="unknown"; rxb=0; txb=0; rxp=0; txp=0
|
|
|
|
|
if ip link show "$IF" &>/dev/null; then
|
|
|
|
|
state="$(cat /sys/class/net/"$IF"/operstate 2>/dev/null || echo unknown)"
|
|
|
|
|
@@ -267,18 +391,11 @@ inspect_network() {
|
|
|
|
|
txb="$(cat /sys/class/net/"$IF"/statistics/tx_bytes 2>/dev/null || echo 0)"
|
|
|
|
|
rxp="$(cat /sys/class/net/"$IF"/statistics/rx_packets 2>/dev/null || echo 0)"
|
|
|
|
|
txp="$(cat /sys/class/net/"$IF"/statistics/tx_packets 2>/dev/null || echo 0)"
|
|
|
|
|
else
|
|
|
|
|
echo "WARN: Interface $IF existiert (noch) nicht auf dem Host."
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
print_rule "="
|
|
|
|
|
echo "Detaillerte Informationen fuer Netzwerk: $NET"
|
|
|
|
|
print_rule "="
|
|
|
|
|
echo ""
|
|
|
|
|
cat <<OUT
|
|
|
|
|
Docker-Netzwerk : $NET
|
|
|
|
|
Driver : $(docker network inspect "$NET" --format '{{.Driver}}')
|
|
|
|
|
Driver : $DRIVER
|
|
|
|
|
Bridge-Interface : $IF
|
|
|
|
|
Subnet/Gateway : ${SUBNET:--} / ${GATEWAY:--}
|
|
|
|
|
OperState : $state
|
|
|
|
|
@@ -305,6 +422,14 @@ case "$COMMAND" in
|
|
|
|
|
list_ips_all_networks
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
unused-networks)
|
|
|
|
|
list_unused_networks
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
delete-networks)
|
|
|
|
|
delete_networks
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
help | -h | --help)
|
|
|
|
|
show_help
|
|
|
|
|
exit 0
|
|
|
|
|
|