mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
PRF
@geekpi
This commit is contained in:
parent
ff90ea58d2
commit
5c2e49cb9f
@ -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" > results.csv
|
printf "%s %s %s\n" "NAMESPACE,POD_NAME,CONTAINER_NAME,ERRORS" > results.csv
|
||||||
printf "%s %s %s\n" "---------,--------,--------------,------" >> 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>/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< <($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} >> results.csv
|
printf "%s\n" ${STATE[@]:-None} >> results.csv
|
||||||
STATE=()
|
STATE=()
|
||||||
}
|
}
|
||||||
#define usage for seprate run
|
#define usage for seprate run
|
||||||
usage()
|
usage()
|
||||||
{
|
{
|
||||||
cat << EOF
|
cat << EOF
|
||||||
|
|
||||||
USAGE: "${0##*/} </path/to/kube-config>(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/) 荣誉推出
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user