support.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/usr/bin/env bash
  2. while getopts ":s" opt; do
  3. case $opt in
  4. s)
  5. SSD="true"
  6. ;;
  7. esac
  8. done
  9. SSD="${SSD:-false}"
  10. # Required tools
  11. DOCKER="${DOCKER:-docker}"
  12. NSENTER="${NSENTER:-nsenter}"
  13. BRIDGE="${BRIDGE:-bridge}"
  14. IPTABLES="${IPTABLES:-iptables}"
  15. IPVSADM="${IPVSADM:-ipvsadm}"
  16. IP="${IP:-ip}"
  17. SSDBIN="${SSDBIN:-ssd}"
  18. JQ="${JQ:-jq}"
  19. networks=0
  20. containers=0
  21. ip_overlap=0
  22. NSDIR=/var/run/docker/netns
  23. function die() {
  24. echo $*
  25. exit 1
  26. }
  27. function echo_and_run() {
  28. echo "#" "$@"
  29. eval $(printf '%q ' "$@") < /dev/stdout
  30. }
  31. function check_ip_overlap() {
  32. inspect=$1
  33. overlap=$(echo "$inspect_output" | grep "EndpointIP\|VIP" | cut -d':' -f2 | sort | uniq -c | grep -v "1 ")
  34. if [ ! -z "$overlap" ]; then
  35. echo -e "\n\n*** OVERLAP on Network ${networkID} ***"
  36. echo -e "${overlap} \n\n"
  37. ((ip_overlap++))
  38. else
  39. echo "No overlap"
  40. fi
  41. }
  42. type -P ${DOCKER} > /dev/null || echo "This tool requires the docker binary"
  43. type -P ${NSENTER} > /dev/null || echo "This tool requires nsenter"
  44. type -P ${BRIDGE} > /dev/null || echo "This tool requires bridge"
  45. type -P ${IPTABLES} > /dev/null || echo "This tool requires iptables"
  46. type -P ${IPVSADM} > /dev/null || echo "This tool requires ipvsadm"
  47. type -P ${IP} > /dev/null || echo "This tool requires ip"
  48. type -P ${JQ} > /dev/null || echo "This tool requires jq"
  49. if ${DOCKER} network inspect --help | grep -q -- --verbose; then
  50. NETINSPECT_VERBOSE_SUPPORT="--verbose"
  51. else
  52. NETINSPECT_VERBOSE_SUPPORT=""
  53. fi
  54. echo "Host iptables"
  55. echo_and_run ${IPTABLES} -w1 -n -v -L -t filter | grep -v '^$'
  56. echo_and_run ${IPTABLES} -w1 -n -v -L -t nat | grep -v '^$'
  57. echo_and_run ${IPTABLES} -w1 -n -v -L -t mangle | grep -v '^$'
  58. printf "\n"
  59. echo "Host links addresses and routes"
  60. echo_and_run ${IP} -o link show
  61. echo_and_run ${IP} -o -4 address show
  62. echo_and_run ${IP} -4 route show
  63. printf "\n"
  64. echo "Overlay network configuration"
  65. for networkID in $(${DOCKER} network ls --no-trunc --filter driver=overlay -q) "ingress_sbox"; do
  66. echo "nnn Network ${networkID}"
  67. if [ "${networkID}" != "ingress_sbox" ]; then
  68. nspath=($(ls ${NSDIR}/*${networkID:0:9}*))
  69. inspect_output=$(${DOCKER} network inspect ${NETINSPECT_VERBOSE_SUPPORT} ${networkID})
  70. echo "$inspect_output"
  71. check_ip_overlap $inspect_output
  72. else
  73. nspath=(${NSDIR}/${networkID})
  74. fi
  75. for i in "${nspath[@]}"; do
  76. echo_and_run ${NSENTER} --net=${i} ${IP} -o -4 address show
  77. echo_and_run ${NSENTER} --net=${i} ${IP} -4 route show
  78. echo_and_run ${NSENTER} --net=${i} ${IP} -4 neigh show
  79. bridges=$(${NSENTER} --net=${i} ${IP} -j link show type bridge | ${JQ} -r '.[].ifname')
  80. # break string to array
  81. bridges=(${bridges})
  82. for b in "${bridges[@]}"; do
  83. if [ -z ${b} ] || [ ${b} == "null" ]; then
  84. continue
  85. fi
  86. echo_and_run ${NSENTER} --net=${i} ${BRIDGE} fdb show br ${b}
  87. done
  88. echo_and_run ${NSENTER} --net=${i} ${IPTABLES} -w1 -n -v -L -t filter | grep -v '^$'
  89. echo_and_run ${NSENTER} --net=${i} ${IPTABLES} -w1 -n -v -L -t nat | grep -v '^$'
  90. echo_and_run ${NSENTER} --net=${i} ${IPTABLES} -w1 -n -v -L -t mangle | grep -v '^$'
  91. echo_and_run ${NSENTER} --net=${i} ${IPVSADM} -l -n
  92. printf "\n"
  93. ((networks++))
  94. done
  95. done
  96. echo "Container network configuration"
  97. while read containerID status; do
  98. echo "ccc Container ${containerID} state: ${status}"
  99. ${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;}'
  100. if [ ${status} = "Up" ]; then
  101. nspath=$(docker container inspect --format {{.NetworkSettings.SandboxKey}} ${containerID})
  102. echo_and_run ${NSENTER} --net=${nspath[0]} ${IP} -o -4 address show
  103. echo_and_run ${NSENTER} --net=${nspath[0]} ${IP} -4 route show
  104. echo_and_run ${NSENTER} --net=${nspath[0]} ${IP} -4 neigh show
  105. echo_and_run ${NSENTER} --net=${nspath[0]} ${IPTABLES} -w1 -n -v -L -t nat | grep -v '^$'
  106. echo_and_run ${NSENTER} --net=${nspath[0]} ${IPTABLES} -w1 -n -v -L -t mangle | grep -v '^$'
  107. echo_and_run ${NSENTER} --net=${nspath[0]} ${IPVSADM} -l -n
  108. ((containers++))
  109. fi
  110. printf "\n"
  111. done < <(${DOCKER} container ls -a --format '{{.ID}} {{.Status}}' | cut -d' ' -f1,2)
  112. if [ "true" == ${SSD} ]; then
  113. echo ""
  114. echo "#### SSD control-plane and datapath consistency check on a node ####"
  115. for netName in $(docker network ls -f driver=overlay --format "{{.Name}}"); do
  116. echo "## $netName ##"
  117. ${SSDBIN} $netName
  118. echo ""
  119. done
  120. fi
  121. echo -e "\n\n==SUMMARY=="
  122. echo -e "\t Processed $networks networks"
  123. echo -e "\t IP overlap found: $ip_overlap"
  124. echo -e "\t Processed $containers running containers"