由于 kubie
是开一个子 shell 它会导致 direnv
失效,也就是说 kubie
和 direnv
无法共同使用,我只好再去尝试其他兼容的方案,毕竟如果换回 kubectx
就依然有维护 kubeconfig 的烦恼。这里找到一个新的工具 kubecm 可以帮助做 kubeconfig 的合并。
不过其实它也包含了 kubectx 的功能,但我的 kubectx 还提供了自动补全等东西,就这么一直用着了。
如果需要维护很多 kubernetes 集群,每个集群都有一个 kubeconfig 的 yaml 那么在 ~/.kube
目录下就会有一大堆的 yaml 。在频繁切换和修改不同的集群的内容的时候,一个不小心就可能把 A 集群的东西部署到 B 集群造成运维事故。这里介绍下到目前为止维护对多个集群环境的一些痛点和实践。
首先先总结下痛点吧:
下面记录下自己在试图解决这些痛点过程中找到的还不错的方案。
kubectx
可以切换 ~/.kube/config
文件中的多个 context
,然后可以通过 kubens
命令切换不同的 namespace
。但如果我有一堆 kubeconfig yaml 的话还需要额外的一步,将它们合并到 ~/.kube/config
文件里。这个步骤用 kubectl 就能搞定:
KUBECONFIG=~/.kube/config:~/.kube/other.yaml kubectl config view \
--merge --flatten > out.txt
不过依然是多了一步,而且既然有添加就有删除,如果其中一个集群的配置文件变化了或者废弃了就需要把这个集群剃掉:
kubectl config unset users.gke_project_zone_name
kubectl config unset contexts.aws_cluster1-kubernetes
kubectl config unset clusters.foobar-baz
既然 kubectl config current-context
可以获取当前的上下文,那么如果可以在 shell 里面展示这些信息基本就可以保证自己知道当前在什么上下文了。对不同的 shell 可以用不同的方式实现类似的效果。
安装成功后按照项目 README 提示就可以了。
很遗憾 fish 里不能用 kube-ps1
不过找一个 shell 函数做的类似的效果也可以的:
function kubectl_status
[ -z "$KUBECTL_PROMPT_ICON" ]; and set -l KUBECTL_PROMPT_ICON "⎈"
[ -z "$KUBECTL_PROMPT_SEPARATOR" ]; and set -l KUBECTL_PROMPT_SEPARATOR "/"
set -l config $KUBECONFIG
[ -z "$config" ]; and set -l config "$HOME/.kube/config"
if [ ! -f $config ]
echo (set_color red)$KUBECTL_PROMPT_ICON" "(set_color white)"no config"
return
end
set -l ctx (kubectl config current-context 2>/dev/null)
if [ $status -ne 0 ]
echo (set_color red)$KUBECTL_PROMPT_ICON" "(set_color white)"no context"
return
end
set -l ns (kubectl config view -o "jsonpath={.contexts[?(@.name==\"$ctx\")].context.namespace}")
[ -z $ns ]; and set -l ns 'default'
echo (set_color cyan)$KUBECTL_PROMPT_ICON" "(set_color white)"($ctx$KUBECTL_PROMPT_SEPARATOR$ns)"
end
function fish_right_prompt
string unescape $$_tide_prompt_var[1][1]
echo (kubectl_status)
end
这个代码不是我原创的,我只是做了魔改,很遗憾忘记了出处...具体的代码在 fish_prompt 里,这里同时包含了我公开的 dotfiles 信息。效果如下:
注意 这个最终效果是建立在我的 fish 主题之上的,单独使用效果如何不得而知。
除了 kubectx 外我在最近装机的时候还发现了一个更完善的解决方案:kubie。它有三个优势:
~/.kube/*.yaml
这样的通配符匹配kube-ps1
的功能当然,也有坏处:
~/.kube/config
下当前的上下文认为是默认的上下文,它的 prompt 不会在你新建一个 terminal 的时候假设是没有上下文的,然而事实上在这个时候 kubectl 的 context 已经指向了 ~/.kube/config
的上下文了。你需要做一次切换后才会弹出。最后一个痛点以上的东西都没有解决。虽然增加了提示很大概率可以避免用错环境了,但还是挡不住有手比眼快的时候。这时候就需要 direnv
救场了。它可以在切换到某一个目录的之后触发一个 shell 执行,比如我可以强制在切换到维护 dev 集群的目录时将 KUBECONFIG
环境变量切换成对应集群的 kubeconfig 文件,这样就可以保证了上下文随着我操纵的 kustomize / helm charts 文件目录自动切换了。
最后上 demo,这里包含了上述介绍的一些演示,顺序通过内部的标题组织的,和上述顺序不一致。