如何优雅地使用 kubectl 访问多集群多 namespace ☕️—— kubectl-cf, kubectx 和 kubens
29 May 21 13:35 +0000

在 kubectl 的使用过程中我们经常需要在不同上下文之间切换,从而连接不同的集群,或者访问不同的 namespace,或者使用不同的用户身份。这种切换可以有很多种不同的方式实现,官方提供的途径包括使用 --kubeconfig 参数指定不同的 kubeconfig 文件,以及使用 kubectl config 子命令切换上下文 (context),但这两种方式使用起来都不够方便,今天我给大家介绍 3 个 kubectl 插件:kubectl-cfkubectx + kubens,实现优雅地切换 kubectl 上下文。☕️

kubectl 上下文

在开始介绍 kubectl-cf, kubectx 和 kubens 前,先介绍一下 kubectl 上下文的概念,以免有读者还不了解 kubectl 上下文包含的内容。

稍微了解过 kubectl 命令的人都会知道,kubectl 配置来自 kubeconfig 文件。默认的 kubeconfig 文件位于 ${HOME}/.kube/config。其中包含了 kubectl 的所有上下文信息,比如:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: {truncated}
    server: https://api-server.wbsnail.com:6443
  name: kubernetes
contexts:
- context:
    cluster: my-cluster
    namespace: default
    user: admin
  name: admin@my-cluster
current-context: admin@my-cluster
kind: Config
users:
- name: admin
  user:
    client-certificate-data: {truncated}
    client-key-data: {truncated}

可以看到一个 context 中包含了 cluster, namespaceuser 3 个信息。同时通过 current-context 确定了当前使用的上下文("admin@my-cluster")。

从上面的配置可以发现,一个 kubeconfig 文件中可能包含多个 clusters, namespaces 和 users,格式如:

apiVersion: v1
kind: Config
preferences: {}

clusters:
- cluster:
  name: development
- cluster:
  name: scratch

users:
- name: developer
- name: experimenter

contexts:
- context:
  name: dev-frontend
- context:
  name: dev-storage
- context:
  name: exp-scratch

current-context: dev-frontend

在使用 kubectl 时就需要使用某种方式在多个上下文间切换。

如果没有 kubeconfig 文件,kubectl 也可以使用一系列参数连接到集群,包括 --server, --certificate-authority, --client-certificate, --client-key, --namespace 等,一般情况下不会这样操作。

切换上下文

直接指定相关参数

直接指定相关参数准确来说没有切换上下文,只是对当前命令指定特定的上下文参数,比如最常用的 --namespace 参数,以及 --cluster 参数和 --user 参数,或者直接指定 --context 参数。

使用 --kubeconfig 参数

可以使用 kubectl 的 --kubeconfig 参数指定 kubeconfig 文件实现上下文切换,实际上换掉了整套配置:

kubectl --kubeconfig=${HOME}/.kube/local.kubeconfig get pods

用这种方式切换 kubectl 上下文难度较低,但命令比较繁琐。

使用 kubectl config 子命令

kubectl config 子命令提供了一系列命令用于查看和修改当前的配置,包括上下文切换:

Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"

 The loading order follows these rules:

  1.  If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes
place.
  2.  If $KUBECONFIG environment variable is set, then it is used as a list of paths (normal path delimiting rules for
your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When
a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the
last file in the list.
  3.  Otherwise, ${HOME}/.kube/config is used and no merging takes place.

Available Commands:
  current-context Displays the current-context
  delete-cluster  Delete the specified cluster from the kubeconfig
  delete-context  Delete the specified context from the kubeconfig
  get-clusters    Display clusters defined in the kubeconfig
  get-contexts    Describe one or many contexts
  rename-context  Renames a context from the kubeconfig file.
  set             Sets an individual value in a kubeconfig file
  set-cluster     Sets a cluster entry in kubeconfig
  set-context     Sets a context entry in kubeconfig
  set-credentials Sets a user entry in kubeconfig
  unset           Unsets an individual value in a kubeconfig file
  use-context     Sets the current-context in a kubeconfig file
  view            Display merged kubeconfig settings or a specified kubeconfig file

Usage:
  kubectl config SUBCOMMAND [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

切换上下文的方式:

kubectl config use-context admin@my-cluster

用这种方式切换 kubectl 上下文难度较低,但命令同样比较繁琐。

使用别名 (alias)

上面两个方法的操作难度都很低,唯一的问题在于命令过于繁琐,第一个想到的解决办法就是设置别名,比如我曾经这样设置:

alias k='kubectl'
alias kp='kubectl --kubeconfig=${HOME}/.kube/production.kubeconfig'
alias kl='kubectl --kubeconfig=${HOME}/.kube/local.kubeconfig'

这样可以使用 kp 操作生产集群,kl 操作本地集群。

或者说:

alias k='kubectl'
alias kp='kubectl config use-context admin@production-cluster'
alias kd='kubectl config use-context admin@local-clusetr'

这样也可以使用 kpkl 切换集群。

这种方式一不够原生,二不够灵活,有没有更好的方法呢?下面我给大家介绍 3 个 kubectl 插件:kubectl-cf, kubectx 和 kubens。

有关 kubectl 插件,请看官方文档:Extend kubectl with plugins | Kubernetes,简单来说,所有 kubectl- 开头的命令都是 kubectl 插件,很简单吧?

比如 kubectl-cf,既可以使用 kubectl-cf 调用,也可以使用 kubectl cf 调用。

使用 kubectl-cf

spongeprojects/kubectl-cf 是一个用于在多个 kubeconfig 文件间切换的工具,可以在 release 页面下载安装:Releases · spongeprojects/kubectl-cf · GitHub

kubectl-cf 有专门的中文版本 Fork:wbsnail/kubectl-cf

如上所述,作为 kubectl 插件,安装后 kubectl-cf 可以通过 kubectl-cfkubectl cf 两种方式调用,基本使用方式有以下 3 种:

kubectl-cf 使用说明:
  cf           选择 kubeconfig
  cf [config]  选择 kubeconfig (无交互)
  cf -         切换到前一个使用的 kubeconfig

kubectl-cf 要求 kubeconfig 文件以 "*.kubeconfig" 的后缀格式放在 ${HOME}/.kube 目录下,比如 "${HOME}/.kube/production.kubeconfig","${HOME}/.kube/local.kubeconfig"。

使用起来就像这样:

File

在使用无交互模式下选择 kubeconfig 时,kubectl-cf 很贴心地提供了前缀查找功能,比如使用 production.kubeconfig 文件,完整命令是 kubectl-cf production,可以缩写为 kubectl-cf p,类似于 Docker.

注意 kubectl-cf 是用来切换 kubeconfig 文件的,如果需要切换单个 kubeconfig(或者多个 kubeconfigs)当中的不同上下文时,就需要使用另一个 kubectl 插件:kubectx。

使用 kubectx

kubectx 是一个用于在多个上下文之间切换的工具,可以在 release 页面下载安装:Releases · ahmetb/kubectx · GitHub,也可以使用 Krew 安装:

kubectl krew install ctx

使用方式类似于 kubectl-cf,但没有提供交互式命令行:

kubectx admin@production
kubectl ctx admin@production

使用 kubens

还有很多时候我们只想在 namespace 间切换,比如接下来一些命令我都想在 dev namespace 下操作,又不想每个命令都加 "-n dev",可以使用 kubens 方便地切换当前上下文中的 namespace。

kubens 和 kubectx 在同一个仓库下,同样可以在 release 页面下载安装:Releases · ahmetb/kubectx · GitHub,也可以使用 Krew 安装:

kubectl krew install ns

使用方式和 kubectx 完全相同:

kubens dev
kubectl ns dev

一起使用

我在实际使用中是这样使用 kubectl 命令的:

# 设置别名
alias k='kubectl' # 放在 rc 文件中,比如 .bashrc, .zshrc

k get pods

# 切换 kubeconfig 文件,l 是 local 的前缀
k cf l

# 切换 kubeconfig 文件,p 是 production 前缀
k cf p

# 切换上下文(有了 kubectl-cf 我一般都不会用 kubectx,因为把不同集群配置放在不同文件中看起来更清晰)
k ctx admin@my-cluster

# 切换 namespace
k ns dev

# 切换 namespace
k ns default

忘记 kubectl --kubeconfigkubectl config use-context 吧,因为这两个命令实在太长了。。。

这样就实现了对 kubectl 上下文切换操作的最优雅化!你有什么更好的使用建议吗?欢迎通过各种方式告诉我 💌

参考资料

Configure Access to Multiple Clusters | Kubernetes

Extend kubectl with plugins | Kubernetes

Krew - kubectl plugin manager

Who Lives in a Pineapple Under the Sea? · GitHub

GitHub - spongeprojects/kubectl-cf: Faster way to switch between kubeconfig files.

GitHub - wbsnail/kubectl-cf: 更方便地在 kubeconfig 配置文件间切换。

GitHub - ahmetb/kubectx: Faster way to switch between clusters and namespaces in kubectl


Loading comments...