一些快捷方式让 kubectl 更好用
本文为同一作者原博客的中文翻译。
分享一些使用 kubectl
时的命令行小工具、技巧。
oh-my-zsh 的 kubectl 插件:
如果你使用 Zsh 和 oh-my-zsh, 这个插件 将会非常有帮助.
在 rc 文件 ~/.zshrc
的这一行 plugins=
处加上 kubectl
即可使用。即使你不用 Zsh,也许也可以找到你的 shell 的对应插件,或者直接把这里的一些 alias 和 functions 定义 加入到你自己的 rc 文件中去。
该插件最有用的部分就是 alias k=kubectl
,只需要输入一个字母就可以使用 kubectl 命令。另一个比较有用的是 kca
,它会把后面的命令应用到 all-namespaces
。
% kca get svc
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
analytics pod0 ClusterIP 172.20.xxx.xx <none> 80/TCP 262d
analytics pod1 ClusterIP 172.20.xxx.xx <none> 80/TCP 4y190d
cache pod2 ClusterIP 172.20.xxx.xx <none> 6379/TCP 2y333d
cache pod3 ClusterIP None <none> 6379/TCP,16379/TCP 2y333d
如果你本地安装了一些格式着色工具,比如 jq, fx, yh , 就可以使用快捷命令 kj
, ky
来执行原本的 kuebctl 命令,输出内容会自动变成对应格式并用相应的工具高亮。
这个 oh-my-zsh 插件提供了大量 kubectl 命令(和子命令)的快捷方式。如果你是位全职运维工程师并且每天要使用大量不同的 kubectl 命令,这个插件提供的快捷方式将非常有用。但对我来说,我只会选取一个比较有限的集合只包括我非常高频使用并且可以灵活扩展的快捷方式。
精选 aliases:
我个人不喜欢诸如 kgp=kubectl get pods
这样的别名,太具体从而失去了灵活性。导致我要记大量不同别名。这是我自己使用的几个别名:
-
kg="k get"
-
kd="k describe"
-
kgy="k get -o yaml"
-
kgw="k get -o wide"
我倾向于把别名设置到 kubectl 命令(
get
和describe
)这一级别,这样我可以只打两个字母就能用,还能跟剩余部分做各种结合。使用
kg
来获取某个类型的资源;使用kgw
来展示更丰富的信息;使用kgy
或kd
来获得某个资源的细节。% kgw -n kube-system pod NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINE SS GATES aws-node-xxx 1/1 Running 0 33d 10.0.xx.xx ip-10-0-xx-xx.ec2.internal <none> <none> aws-node-ooo 1/1 Running 0 2d7h 10.0.xx.xx ip-10-0-xx-xx.ec2.internal <none> <none> aws-node-yyy 1/1 Running 0 33d 10.0.xx.xx ip-10-0-xx-xx.ec2.internal <none> <none> % kgy -n glow pod/my-pod-aaaaaaa-66666 apiVersion: v1 kind: Pod metadata: annotations: cliRestartAt: "1565324980" cluster-autoscaler.kubernetes.io/safe-to-evict: "true" fluentbit.io/exclude: "true" kubectl.kubernetes.io/restartedAt: "2023-10-10T21:51:25+08:00" kubernetes.io/psp: eks.privileged creationTimestamp: "2023-11-11T02:35:30Z" generateName: zoe-www-aaaaaaa- labels: app.kubernetes.io/instance: my-pod app.kubernetes.io/name: my-pod ... ...
-
kt="k taint node"
在做 k8s 集群升级的过程当中我要经常使用taint
,所以加入这个别名。 -
ktop="k top"
也经常使用k top
来查看节点或 pods 的资源使用情况。 -
kl="k logs"
这个别名是上文中 oh-my-zsh 插件提供的,同时还提供了其他几个相关的别名,也挺有用的,比如klf
(k logs -f),kl1m
(k logs --since 1m)。
根据(部分) pod 名字来查找:
function kfindpod {
name=$1
shift
kg --all-namespaces pod $@ | grep $name
}
偶尔会发生忘了名字空间但隐约记得 pod 名字的情况,我用这个方法把带某些关键词的 pod 都列出来。有一次我就是忘了 ingress
这个名字空间,就只能用这个方法把 aws load balancer controller 所在的 pod 和名字空间给找到:
aws:(prod-eks) k8s:(prod-eks) % kfindpod lb
ingress aws-lb-controller-xxx-yyy 1/1 Running 0 34d
ingress aws-lb-controller-xxx-yyy 1/1 Running 0 34d
给节点添加 No-Schedule 污点:
function ktnos {
for n in $*
do
k taint node $n eks-node-rolling:NoSchedule
done
}
function ktnos- {
for n in $*
do
k taint node $n eks-node-rolling:NoSchedule-
done
}
在升级 k8s 集群的工作中,我需要经常给多个节点添加和去除污点,所以我写了这两个方法。如果读者自己使用的话,要根据你的 k8s 集群作相应调整,比如污点的键值对名称。
列出 pods 和它们所在的节点:
function kpodnode {
ns=$1
shift
if [[ $ns =~ "allns" || $ns =~ "all" ]]; then
kg --all-namespaces pod -o=custom-columns=NAME:.metadata.name,NODE:.spec.nodeName,NS:.metadata.namespace,STATUS:.status.phase $@
else
kg -n $ns pod -o=custom-columns=NAME:.metadata.name,NODE:.spec.nodeName,STATUS:.status.phase $@
fi
}
alias knodepod="kpodnode"
这个方法会选出某个名字空间下(或所有)的 pod,并显示对应的节点的名字。在升级工作节点使经常会用到。我最常把这两个方法搭配 -w
选项使用(可以持续监控 pod 的转移情况):
aws:(prod-eks) k8s:(prod-eks) % kpodnode analytics -w
NAME NODE STATUS
metabase2023-xxxx ip-10-0-xx-oo.ec2.internal Running
superset-yyy ip-10-0-xx-oo.ec2.internal Running
Node group 相关:
如果你使用 node group(节点组) 标签来组织 k8s 集群中的节点,你可能经常需要列出节点的 node group 信息,或要找到某个 node group 标签下的节点:
function kgnode {
kubectl get node -o=custom-columns=NAME:.metadata.name,NODEGROUP:.metadata.labels.node-group,VERSION:.status.nodeInfo.kubeletVersion $@
}
function knodegroup {
kubectl get node -l node-group=$@
}
⚠️注意:这个具体的标签名(node-group
)可能不同,根据实际情况改写这些方法。
让 sops
更好用:
如果你使用 sops 来加解密 helm 变量,让相关指令变短是很有必要的。此外,我自己有两个 k8s 环境(对应两个 kube config)所以每次要根据环境指定不同的 kms 和加密变量文件挺麻烦的。所以我用下面这两个方法来“偷懒”:
function sopsd {
if [[ $KUBECONFIG =~ "prod-eks$" ]]; then
sops -d -i helm_vars/prod/secrets.yaml
elif [[ $KUBECONFIG =~ "sandbox-eks$" ]]; then
sops -d -i helm_vars/sandbox/secrets.yaml
fi
}
function sopse {
if [[ $KUBECONFIG =~ "prod-eks$" ]]; then
sops -e -k arn:aws:kms:us-east-1:xxxx:key/ooo -i helm_vars/prod/secrets.yaml
elif [[ $KUBECONFIG =~ "sandbox-eks$" ]]; then
sops -e -k arn:aws:kms:us-east-1:yyyy:key/iii -i helm_vars/sandbox/secrets.yaml
fi
}
读者如果要在自己的场景里使用,记得也要有指明 k8s 环境的环境变量(如果没有多个 k8s 环境可以直接去掉 if..elif
分支判断)。同时 sops -e -k
里使用的秘钥(这里是一个 aws arn)和加密变量文件的路径也各不相同,请根据实际情况更改定制。