利用Tmux和kubectl解決Kubernetes故障
一個(gè)使用 tmux 的 kubectl 插件可以使 Kubernetes 疑難問(wèn)題變得更簡(jiǎn)單。
Kubernetes 是一個(gè)活躍的開(kāi)源容器管理平臺(tái),它提供了可擴(kuò)展性、高可用性、健壯性和富有彈性的應(yīng)用程序管理。它的眾多特性之一是支持通過(guò)其主要的二進(jìn)制客戶端 kubectl 運(yùn)行定制腳本或可執(zhí)行程序,kubectl 很強(qiáng)大的,允許用戶在 Kubernetes 集群上用它直接做很多事情。
使用別名進(jìn)行 Kubernetes 的故障排查
使用 Kubernetes 進(jìn)行容器編排的人都知道由于設(shè)計(jì)上原因帶來(lái)了其功能的復(fù)雜性。舉例說(shuō),迫切需要以更快的速度并且?guī)缀醪恍枰謩?dòng)干預(yù)的方式來(lái)簡(jiǎn)化 Kubernetes 中的故障排除(除過(guò)特殊情況)。
在故障排查功能方面,有很多場(chǎng)景需要考慮。在一種場(chǎng)景下,你知道你需要運(yùn)行什么,但是這個(gè)命令的語(yǔ)法(即使作為一個(gè)單獨(dú)的命令運(yùn)行)過(guò)于復(fù)雜,或需要一、兩次交互才能起作用。
例如,如果你需要經(jīng)常進(jìn)入一個(gè)系統(tǒng)命名空間中運(yùn)行的容器,你可能發(fā)現(xiàn)自己在重復(fù)地鍵入:
kubectl --namespace=kube-system exec -i -t <your-pod-name>
為了簡(jiǎn)化故障排查,你可以用這些指令的命令行別名。比如,你可以增加下面命令到你的隱藏配置文件(.bashrc
或 .zshrc
):
alias ksysex='kubectl --namespace=kube-system exec -i -t'
這是來(lái)自于 Kubernetes 常見(jiàn)別名存儲(chǔ)庫(kù)的一個(gè)例子,它展示了一種簡(jiǎn)化 kubectl
中的功能的方法。像這種場(chǎng)景下的簡(jiǎn)單情形,使用別名很有用。
切換到 kubectl 插件
更復(fù)雜的故障排查場(chǎng)景是需要一個(gè)一個(gè)的執(zhí)行很多命令,調(diào)查環(huán)境,最后得出結(jié)論。僅僅用別名方法是不能解決這種情況的;你需要知道你所部署的 Kubernetes 之間邏輯和相關(guān)性,你真正需要的是自動(dòng)化,以在更短的時(shí)間內(nèi)輸出你想要的。
考慮到你的集群有 10 ~ 20 或 50 ~ 100 個(gè)命名空間來(lái)提供不同的微服務(wù)。一般在進(jìn)行故障排查時(shí),什么對(duì)你有幫助?
- 你需要能夠快速分辨出拋出錯(cuò)誤的是哪個(gè) 命名空間的哪個(gè) Pod 的東西。
- 你需要一些可監(jiān)視一個(gè)命名空間的所有 Pod 日志的東西。
- 你可能也需要監(jiān)視特定命名空間的出現(xiàn)錯(cuò)誤的某個(gè) Pod 的日志。
涵蓋這些要點(diǎn)的解決方案對(duì)于定位生產(chǎn)環(huán)境的問(wèn)題有很大的幫助,以及在開(kāi)發(fā)和測(cè)試環(huán)節(jié)中也很有用。
你可以用 kubectl 插件創(chuàng)建比簡(jiǎn)單的別名更強(qiáng)大的功能。插件類(lèi)似于其它用任何語(yǔ)言編寫(xiě)的獨(dú)立腳本,但被設(shè)計(jì)為可以擴(kuò)充 Kubernetes 管理員的主要命令。
創(chuàng)建一個(gè)插件,你必須用 kubectl-<your-plugin-name>
的正確的語(yǔ)法來(lái)拷貝這個(gè)腳本到 $PATH
中的導(dǎo)出目錄之一,并需要為其賦予可執(zhí)行權(quán)限(chmod +x
)。
創(chuàng)建插件之后將其移動(dòng)到路徑中,你可以立即運(yùn)行它。例如,我的路徑下有一個(gè) 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
現(xiàn)在讓我們見(jiàn)識(shí)下帶有 tmux 的 Kubernetes 的有多強(qiáng)大。
駕馭強(qiáng)大的 tmux
Tmux 是一個(gè)非常強(qiáng)大的工具,許多管理員和運(yùn)維團(tuán)隊(duì)都依賴它來(lái)解決與易操作性相關(guān)的問(wèn)題:通過(guò)將窗口分成多個(gè)窗格以便在多臺(tái)計(jì)算機(jī)上運(yùn)行并行的調(diào)試來(lái)監(jiān)視日志。它的主要的優(yōu)點(diǎn)是可在命令行或自動(dòng)化腳本中使用。
我創(chuàng)建一個(gè) kubectl 插件,使用 tmux 使故障排查更加簡(jiǎn)單。我將通過(guò)注釋來(lái)解析插件背后的邏輯(插件的完整代碼留待給你實(shí)現(xiàn)):
# NAMESPACE 是要監(jiān)控的名字空間
# POD 是 Pod 名稱
# Containers 是容器名稱
# 初始化一個(gè)計(jì)數(shù)器 n 以計(jì)算循環(huán)計(jì)數(shù)的數(shù)量,
# 之后 tmux 使用它來(lái)拆分窗格。
n=0;
# 在 Pod 和容器列表上開(kāi)始循環(huán)
while IFS=' ' read -r POD CONTAINERS
do
# tmux 為每個(gè) Pod 創(chuàng)建一個(gè)新窗口
tmux neww $COMMAND -n $POD 2>/dev/null
# 對(duì)運(yùn)行中的 Pod 中 的所有容器啟動(dòng)循環(huán)
for CONTAINER in ${CONTAINERS//,/ }
do
if [ x$POD = x -o x$CONTAINER = x ]; then
# 如果任何值為 null,則退出。
warn "Looks like there is a problem getting pods data."
break
fi
# 設(shè)置要執(zhí)行的命令
COMMAND=”kubectl logs -f $POD -c $CONTAINER -n $NAMESPACE”
# 檢查 tmux 會(huì)話
if tmux has-session -t <會(huì)話名> 2>/dev/null;
then
<設(shè)置會(huì)話退出>
else
<創(chuàng)建會(huì)話>
fi
# 在當(dāng)前窗口為每個(gè)容器切分窗格
tmux selectp -t $n \; \
splitw $COMMAND \; \
select-layout tiled \;
# 終止容器循環(huán)
done
# 用 Pod 名稱重命名窗口以識(shí)別
tmux renamew $POD 2>/dev/null
# 增加計(jì)數(shù)器
((n+=1))
# 終止 Pod 循環(huán)
done<<(<從 kubernetes 集群獲取 Pod 和容器的列表>)
# 最后選擇窗口并附加會(huì)話
tmux selectw -t <會(huì)話名>:1 \; \
attach-session -t <會(huì)話名>\;
運(yùn)行插件腳本后,將產(chǎn)生類(lèi)似于下圖的輸出。每個(gè) Pod 有一個(gè)自己的窗口,每個(gè)容器(如果有多個(gè))被分割到其窗口中 Pod 窗格中,并在日志到達(dá)時(shí)輸出。Tmux 之美如下可見(jiàn);通過(guò)正確的配置,你甚至?xí)吹侥膫€(gè)窗口正處于激活運(yùn)行狀態(tài)(可看到標(biāo)簽是白色的)。
總結(jié)
別名是在 Kubernetes 環(huán)境下常見(jiàn)的也有用的簡(jiǎn)易故障排查方法。當(dāng)環(huán)境變得復(fù)雜,用高級(jí)腳本生成的kubectl 插件是一個(gè)更強(qiáng)大的方法。至于用哪個(gè)編程語(yǔ)言來(lái)編寫(xiě) kubectl 插件是沒(méi)有限制。唯一的要求是該名字在路徑中是可執(zhí)行的,并且不能與已知的 kubectl 命令重復(fù)。