Kubernetes 是一个蓬勃发展的开源容器编排平台,为应用程序提供可扩展性、高可用性、稳健性和弹性。它的众多功能之一是支持通过其主要客户端二进制文件 kubectl 运行自定义脚本或二进制文件。Kubectl 非常强大,允许用户使用它执行任何可以直接在 Kubernetes 集群上执行的操作。
使用别名排查 Kubernetes 问题
任何使用 Kubernetes 进行容器编排的人都知道它的功能,以及它因其设计而带来的复杂性。例如,迫切需要简化 Kubernetes 中的故障排除,使其更快,并且几乎不需要人工干预(除非在紧急情况下)。
在故障排除功能方面,有很多场景需要考虑。在一种场景中,您知道需要运行什么,但是命令的语法(即使它可以作为单个命令运行)也过于复杂,或者可能需要一个或两个输入才能工作。
例如,如果您经常需要跳转到 System 命名空间中正在运行的容器中,您可能会发现自己反复编写
kubectl --namespace=kube-system exec -i -t <your-pod-name>
为了简化故障排除,您可以使用这些命令的命令行别名。例如,您可以将以下内容添加到您的 dotfiles 文件(.bashrc 或 .zshrc)中
alias ksysex='kubectl --namespace=kube-system exec -i -t'
这只是 常见 Kubernetes 别名存储库 中的众多示例之一,该存储库展示了一种简化 kubectl 中功能的方法。对于像这种情况这样简单的场景,别名就足够了。
切换到 kubectl 插件
更复杂的故障排除场景涉及需要一个接一个地运行许多命令,以调查环境并得出结论。仅靠别名不足以满足此用途
案例;您需要可重复的逻辑以及 Kubernetes 部署的许多部分之间的关联。您真正需要的是自动化,以便在更短的时间内交付所需的输出。
考虑集群上 10 到 20 个甚至 50 到 100 个持有不同微服务的命名空间。对于您来说,开始排查这种情况,什么会有所帮助?
- 您需要一些可以快速告诉您哪个命名空间中的哪个 Pod 正在抛出错误的东西。
- 您需要一些可以监视命名空间中所有 Pod 日志的东西。
- 您可能还需要监视特定命名空间中已显示错误的某些 Pod 的日志。
任何涵盖这些点的解决方案对于调查生产问题以及开发和测试周期都非常有用。
要创建比简单别名更强大的东西,您可以使用 kubectl 插件。插件就像用任何脚本语言编写的独立脚本,但旨在扩展主命令的功能,在作为 Kubernetes 管理员时提供服务。
要创建插件,您必须使用 kubectl-<您的插件名称> 的正确语法,将脚本复制到 $PATH 中的导出路径之一,并赋予它可执行权限 (chmod +x)。
创建插件并将其移动到您的路径后,您可以立即运行它。例如,我的路径中有 kubectl-krawl 和 kubectl-kmux
$ kubectl plugin list
The following compatible plugins are available:
/usr/local/bin/kubectl-krawl
/usr/local/bin/kubectl-kmux
$ kubectl kmux
现在让我们探索当您使用 tmux 增强 Kubernetes 功能时会是什么样子。
利用 tmux 的强大功能
Tmux 是一个非常强大的工具,许多系统管理员和运维团队都依赖它来排查与易操作性相关的问题,从将窗口拆分为窗格以在多台机器上并行运行调试到监视日志。它的主要优势之一是可以在命令行或自动化脚本中使用。
我创建了一个 kubectl 插件,该插件使用 tmux 使故障排除更加简单。我将使用注释来解释插件背后的逻辑(并让您浏览插件的完整代码)
#NAMESPACE is namespace to monitor.
#POD is pod name
#Containers is container names
# initialize a counter n to count the number of loop counts, later be used by tmux to split panes.
n=0;
# start a loop on a list of pod and containers
while IFS=' ' read -r POD CONTAINERS
do
# tmux create the new window for each pod
tmux neww $COMMAND -n $POD 2>/dev/null
# start a loop for all containers inside a running pod
for CONTAINER in ${CONTAINERS//,/ }
do
if [ x$POD = x -o x$CONTAINER = x ]; then
# if any of the values is null, exit.
warn "Looks like there is a problem getting pods data."
break
fi
# set the command to execute
COMMAND=”kubectl logs -f $POD -c $CONTAINER -n $NAMESPACE”
# check tmux session
if tmux has-session -t <session name> 2>/dev/null;
then
<set session exists>
else
<create session>
fi
# split planes in the current window for each containers
tmux selectp -t $n \; \
splitw $COMMAND \; \
select-layout tiled \;
# end loop for containers
done
# rename the window to identify by pod name
tmux renamew $POD 2>/dev/null
# increment the counter
((n+=1))
# end loop for pods
done< <(<fetch list of pod and containers from kubernetes cluster>)
# finally select the window and attach session
tmux selectw -t <session name>:1 \; \
attach-session -t <session name>\;
插件脚本运行后,它将生成类似于下图的输出。每个 Pod 都有自己的窗口,每个容器(如果有一个以上)都按其 Pod 窗口中的窗格拆分,并流式传输到达的日志。tmux 的美妙之处可以在下面看到;通过适当的配置,您甚至可以看到哪个窗口正在进行活动(请参阅白色标签)。

结论
别名始终有助于 Kubernetes 环境中的简单故障排除。当环境变得更加复杂时,kubectl 插件是使用更高级脚本的强大选择。您可以用来编写 kubectl 插件的编程语言没有限制。唯一的要求是路径中的命名约定是可执行的,并且它与现有的 kubectl 命令名称不同。
要阅读完整代码或试用我创建的插件,请查看我的 kube-plugins-github 存储库。欢迎提出问题和拉取请求。
5 条评论