@geekpi
This commit is contained in:
Xingyu Wang 2020-02-27 10:29:42 +08:00
parent ff90ea58d2
commit 5c2e49cb9f

View File

@ -1,6 +1,6 @@
[#]: collector: (lujun9972) [#]: collector: (lujun9972)
[#]: translator: (geekpi) [#]: translator: (geekpi)
[#]: reviewer: ( ) [#]: reviewer: (wxy)
[#]: publisher: ( ) [#]: publisher: ( )
[#]: url: ( ) [#]: url: ( )
[#]: subject: (Scan Kubernetes for errors with KRAWL) [#]: subject: (Scan Kubernetes for errors with KRAWL)
@ -9,25 +9,25 @@
使用 KRAWL 扫描 Kubernetes 错误 使用 KRAWL 扫描 Kubernetes 错误
====== ======
用 KRAWL 脚本来标识 Kubernetes pod 和容器中的错误。
> 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。
![Ship captain sailing the Kubernetes seas][1] ![Ship captain sailing the Kubernetes seas][1]
当你使用 Kubernetes 运行容器时,你通常会发现它们堆积。这是设计使然。它是容器的优点之一:每当需要新的容器时,它们启动成本都很低。你可以使用前端(如 OpenShift 或 OKD来管理 pod 和容器。这些工具使可视化设置变得容易,并且它具有一组丰富的用于快速交互的命令。 当你使用 Kubernetes 运行容器时,你通常会发现它们堆积在一起。这是设计使然。它是容器的优点之一:每当需要新的容器时,它们启动成本都很低。你可以使用前端工具(如 OpenShift 或 OKD来管理 Pod 和容器。这些工具使可视化设置变得容易,并且它具有一组丰富的用于快速交互的命令。
如果管理容器的平台不符合你的要求,你也可以仅使用 Kubernetes 工具链获取这些信息,但这需要大量命令才能全面了解复杂环境。出于这个原因,我编写了 [KRAWL][2],这是一个简单的脚本,可用于扫描 Kubernetes 集群命名空间下的 pod 和容器,并在发现任何事件时,显示事件的输出。它也可用作为 Kubernetes 插件使用。这是获取大量有用信息的快速简便方法。 如果管理容器的平台不符合你的要求,你也可以仅使用 Kubernetes 工具链获取这些信息,但这需要大量命令才能全面了解复杂环境。出于这个原因,我编写了 [KRAWL][2],这是一个简单的脚本,可用于扫描 Kubernetes 集群命名空间下的 Pod 和容器,并在发现任何事件时,显示事件的输出。它也可用作为 Kubernetes 插件使用。这是获取大量有用信息的快速简便方法。
### 预先条件
* 必须安装 kubectl。
* 集群的 kubeconfig 配置必须在它的默认位置 $HOME/.kube/config 或已被导出。
### 先决条件
* 必须安装 `kubectl`
* 集群的 kubeconfig 配置必须在它的默认位置(`$HOME/.kube/config`)或已被导出到环境变量(`KUBECONFIG=/path/to/kubeconfig`)。
### 使用 ### 使用
``` ```
`$ ./krawl` $ ./krawl
``` ```
![KRAWL script][3] ![KRAWL script][3]
@ -38,20 +38,20 @@
``` ```
#!/bin/bash #!/bin/bash
# AUTHOR: Abhishek Tamrakar # AUTHOR: Abhishek Tamrakar
# EMAIL: [abhishek.tamrakar08@gmail.com][4] # EMAIL: abhishek.tamrakar08@gmail.com
# LICENSE: Copyright (C) 2018 Abhishek Tamrakar # LICENSE: Copyright (C) 2018 Abhishek Tamrakar
# #
#  Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at # You may obtain a copy of the License at
# #
#       <http://www.apache.org/licenses/LICENSE-2.0> # http://www.apache.org/licenses/LICENSE-2.0
# #
#   Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
#   limitations under the License. # limitations under the License.
## ##
#define the variables #define the variables
KUBE_LOC=~/.kube/config KUBE_LOC=~/.kube/config
@ -66,102 +66,102 @@ normal=$(tput sgr0)
# wrapper for printing info messages # wrapper for printing info messages
info() info()
{ {
  printf '\n\e[34m%s\e[m: %s\n' "INFO" "$@" printf '\n\e[34m%s\e[m: %s\n' "INFO" "$@"
} }
# cleanup when all done # cleanup when all done
cleanup() cleanup()
{ {
  rm -f results.csv rm -f results.csv
} }
# just check if the command we are about to call is available # just check if the command we are about to call is available
checkcmd() checkcmd()
{ {
  #check if command exists #check if command exists
  local cmd=$1 local cmd=$1
  if [ -z "${!cmd}" ] if [ -z "${!cmd}" ]
  then then
    printf '\n\e[31m%s\e[m: %s\n' "ERROR"  "check if $1 is installed !!!" printf '\n\e[31m%s\e[m: %s\n' "ERROR" "check if $1 is installed !!!"
    exit 1 exit 1
  fi fi
} }
get_namespaces() get_namespaces()
{ {
  #get namespaces #get namespaces
  namespaces=( \ namespaces=( \
          $($KUBECTL get namespaces --ignore-not-found=true | \ $($KUBECTL get namespaces --ignore-not-found=true | \
          $AWK '/Active/ {print $1}' \ $AWK '/Active/ {print $1}' \
          ORS=" ") \ ORS=" ") \
          ) )
#exit if namespaces are not found #exit if namespaces are not found
if [ ${#namespaces[@]} -eq 0 ] if [ ${#namespaces[@]} -eq 0 ]
then then
  printf '\n\e[31m%s\e[m: %s\n' "ERROR"  "No namespaces found!!" printf '\n\e[31m%s\e[m: %s\n' "ERROR" "No namespaces found!!"
  exit 1 exit 1
fi fi
} }
#get events for pods in errored state #get events for pods in errored state
get_pod_events() get_pod_events()
{ {
  printf '\n' printf '\n'
  if [ ${#ERRORED[@]} -ne 0 ] if [ ${#ERRORED[@]} -ne 0 ]
  then then
      info "${#ERRORED[@]} errored pods found." info "${#ERRORED[@]} errored pods found."
      for CULPRIT in ${ERRORED[@]} for CULPRIT in ${ERRORED[@]}
      do do
        info "POD: $CULPRIT" info "POD: $CULPRIT"
        info info
        $KUBECTL get events \ $KUBECTL get events \
        --field-selector=involvedObject.name=$CULPRIT \ --field-selector=involvedObject.name=$CULPRIT \
        -ocustom-columns=LASTSEEN:.lastTimestamp,REASON:.reason,MESSAGE:.message \ -ocustom-columns=LASTSEEN:.lastTimestamp,REASON:.reason,MESSAGE:.message \
        --all-namespaces \ --all-namespaces \
        --ignore-not-found=true --ignore-not-found=true
      done done
  else else
      info "0 pods with errored events found." info "0 pods with errored events found."
  fi fi
} }
#define the logic #define the logic
get_pod_errors() get_pod_errors()
{ {
  printf "%s %s %s\n" "NAMESPACE,POD_NAME,CONTAINER_NAME,ERRORS" &gt; results.csv printf "%s %s %s\n" "NAMESPACE,POD_NAME,CONTAINER_NAME,ERRORS" > results.csv
  printf "%s %s %s\n" "---------,--------,--------------,------" &gt;&gt; results.csv printf "%s %s %s\n" "---------,--------,--------------,------" >> results.csv
  for NAMESPACE in ${namespaces[@]} for NAMESPACE in ${namespaces[@]}
  do do
    while IFS=' ' read -r POD CONTAINERS while IFS=' ' read -r POD CONTAINERS
    do do
      for CONTAINER in ${CONTAINERS//,/ } for CONTAINER in ${CONTAINERS//,/ }
      do do
        COUNT=$($KUBECTL logs --since=1h --tail=20 $POD -c $CONTAINER -n $NAMESPACE 2&gt;/dev/null| \ COUNT=$($KUBECTL logs --since=1h --tail=20 $POD -c $CONTAINER -n $NAMESPACE 2>/dev/null| \
        $GET -c '^error|Error|ERROR|Warn|WARN') $GET -c '^error|Error|ERROR|Warn|WARN')
        if [ $COUNT -gt 0 ] if [ $COUNT -gt 0 ]
        then then
            STATE=("${STATE[@]}" "$NAMESPACE,$POD,$CONTAINER,$COUNT") STATE=("${STATE[@]}" "$NAMESPACE,$POD,$CONTAINER,$COUNT")
        else else
        #catch pods in errored state #catch pods in errored state
            ERRORED=($($KUBECTL get pods -n $NAMESPACE --no-headers=true | \ ERRORED=($($KUBECTL get pods -n $NAMESPACE --no-headers=true | \
                awk '!/Running/ {print $1}' ORS=" ") \ awk '!/Running/ {print $1}' ORS=" ") \
                ) )
        fi fi
      done done
    done&lt; &lt;($KUBECTL get pods -n $NAMESPACE --ignore-not-found=true -o=custom-columns=NAME:.metadata.name,CONTAINERS:.spec.containers[*].name --no-headers=true) done< <($KUBECTL get pods -n $NAMESPACE --ignore-not-found=true -o=custom-columns=NAME:.metadata.name,CONTAINERS:.spec.containers[*].name --no-headers=true)
  done done
  printf "%s\n" ${STATE[@]:-None} &gt;&gt; results.csv printf "%s\n" ${STATE[@]:-None} >> results.csv
  STATE=() STATE=()
} }
#define usage for seprate run #define usage for seprate run
usage() usage()
{ {
cat &lt;&lt; EOF cat << EOF
  USAGE: "${0##*/} &lt;/path/to/kube-config&gt;(optional)" USAGE: "${0##*/} </path/to/kube-config>(optional)"
  This program is a free software under the terms of Apache 2.0 License. This program is a free software under the terms of Apache 2.0 License.
  COPYRIGHT (C) 2018 Abhishek Tamrakar COPYRIGHT (C) 2018 Abhishek Tamrakar
EOF EOF
exit 0 exit 0
@ -173,17 +173,17 @@ checkcmd KUBECTL
# #
#set the ground #set the ground
if [ $# -lt 1 ]; then if [ $# -lt 1 ]; then
  if [ ! -e ${KUBE_LOC} -a ! -s ${KUBE_LOC} ] if [ ! -e ${KUBE_LOC} -a ! -s ${KUBE_LOC} ]
  then then
    info "A readable kube config location is required!!" info "A readable kube config location is required!!"
    usage usage
  fi fi
elif [ $# -eq 1 ] elif [ $# -eq 1 ]
then then
  export KUBECONFIG=$1 export KUBECONFIG=$1
elif [ $# -gt 1 ] elif [ $# -gt 1 ]
then then
  usage usage
fi fi
#play #play
get_namespaces get_namespaces
@ -191,7 +191,7 @@ get_pod_errors
printf '\n%40s\n' 'KRAWL' printf '\n%40s\n' 'KRAWL'
printf '%s\n' '---------------------------------------------------------------------------------' printf '%s\n' '---------------------------------------------------------------------------------'
printf '%s\n' '  Krawl is a command line utility to scan pods and prints name of errored pods   ' printf '%s\n' ' Krawl is a command line utility to scan pods and prints name of errored pods '
printf '%s\n\n' ' +and containers within. To use it as kubernetes plugin, please check their page ' printf '%s\n\n' ' +and containers within. To use it as kubernetes plugin, please check their page '
printf '%s\n' '=================================================================================' printf '%s\n' '================================================================================='
@ -199,9 +199,7 @@ cat results.csv | sed 's/,/,|/g'| column -s ',' -t
get_pod_events get_pod_events
``` ```
* * * 此文最初发布在 [KRAWL 的 GitHub 仓库][2]下的 README 中,并被或许重用。
_此文最初发布在 [KRAWL 的 GitHub 仓库][2]下的 README 中并被或许重用。_
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -210,7 +208,7 @@ via: https://opensource.com/article/20/2/kubernetes-scanner
作者:[Abhishek Tamrakar][a] 作者:[Abhishek Tamrakar][a]
选题:[lujun9972][b] 选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi) 译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID) 校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出