...

Text file src/k8s.io/kubernetes/hack/grab-profiles.sh

Documentation: k8s.io/kubernetes/hack

     1#!/usr/bin/env bash
     2
     3# Copyright 2015 The Kubernetes Authors.
     4#
     5# Licensed under the Apache License, Version 2.0 (the "License");
     6# you may not use this file except in compliance with the License.
     7# You may obtain a copy of the License at
     8#
     9#     http://www.apache.org/licenses/LICENSE-2.0
    10#
    11# Unless required by applicable law or agreed to in writing, software
    12# distributed under the License is distributed on an "AS IS" BASIS,
    13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14# See the License for the specific language governing permissions and
    15# limitations under the License.
    16
    17# This script grabs profiles from running components.
    18# Usage: `hack/grab-profiles.sh`.
    19
    20set -o errexit
    21set -o nounset
    22set -o pipefail
    23
    24function grab_profiles_from_component {
    25  local requested_profiles=$1
    26  local mem_pprof_flags=$2
    27  local binary=$3
    28  local tunnel_port=$4
    29  local path=$5
    30  local output_prefix=$6
    31  local timestamp=$7
    32
    33  echo "binary: $binary"
    34
    35  for profile in ${requested_profiles}; do
    36    case ${profile} in
    37      cpu)
    38        go tool pprof "-pdf" "${binary}" "http://localhost:${tunnel_port}${path}/debug/pprof/profile" > "${output_prefix}-${profile}-profile-${timestamp}.pdf"
    39        ;;
    40      mem)
    41        # There are different kinds of memory profiles that are available that
    42        # had to be grabbed separately: --inuse-space, --inuse-objects,
    43        # --alloc-space, --alloc-objects. We need to iterate over all requested
    44        # kinds.
    45        for flag in ${mem_pprof_flags}; do
    46          go tool pprof "-${flag}" "-pdf" "${binary}" "http://localhost:${tunnel_port}${path}/debug/pprof/heap" > "${output_prefix}-${profile}-${flag}-profile-${timestamp}.pdf"
    47        done
    48        ;;
    49    esac
    50  done
    51}
    52
    53KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
    54source "${KUBE_ROOT}/hack/lib/init.sh"
    55
    56server_addr=""
    57kubelet_addresses=""
    58kubelet_binary=""
    59master_binary=""
    60scheduler_binary=""
    61scheduler_port="10251"
    62controller_manager_port="10252"
    63controller_manager_binary=""
    64requested_profiles=""
    65mem_pprof_flags=""
    66profile_components=""
    67output_dir="."
    68tunnel_port="${tunnel_port:-1234}"
    69
    70if ! args=$(getopt -o s:mho:k:c -l server:,master,heapster,output:,kubelet:,scheduler,controller-manager,help,inuse-space,inuse-objects,alloc-space,alloc-objects,cpu,kubelet-binary:,master-binary:,scheduler-binary:,controller-manager-binary:,scheduler-port:,controller-manager-port: -- "$@"); then
    71  >&2 echo "Error in getopt"
    72  exit 1
    73fi
    74
    75HEAPSTER_VERSION="v0.18.2"
    76MASTER_PPROF_PATH=""
    77HEAPSTER_PPROF_PATH="/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy"
    78KUBELET_PPROF_PATH_PREFIX="/api/v1/proxy/nodes"
    79SCHEDULER_PPROF_PATH_PREFIX="/api/v1/namespaces/kube-system/pods/kube-scheduler/proxy"
    80CONTROLLER_MANAGER_PPROF_PATH_PREFIX="/api/v1/namespaces/kube-system/pods/kube-controller-manager/proxy"
    81
    82eval set -- "${args}"
    83
    84while true; do
    85  case $1 in
    86    -s|--server)
    87      shift
    88      if [ -z "$1" ]; then
    89        >&2 echo "empty argument to --server flag"
    90        exit 1
    91      fi
    92      server_addr=$1
    93      shift
    94      ;;
    95    -m|--master)
    96      shift
    97      profile_components="master ${profile_components}"
    98      ;;
    99    --master-binary)
   100      shift
   101      if [ -z "$1" ]; then
   102        >&2 echo "empty argument to --master-binary flag"
   103        exit 1
   104      fi
   105      master_binary=$1
   106      shift
   107      ;;
   108    -h|--heapster)
   109      shift
   110      profile_components="heapster ${profile_components}"
   111      ;;
   112    -k|--kubelet)
   113      shift
   114      profile_components="kubelet ${profile_components}"
   115      if [ -z "$1" ]; then
   116        >&2 echo "empty argument to --kubelet flag"
   117        exit 1
   118      fi
   119      kubelet_addresses="$1 $kubelet_addresses"
   120      shift
   121      ;;
   122    --kubelet-binary)
   123      shift
   124      if [ -z "$1" ]; then
   125        >&2 echo "empty argument to --kubelet-binary flag"
   126        exit 1
   127      fi
   128      kubelet_binary=$1
   129      shift
   130      ;;
   131    --scheduler)
   132      shift
   133      profile_components="scheduler ${profile_components}"
   134      ;;
   135    --scheduler-binary)
   136      shift
   137      if [ -z "$1" ]; then
   138        >&2 echo "empty argument to --scheduler-binary flag"
   139        exit 1
   140      fi
   141      scheduler_binary=$1
   142      shift
   143      ;;
   144    --scheduler-port)
   145      shift
   146      if [ -z "$1" ]; then
   147        >&2 echo "empty argument to --scheduler-port flag"
   148        exit 1
   149      fi
   150      scheduler_port=$1
   151      shift
   152      ;;
   153    -c|--controller-manager)
   154      shift
   155      profile_components="controller-manager ${profile_components}"
   156      ;;
   157    --controller-manager-binary)
   158      shift
   159      if [ -z "$1" ]; then
   160        >&2 echo "empty argument to --controller-manager-binary flag"
   161        exit 1
   162      fi
   163      controller_manager_binary=$1
   164      shift
   165      ;;
   166    --controller-manager-port)
   167      shift
   168      if [ -z "$1" ]; then
   169        >&2 echo "empty argument to --controller-manager-port flag"
   170        exit 1
   171      fi
   172      controller_manager_port=$1
   173      shift
   174      ;;
   175    -o|--output)
   176      shift
   177      if [ -z "$1" ]; then
   178        >&2 echo "empty argument to --output flag"
   179        exit 1
   180      fi
   181      output_dir=$1
   182      shift
   183      ;;
   184    --inuse-space)
   185      shift
   186      requested_profiles="mem ${requested_profiles}"
   187      mem_pprof_flags="inuse_space ${mem_pprof_flags}"
   188      ;;
   189    --inuse-objects)
   190      shift
   191      requested_profiles="mem ${requested_profiles}"
   192      mem_pprof_flags="inuse_objects ${mem_pprof_flags}"
   193      ;;
   194    --alloc-space)
   195      shift
   196      requested_profiles="mem ${requested_profiles}"
   197      mem_pprof_flags="alloc_space ${mem_pprof_flags}"
   198      ;;
   199    --alloc-objects)
   200      shift
   201      requested_profiles="mem ${requested_profiles}"
   202      mem_pprof_flags="alloc_objects ${mem_pprof_flags}"
   203      ;;
   204    --cpu)
   205      shift
   206      requested_profiles="cpu ${requested_profiles}"
   207      ;;
   208    --help)
   209      shift
   210      echo "Recognized options:
   211        -o/--output,
   212        -s/--server,
   213        -m/--master,
   214        -h/--heapster,
   215        --inuse-space,
   216        --inuse-objects,
   217        --alloc-space,
   218        --alloc-objects,
   219        --cpu,
   220        --help"
   221      exit 0
   222      ;;
   223    --)
   224      shift
   225      break;
   226      ;;
   227  esac
   228done
   229
   230if [[ -z "${server_addr}" ]]; then
   231  >&2 echo "Server flag is required"
   232  exit 1
   233fi
   234
   235if [[ -z "${profile_components}" ]]; then
   236  >&2 echo "Choose at least one component to profile"
   237  exit 1
   238fi
   239
   240if [[ -z "${requested_profiles}" ]]; then
   241  >&2 echo "Choose at least one profiling option"
   242  exit 1
   243fi
   244
   245gcloud compute ssh "${server_addr}" --ssh-flag=-nN --ssh-flag=-L"${tunnel_port}":localhost:8080 &
   246
   247echo "Waiting for tunnel to be created..."
   248kube::util::wait_for_url http://localhost:"${tunnel_port}"/healthz
   249
   250SSH_PID=$(pgrep -f "/usr/bin/ssh.*${tunnel_port}:localhost:8080")
   251kube::util::trap_add "kill $SSH_PID" EXIT
   252kube::util::trap_add "kill $SSH_PID" SIGTERM
   253
   254requested_profiles=$(echo "${requested_profiles}" | xargs -n1 | LC_ALL=C sort -u | xargs)
   255profile_components=$(echo "${profile_components}" | xargs -n1 | LC_ALL=C sort -u | xargs)
   256kubelet_addresses=$(echo "${kubelet_addresses}" | xargs -n1 | LC_ALL=C sort -u | xargs)
   257echo "requested profiles: ${requested_profiles}"
   258echo "flags for heap profile: ${mem_pprof_flags}"
   259
   260timestamp=$(date +%Y%m%d%H%M%S)
   261binary=""
   262
   263for component in ${profile_components}; do
   264  case ${component} in
   265    master)
   266      path=${MASTER_PPROF_PATH}
   267      binary=${master_binary}
   268      ;;
   269    controller-manager)
   270      path="${CONTROLLER_MANAGER_PPROF_PATH_PREFIX}-${server_addr}:${controller_manager_port}"
   271      binary=${controller_manager_binary}
   272      ;;
   273    scheduler)
   274      path="${SCHEDULER_PPROF_PATH_PREFIX}-${server_addr}:${scheduler_port}"
   275      binary=${scheduler_binary}
   276      ;;
   277    heapster)
   278      rm heapster
   279      wget https://github.com/kubernetes/heapster/releases/download/${HEAPSTER_VERSION}/heapster
   280      kube::util::trap_add 'rm -f heapster' EXIT
   281      kube::util::trap_add 'rm -f heapster' SIGTERM
   282      binary=heapster
   283      path=${HEAPSTER_PPROF_PATH}
   284      ;;
   285    kubelet)
   286      path="${KUBELET_PPROF_PATH_PREFIX}"
   287      if [[ -z "${kubelet_binary}" ]]; then
   288        binary="${KUBE_ROOT}/_output/local/bin/linux/amd64/kubelet"
   289      else
   290        binary=${kubelet_binary}
   291      fi
   292      ;;
   293  esac
   294
   295  if [[ "${component}" == "kubelet" ]]; then
   296    for node in ${kubelet_addresses//[,;]/' '}; do
   297      grab_profiles_from_component "${requested_profiles}" "${mem_pprof_flags}" "${binary}" "${tunnel_port}" "${path}/${node}/proxy" "${output_dir}/${component}" "${timestamp}"
   298    done
   299  else
   300    grab_profiles_from_component "${requested_profiles}" "${mem_pprof_flags}" "${binary}" "${tunnel_port}" "${path}" "${output_dir}/${component}" "${timestamp}"
   301  fi
   302done

View as plain text