| #!/usr/bin/env bash |
| |
| while getopts ":s" opt; do |
| case $opt in |
| s) |
| SSD="true" |
| ;; |
| esac |
| done |
| |
| SSD="${SSD:-false}" |
| |
| # Required tools |
| DOCKER="${DOCKER:-docker}" |
| NSENTER="${NSENTER:-nsenter}" |
| BRIDGE="${BRIDGE:-bridge}" |
| IPTABLES="${IPTABLES:-iptables}" |
| IPVSADM="${IPVSADM:-ipvsadm}" |
| IP="${IP:-ip}" |
| SSDBIN="${SSDBIN:-ssd}" |
| JQ="${JQ:-jq}" |
| |
| networks=0 |
| containers=0 |
| ip_overlap=0 |
| |
| NSDIR=/var/run/docker/netns |
| |
| function die() { |
| echo $* |
| exit 1 |
| } |
| |
| function echo_and_run() { |
| echo "#" "$@" |
| eval $(printf '%q ' "$@") < /dev/stdout |
| } |
| |
| function check_ip_overlap() { |
| inspect=$1 |
| overlap=$(echo "$inspect_output" | grep "EndpointIP\|VIP" | cut -d':' -f2 | sort | uniq -c | grep -v "1 ") |
| if [ ! -z "$overlap" ]; then |
| echo -e "\n\n*** OVERLAP on Network ${networkID} ***" |
| echo -e "${overlap} \n\n" |
| ((ip_overlap++)) |
| else |
| echo "No overlap" |
| fi |
| } |
| |
| type -P ${DOCKER} > /dev/null || echo "This tool requires the docker binary" |
| type -P ${NSENTER} > /dev/null || echo "This tool requires nsenter" |
| type -P ${BRIDGE} > /dev/null || echo "This tool requires bridge" |
| type -P ${IPTABLES} > /dev/null || echo "This tool requires iptables" |
| type -P ${IPVSADM} > /dev/null || echo "This tool requires ipvsadm" |
| type -P ${IP} > /dev/null || echo "This tool requires ip" |
| type -P ${JQ} > /dev/null || echo "This tool requires jq" |
| |
| if ${DOCKER} network inspect --help | grep -q -- --verbose; then |
| NETINSPECT_VERBOSE_SUPPORT="--verbose" |
| else |
| NETINSPECT_VERBOSE_SUPPORT="" |
| fi |
| |
| echo "Host iptables" |
| echo_and_run ${IPTABLES} -w1 -n -v -L -t filter | grep -v '^$' |
| echo_and_run ${IPTABLES} -w1 -n -v -L -t nat | grep -v '^$' |
| echo_and_run ${IPTABLES} -w1 -n -v -L -t mangle | grep -v '^$' |
| printf "\n" |
| |
| echo "Host links addresses and routes" |
| echo_and_run ${IP} -o link show |
| echo_and_run ${IP} -o -4 address show |
| echo_and_run ${IP} -4 route show |
| printf "\n" |
| |
| echo "Overlay network configuration" |
| for networkID in $(${DOCKER} network ls --no-trunc --filter driver=overlay -q) "ingress_sbox"; do |
| echo "nnn Network ${networkID}" |
| if [ "${networkID}" != "ingress_sbox" ]; then |
| nspath=($(ls ${NSDIR}/*${networkID:0:9}*)) |
| inspect_output=$(${DOCKER} network inspect ${NETINSPECT_VERBOSE_SUPPORT} ${networkID}) |
| echo "$inspect_output" |
| check_ip_overlap $inspect_output |
| else |
| nspath=(${NSDIR}/${networkID}) |
| fi |
| |
| for i in "${nspath[@]}"; do |
| echo_and_run ${NSENTER} --net=${i} ${IP} -o -4 address show |
| echo_and_run ${NSENTER} --net=${i} ${IP} -4 route show |
| echo_and_run ${NSENTER} --net=${i} ${IP} -4 neigh show |
| bridges=$(${NSENTER} --net=${i} ${IP} -j link show type bridge | ${JQ} -r '.[].ifname') |
| # break string to array |
| bridges=(${bridges}) |
| for b in "${bridges[@]}"; do |
| if [ -z ${b} ] || [ ${b} == "null" ]; then |
| continue |
| fi |
| echo_and_run ${NSENTER} --net=${i} ${BRIDGE} fdb show br ${b} |
| done |
| echo_and_run ${NSENTER} --net=${i} ${IPTABLES} -w1 -n -v -L -t filter | grep -v '^$' |
| echo_and_run ${NSENTER} --net=${i} ${IPTABLES} -w1 -n -v -L -t nat | grep -v '^$' |
| echo_and_run ${NSENTER} --net=${i} ${IPTABLES} -w1 -n -v -L -t mangle | grep -v '^$' |
| echo_and_run ${NSENTER} --net=${i} ${IPVSADM} -l -n |
| printf "\n" |
| ((networks++)) |
| done |
| done |
| |
| echo "Container network configuration" |
| while read containerID status; do |
| echo "ccc Container ${containerID} state: ${status}" |
| ${DOCKER} container inspect ${containerID} --format 'Name:{{json .Name | printf "%s\n"}}Id:{{json .Id | printf "%s\n"}}Hostname:{{json .Config.Hostname | printf "%s\n"}}CreatedAt:{{json .Created | printf "%s\n"}}State:{{json .State|printf "%s\n"}}RestartCount:{{json .RestartCount | printf "%s\n" }}Labels:{{json .Config.Labels | printf "%s\n"}}NetworkSettings:{{json .NetworkSettings}}' | sed '/^State:/ {s/\\"/QUOTE/g; s/,"Output":"[^"]*"//g;}' |
| if [ ${status} = "Up" ]; then |
| nspath=$(docker container inspect --format {{.NetworkSettings.SandboxKey}} ${containerID}) |
| echo_and_run ${NSENTER} --net=${nspath[0]} ${IP} -o -4 address show |
| echo_and_run ${NSENTER} --net=${nspath[0]} ${IP} -4 route show |
| echo_and_run ${NSENTER} --net=${nspath[0]} ${IP} -4 neigh show |
| echo_and_run ${NSENTER} --net=${nspath[0]} ${IPTABLES} -w1 -n -v -L -t nat | grep -v '^$' |
| echo_and_run ${NSENTER} --net=${nspath[0]} ${IPTABLES} -w1 -n -v -L -t mangle | grep -v '^$' |
| echo_and_run ${NSENTER} --net=${nspath[0]} ${IPVSADM} -l -n |
| ((containers++)) |
| fi |
| printf "\n" |
| done < <(${DOCKER} container ls -a --format '{{.ID}} {{.Status}}' | cut -d' ' -f1,2) |
| |
| if [ "true" == ${SSD} ]; then |
| echo "" |
| echo "#### SSD control-plane and datapath consistency check on a node ####" |
| for netName in $(docker network ls -f driver=overlay --format "{{.Name}}"); do |
| echo "## $netName ##" |
| ${SSDBIN} $netName |
| echo "" |
| done |
| fi |
| |
| echo -e "\n\n==SUMMARY==" |
| echo -e "\t Processed $networks networks" |
| echo -e "\t IP overlap found: $ip_overlap" |
| echo -e "\t Processed $containers running containers" |