万字硬核干货!6大技巧,极速提升kubectl的生产力!

R

本周四晚8:30,k3s实战课程开启!将由Rancher研发总监带你畅游k3s与边缘AI的奇妙世界。课程内容完全由实际使用场景中总结而来,别错过啦~!点击【阅读原文】或访问以下链接即可传送到课程现场:
http://z-mz.cn/PmxF

如果你正在使用Kubernetes,那么kubectl一定是你最常使用的工具。无论你需要学习任何工具,都应该先提前了解kubectl并有效地使用它。本文包含了一系列技巧,可以让你更高效而且有效地使用kubectl。同时,可以加深你对Kubernetes各个方面工作方式的理解。
本文的目标不仅是使你使用Kubernetes的日常工作更高效,而且更愉快!


目  录

  • 什么是kubectl?
  • 使用命令补全功能保存输入
  • 迅速查找资源规范
  • 使用自定义列输出格式
  • 轻松在集群和命名空间之间切换
  • 使用自动生成别名(Aliases)保存输入
  • 使用插件扩展kubectl


什么是kubectl

在学习如何更高效地使用kubectl之前,你应该对它是什么以及如何工作有个基本的了解。从用户的角度来说,kubectl是你控制Kubernetes的“驾驶舱”。它可以让你执行所有可能的Kubernetes操作。
从技术角度上看,kubectl是Kubernetes API的客户端。Kubernetes API是一个 HTTP REST API。这个API是真正的Kubernetes用户界面。Kubernetes完全受这个API控制,这意味着每个Kubernetes操作都作为API端点公开,并且可以由对此端点的HTTP请求执行。因此,kubectl的主要工作是执行对Kubernetes API的HTTP请求:

Kubernetes是一个完全以资源为中心的系统。这意味着,Kubernetes维护资源的内部状态并且所有的Kubernetes操作都是针对这些资源的CRUD(增加、读取、更新、删除)操作。你完全可以通过操控这些资源(Kubernetes会根据资源的当前状态找出解决方案)来控制Kubernetes。因此,Kubernetes API reference主要是资源类型及其相关操作的列表。
来,我们来看一个例子。
假设你想要创建一个ReplicaSet资源。为了达成此目标,你在一个名为replicaset.yaml的文件中定义ReplicaSet,然后运行以下命令:

kubectl create -f replicaset.yaml

显然,在Kubernetes已经创建了你的ReplicaSet。但之后会发生什么呢?
Kubernetes有一个创建ReplicaSet的操作,并且它和其他所有Kubernetes操作一样,都会作为API端点暴露。对于这个操作而言,该特定API端点如下:

POST /apis/apps/v1/namespaces/{namespace}/replicasets

你可以在API reference中找到所有Kubernetes操作对应的API端点,包括以上端点( https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13
)。要向端点发出实际请求,你需要一开始就在API reference中列出的端点路径中添加API server的URL。
因此,当你执行上述命令时,kubectl将向上述API端点发出HTTP POST请求。ReplicaSet定义(你在replicaset.yaml文件中所提供的)在请求的正文中传递。
这就是kubectl对于与Kubernetes集群交互的所有命令的工作方式。在这些情况下,kubectl只需向适当的Kubernetes API端点发出HTTP请求即可。
请注意,通过手动向Kubernetes API发出HTTP请求,完全有可能使用curl之类的工具来控制Kubernetes。Kubectl只是让你更轻松地使用Kubernetes API。
以上就是什么是kubectl及其工作原理的简单介绍。但是,每个kubectl用户都应该了解更多有关Kubernetes API的信息。为此,我们先简要地介绍一下Kubernetes的内部结构。

Kubernetes 内部

Kubernetes由一系列独立组件构成,这些组件会在集群的节点上作为单独的进程运行。一些组件运行在master节点,一些组件运行在worker节点,每个组件都有其特定功能。
在master节点上,有以下重要组件:

  • 存储后端:存储资源定义(通常使用etcd)
  • API Server:提供Kubernetes API并管理存储后端
  • Controller manager:确保资源状态与规范相匹配
  • Scheduler:将Pod调度到worker节点

在worker节点上最重要的组件为:

  • Kubelet:在worker节点上管理容器的执行

为了充分了解这些组件是如何一起工作的,让我们来看一个例子。

假设你刚刚执行了 kubectl create -f replicaset.yaml
,此后,kubectl向 create ReplicaSet  API端点
发出了HTTP POST请求(传递你的ReplicaSet资源定义)。哪些因素会导致集群中出现这种情况?如下:

执行 kubectl create -f replicaset.yaml
之后,API server将会在存储后端保存你的ReplicaSet资源定义。


这将触发controller manager中的ReplicaSet controller,后者监视ReplicaSet资源的创建,更新和删除。


ReplicaSet controller为每个ReplicaSet副本创建了一个Pod定义(根据在ReplicaSet定义中的Pod模板创建)并将它们保存到存储后端。


这触发了scheduler,它监视尚未被分配给worker节点的Pod。

Scheduler为每个Pod选择一个合适的worker节点,并在存储后端中添加该信息到Pod定义中。
请注意,到目前为止,集群中任何地方都没有运行工作负载的代码。至今,我们所完成的事就是在master节点上的存储后端中创建和更新资源。


这触发了在Pod所调度到的worker节点上的kubelet,它监视调度到其worker节点上的pod。

Kubelet从存储后端读取Pod定义并指示容器运行时(比如,Docker)来运行在worker节点上的容器。
此时,你的ReplicaSet应用程序就正在运行啦!
Kubernetes API的角色

从上述例子可知,Kubernetes组件(除了API server和存储后端)通过在存储后端监视资源更改和操控资源工作。然而,这些组件无法直接访问存储后端,仅能通过Kubernetes API进行访问。
看一下以下示例:

  • ReplicaSet controller使用带有watch参数 的list ReplicaSets API 端点
    API操作来监视ReplicaSet资源的更改。

  • ReplicaSet controller使用 create Pod API 端点
    来创建Pod

  • Scheduler使用 patch Pod API端点
    以及有关选定的worker节点信息来更新Pod。

正如你所见,这与kubectl所使用的API相同。
Kubernetes API对于内部组件和外部用户的重复操作是Kubernetes的基本设计概念。现在,我们来总结一下Kubernetes如何工作的:

  1. 存储后端存储(如,资源)Kubernetes的状态
  2. API server以Kubernetes API的形式提供到存储后端的接口
  3. 所有其他Kubernetes的组件和用户通过Kubernetes API读取、监视以及操控Kubernetes的状态(如资源)。

熟悉这些概念将在很大程度上帮助你更好地理解kubectl并利用它。
接下来,我们来看一下具体的技巧,来帮助你提升kubectl的生产力。


1、 使用命令补全功能保存输入

命令补全是提高kubectl生产率的最有用但经常被忽略的技巧之一。
命令补全功能使你可以使用Tab键自动完成kubectl命令的各个部分。这适用于子命令、选项和参数,包括诸如资源名称之类难以键入的内容。
在这里,你可以看到kubectl命令的完成情况:

命令补全可用于Bash和Zsh Shell。

官方文档中包含有关设置命令完成的详细说明( https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion
),但是以下部分会简要向您介绍如何设置。
命令补全功能工作方式

总体而言,命令补全是通过补全脚本而起作用的Shell功能。补全脚本是一个shell脚本,它为特定命令定义了补全行为。通过输入补全脚本可以补全相应的命令。Kubectl可以使用以下命令为Bash和Zsh自动生成并print out补全脚本:

kubectl completion bash

# or

kubectl completion zsh

理论上,在合适的shell(Bash或Zsh)中提供此命令的输出将会启用kubectl的命令补全功能。然而,实际上,在Bash和Zsh之间存在一些细微的差别(包括在Linux和macOS之间也存在差别)。以下部分将对此进行详细解释。

Bash on Linux

Bash的补全脚本主要依赖bash-completion项目( https://github.com/scop/bash-completion
),所以你需要先安装它。
你可以使用不同的软件包管理器安装bash-completion。如:

sudo apt-get install bash-completion

# or

yum install bash-completion

你可以使用以下命令测试bash-completion是否正确安装:

type _init_completion

如果输出的是shell功能的代码,那么bash-completion就已经正确安装了。如果命令输出的是 not found
错误,你必须添加以下命令行到你的 ~/.bashrc
文件:

source /usr/share/bash-completion/bash_completion

你是否需要添加这一行到你的 ~/.bashrc
文件中,取决于你用于安装bash-completion的软件包管理器。对于APT来说,这是必要的,对于yum则不是。

bash-completion安装完成之后,你需要进行一些设置,以便在所有的shell会话中获得kubectl补全脚本。一种方法是将以下命令行添加到 ~/.bashrc
文件中:

source <(kubectl completion bash)

另一种可能性是将kubectl补充脚本添加到 /etc/bash_completion.d
目录中(如果不存在,则需要先创建它):

kubectl completion bash >/etc/bash_completion.d/kubectl

/etc/bash_completion.d
目录中的所有补全脚本均由bash-completion自动提供。
以上两种方法都是一样的效果。重新加载shell后,kubectl命令补全就能正常工作啦!
Bash on macOS
使用macOS时,会有些复杂。原因是截至成文时macOS上Bash的默认版本是3.2,这已经过时了。不幸的是,kubectl补全脚本至少需要Bash 4.1,因此不适用于Bash 3.2。
苹果依旧在macOS上默认使用过时的Bash版本是因为更新版本的Bash使用的是GPLv3 license,而苹果不支持这一license。
这意味着,要在macOS上使用kubectl命令补全功能,你必须安装较新版本的Bash。你甚至可以将其设置为新的默认shell,这将在将来为你省去很多此类麻烦。这实际上并不难,你可以在我之前写的文章中找到说明:
https://itnext.io/upgrading-bash-on-macos-7138bd1066ba

在继续剩下的步骤之前,确保你现在已经在使用Bash 4.1或更高的版本(使用 bash –version
查看版本)。

同上一部分一样,Bash的补全脚本主要依赖bash-completion项目( https://github.com/scop/bash-completion
),所以你需要先安装它。
你可以使用Homebrew安装bash-completion:

brew install bash-completion@2

@2
代表bash-completion v2。Kubectl补全脚本要求bash-completion v2,而bash-completion v2要求至少是Bash 4.1。这就是你不能在低于4.1的Bash版本上使用kubectl补全脚本的原因。

brew intall
命令的输出包括一个“Caveats”部分,其中的说明将以下行添加 ~/.bash_profile
文件:

export BASH_COMPLETION_COMPAT_DIR=/usr/local/etc/bash_completion.d

[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"

你必须执行此操作才能完成bash-completion的安装。但是,我建议将这些行添加到 ~/.bashrc
而不是 ~/.bash_profile
文件中。这可以确保bash-completion在子shell中也可用。
重新加载shell之后,你可以使用以下命令测试bash-completion是否正确安装:

type _init_completion

如果输出为shell功能的代码,意味着一切都设置完成。现在,你需要进行一些设置,以便在所有的shell会话中获得kubectl补全脚本。一种方法是将以下命令行添加到 ~/.bashrc
文件中:

source <(kubectl completion bash)

另一种方法是将kubectl补全脚本添加到 /usr/local/etc/bash_completion.d
目录中:

kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl

仅当你使用Homebrew安装了bash-completion时,此方法才有效。在这种情况下,bash-completion会在此目录中提供所有补全脚本。

如果你还用Homebrew安装了kubectl,则甚至不必执行上述步骤,因为补全脚本应该已经由kubectl Homebrew公式放置在 /usr/local/etc/bash_completion.d
目录中。在这种情况下,kubectl补全应该在安装bash-completion后自动开始工作。所有这些方法都是等效的。
重新加载shell后,kubectl完成就能正常工作!

Zsh

Zsh的补全脚本没有任何依赖项。所以,你所需要做的是去进行一些设置,以便它能在所有的shell会话中被获取到。

你可以通过添加以下命令行到你的 ~/.zshrc
文件中来实现这一效果:

source <(kubectl completion zsh)

如果在重新加载你的shell之后,你获得了 command not found: compdef
错误,你需要启动内置的 compdef
,你可以在将以下行添加到开始的 ~/.zshrc
文件中:

autoload -Uz compinit

compinit


2、迅速查看资源规范

当你创建YAML资源定义时,你需要知道字段以及这些资源的意义。API reference中提供了一个查找此类信息的位置,其中包含所有资源的完整规范:
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/

然而,每次你需要查找某些内容时都要切换到Web浏览器,这十分繁琐。因此,kubectl提供了 kubectl explain
命令,它能在你的terminal中正确地输入所有资源规范。

kubectl explain
的用法如下:

kubectl explain resource[.field]...

该命令输出所请求资源或字段的规范。 kubectl explain
所显示的信息与API reference中的信息相同。默认情况下, kubectl explain
仅显示单个级别的字段。你可以使用 –recursive
标志来显示所有级别的字段:

kubectl explain deployment.spec --recursive

如果你不确定哪个资源名称可以用于 kubectl explain
,你可以使用以下命令查看:

kubectl api-resources

该命令以复数形式显示资源名称(如 deployments
)。它同时显示资源名称的缩写(如 deploy
)。无需担心这些差别,所有名称变体对于kubectl都是等效的。也就是说,你可以使用它们中的任何一个。
例如,以下命令效果都是一样的:

kubectl explain deployments.spec

# or

kubectl explain deployment.spec

# or

kubectl explain deploy.spec


3、 使用自定义列输出格式

kubectl get
命令默认的输出方式如下(该命令用于读取资源):

kubectl get pods

NAME                      READY   STATUS    RESTARTS   AGE

engine-544b6b6467-22qr6   1/1     Running   0          78d

engine-544b6b6467-lw5t8   1/1     Running   0          78d

engine-544b6b6467-tvgmg   1/1     Running   0          78d

web-ui-6db964458-8pdw4    1/1     Running   0          78d

这是一种很好的可读格式,但是它仅包含有限的信息量。如你所见,每个资源仅显示了一些字段,而不是完整的资源定义。此时,自定义列输出格式应运而生,它使你可以自由定义列和想在其中显示的数据。你可以选择资源的任何字段,使其在输出中显示为单独的列。
自定义列输出选项的用法如下:

-o custom-columns=
:[,
:]...

你必须将每个输出列定义为


对:


  • 是列的名称,你可以选择任何所需的内容。

  • 是一个选择资源字段的表达式(下面将详细说明)。

让我们看一个简单的例子:

kubectl get pods -o custom-columns='NAME:metadata.name'

NAME

engine-544b6b6467-22qr6

engine-544b6b6467-lw5t8

engine-544b6b6467-tvgmg

web-ui-6db964458-8pdw4

在这里,输出包括显示所有Pod名称的一列。

选择Pod名称的表达式是 meta.name
。原因是Pod的名称是在Pod资源的元数据字段的name字段中定义的(你可以在API reference中或使用 kubectl explain pod.metadata.name
进行查找)。
现在,假设你想在输出中添加一个附加列,例如,显示每个Pod在其上运行的节点。为此,你只需在自定义列选项中添加适当的列规范即可:

kubectl get pods \

  -o custom-columns='NAME:metadata.name,NODE:spec.nodeName'

NAME                      NODE

engine-544b6b6467-22qr6   ip-10-0-80-67.ec2.internal

engine-544b6b6467-lw5t8   ip-10-0-36-80.ec2.internal

engine-544b6b6467-tvgmg   ip-10-0-118-34.ec2.internal

web-ui-6db964458-8pdw4    ip-10-0-118-34.ec2.internal

选择节点名称的表达式是 spec.nodeName
。这是因为已将Pod调度的节点保存在Pod的 spec.nodeName
字段中(请参阅 kubectl explain pod.spec.nodeName
)。
请注意,Kubernetes资源字段区分大小写。
你可以通过这种方式将资源的任何字段设置为输出列。只需浏览资源规范并尝试使用任何你喜欢的字段即可!
但是首先,让我们仔细看看这些字段选择表达式。

JSONPath 表达式

用于选择资源字段的表达式基于JSONPath:
https://goessner.net/articles/JsonPath/index.html
JSONPath是一种用于从JSON文档提取数据的语言(类似于XPath for XML)。选择单个字段只是JSONPath的最基本用法。它具有很多功能,例如list selector、filter等。

但是, kubectl explain
,仅支持JSONPath功能的子集。以下通过示例用法总结了这些得到支持的功能:

# Select all elements of a list

kubectl get pods -o custom-columns='DATA:spec.containers[*].image'


# Select a specific element of a list kubectl get pods -o custom-columns='DATA:spec.containers[0].image'
# Select those elements of a list that match a filter expression kubectl get pods -o custom-columns='DATA:spec.containers[?(@.image!="nginx")].image'
# Select all fields under a specific location, regardless of their name kubectl get pods -o custom-columns='DATA:metadata.*'
# Select all fields with a specific name, regardless of their location kubectl get pods -o custom-columns='DATA:..image'

特别重要的是 []
运算符。Kubernetes资源的许多字段都是列表,使用此运算符可以选择这些列表中的项目。它通常与通配符一起用作 [*]
,以选择列表中的所有项目。
在下面,你将找到一些使用此符号的示例。

示例应用程序

使用自定义列输出格式有无限可能,因为你可以在输出中显示资源的任何字段或字段组合。以下是一些示例应用程序,但你可以自己探索并找到对你有用的应用程序。
Tip:如果你经常使用这些命令,则可以为其创建一个shell别名。

显示Pod的容器镜像

kubectl get pods \

  -o custom-columns='NAME:metadata.name,IMAGES:spec.containers[*].image'

NAME                       IMAGES

engine-544b6b6467-22qr6    rabbitmq:3.7.8-management,nginx

engine-544b6b6467-lw5t8    rabbitmq:3.7.8-management,nginx

engine-544b6b6467-tvgmg    rabbitmq:3.7.8-management,nginx

web-ui-6db964458-8pdw4     wordpress

此命令显示每个Pod的所有容器镜像的名称。
请记住,一个Pod可能包含多个容器。在这种情况下,单个Pod的容器镜像在同一列中显示为由逗号分隔的列表。
显示节点的可用区

kubectl get nodes \

  -o custom-columns='NAME:metadata.name,ZONE:metadata.labels.failure-domain\.beta\.kubernetes\.io/zone'

NAME                          ZONE

ip-10-0-118-34.ec2.internal   us-east-1b

ip-10-0-36-80.ec2.internal    us-east-1a

ip-10-0-80-67.ec2.internal    us-east-1b

如果您的Kubernetes集群部署在公有云基础架构(例如AWS,Azure或GCP)上,则此命令很有用。它显示每个节点所在的可用区。
可用区是一个公有云的概念,表示一个地理区域内的复制点。

每个节点的可用区均通过特殊的 failure-domain.beta.kubernetes.io/zone
标签获得。如果集群在公有云基础架构上运行,则将自动创建此标签,并将其值设置为节点的可用性区域的名称。
标签不是Kubernetes资源规范的一部分,因此您无法在API reference中找到以上标签。但是,如果将节点输出为YAML或JSON,则可以看到它(以及所有其他标签):

kubectl get nodes -o yaml

# or

kubectl get nodes -o json

除了探索资源规范外,这通常是发现更多有关资源的信息的好方法。


4、轻松在集群和命名空间之间切换

当kubectl必须向Kubernetes API发出请求时,它将读取系统上的所谓kubeconfig文件,以获取它需要访问的所有连接参数并向API服务器发出请求。

默认的kubeconfig文件是 〜/ .kube / config
。该文件通常是通过某些命令自动创建或更新的(例如,如果使用托管的Kubernetes服务,则为 aws eks update-kubeconfig
gcloud container clusters get-credentials
)。
使用多个集群时,在kubeconfig文件中配置了多个集群的连接参数。这意味着,你需要一种方法来告诉kubectl要将其连接到哪些集群中。
在集群中,您可以设置多个命名空间(命名空间是物理集群中的一种“虚拟”集群)。Kubectl还可确定kubeconfig文件中用于请求的命名空间。因此,你需要一种方法来告诉kubectl你要使用哪个命名空间。

请注意,您还可以通过在KUBECONFIG环境变量中列出它们,以拥有多个kubeconfig文件。在这种情况下,所有这些文件将在执行时合并为一个有效的配置。你还可以为每个kubectl命令使用 –kubeconfig
选项覆盖默认的kubeconfig文件。具体请参阅官方文档:
https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
Kubeconfig文件
让我们看看kubeconfig文件实际包含什么:

如你所见,kubeconfig文件由一组上下文组成。上下文包含以下三个元素:

  • 集群:集群的API server的URL
  • 用户:集群中特定用户的身份验证凭据
  • 命名空间:连接到集群时要使用的命名空间

实际上,人们通常在其kubeconfig文件中为每个集群使用单个上下文。但是,每个集群也可以有多个上下文,它们的用户或命名空间不同。但这似乎不太常见,因此集群和上下文之间通常存在一对一的映射。
在任何给定时间中,这些上下文其中之一都可以被设置为当前上下文(通过kubeconfig文件中的专用字段):

当kubectl读取kubeconfig文件时,它总是使用当前上下文中的信息。因此,在上面的示例中,kubectl将连接到Hare集群。
因此,要切换到另一个集群时,你只需在kubeconfig文件中更改当前上下文即可:

在上面的示例中,kubectl现在将连接到Fox集群。
并切换到同一集群中的另一个命名空间,可以更改当前上下文的命名空间元素的值:

在上面的示例中,kubectl现在将在Fox集群中使用Prod命名空间(而不是之前设置的Test命名空间)。

请注意,kubectl还提供了 —cluster
-user
-namespace
–context
选项,无论kubeconfig文件中设置了什么,它们都可以覆盖单个元素和当前上下文本身。请参阅 kubectl options

从理论上讲,你可以通过手动编辑kubeconfig文件来进行这些更改。但是,这十分繁琐。以下各节介绍了各种工具,可让你自动进行这些更改。
Kubectx

Kubectx可以有效帮助集群和命名空间之间进行切换。该工具提供了 kubectx
kubens
命令,使你可以分别更改当前上下文和命名空间。
如前所述,如果每个集群只有一个上下文,则更改当前上下文意味着更改集群。
在这里,你可以看到这两个命令的作用:

如上一节所述,这些命令仅需在后台编辑kubeconfig文件即可。
要安装kubectx,只需按照GitHub页面上的说明进行操作即可:
https://github.com/ahmetb/kubectx/#installation
kubectx和kubens都通过补全脚本提供命令补全功能。这使你可以自动完成上下文名称和命名空间的输入。你也可以在GitHub页面上找到设置完成的说明:
https://github.com/ahmetb/kubectx/#installation
kubectx的另一个十分有用的功能是交互模式。这与fzf工具(它必须单独安装)一起工作(实际上,安装fzf会自动启用kubectx交互模式)。交互式模式允许你通过交互式模糊搜索界面(由fzf提供)选择目标上下文或命名空间。

fzf Github主页: https://github.com/junegunn/fzf

使用shell别名

实际上,你并不需要单独的工具来更改当前上下文和命名空间,因为kubectl也提供了执行此操作的命令。特别是,kubectl config命令提供了用于编辑kubeconfig文件的子命令。这里是其中的一些:

  • kubectl config get-contexts
    :列出所有上下文

  • kubectl config current-context
    :获取当前上下文

  • kubectl config use-context
    :更改当前上下文

  • kubectl config set-context
    :更改上下文的元素

但是,直接使用这些命令不是很方便,因为它们的键入时间很长。但是你可以做的是将它们包装到可以更容易执行的shell别名中。
我根据这些命令创建了一组别名,这些别名提供了与kubectx类似的功能。在这里,你可以看到它们的作用:

请注意,别名使用fzf提供的交互式模糊搜索界面(例如kubectx的交互式模式)。这意味着,你需要安装fzf才能使用这些别名。
以下是别名的定义:

# Get current context

alias krc='kubectl config current-context'

# List all contexts

alias klc='kubectl config get-contexts -o name | sed "s/^/  /;\|^  $(krc)$|s/ /*/"'

# Change current context

alias kcc='kubectl config use-context "$(klc | fzf -e | sed "s/^..//")"'


# Get current namespace alias krn='kubectl config get-contexts --no-headers "$(krc)" | awk "{print \$5}" | sed "s/^$/default/"' # List all namespaces alias kln='kubectl get -o name ns | sed "s|^.*/| |;\|^ $(krn)$|s/ /*/"' # Change current namespace alias kcn='kubectl config set-context --current --namespace "$(kln | fzf -e | sed "s/^..//")"'

要安装这些别名,只需将以上定义添加到 〜/ .bashrc
〜/ .zshrc
文件中,然后重新加载你的shell。

使用插件

Kubectl允许安装可以像原生命令一样调用的插件。例如,你可以安装名为 kubectl-foo
的插件,然后将其作为 kubectl foo
调用。kubectl插件将在本文后面的部分中详细介绍。

能够像这样更改当前上下文和命名空间不是很好吗?例如,运行 kubectl ctx
更改上下文,运行 kubectl ns
更改命名空间?
我创建了两个可以实现这一功能的插件:

  • kubectl-ctx:
    https://github.com/weibeld/kubectl-ctx
  • kubectl-ns:
    https://github.com/weibeld/kubectl-ns

在内部,插件建立在上一部分的别名基础上。
在这里,你可以看到正在使用的插件:

请注意,插件使用fzf提供的交互式模糊搜索界面。这意味着,您需要安装fzf才能使用这些插件。

要安装插件,只需将名为 kubectl-ctx
kubectl-ns
的shell脚本下载到PATH中的任何目录,并使它们可执行(例如,使用chmod + x)。之后,你应该立即可以使用kubectl ctx和kubectl ns。


5、 使用自动生成的别名保存输入

Shell别名通常是保存输入内容的好方法。kubectl-aliases项目则是这一想法的具体体现,并为常见的kubectl命令提供了约800个别名:
https://github.com/ahmetb/kubectl-aliases
你可能想知道如何记住800个别名?实际上,你不需要记住它们,因为它们都是根据简单的方案生成的,如下所示:

如你所见,别名由组件组成,每个组件代表kubectl命令的特定元素。每个别名可以具有一个用于基本命令、操作和资源的组件,以及一个用于选项的多个组件,你只需按照上述方案从左到右“填充”这些组件即可。
请注意,当前详细的方案位于GitHub页面上:
https://github.com/ahmetb/kubectl-aliases/blob/master/.kubectl_aliases
在这里您还可以找到别名的完整列表:
https://github.com/ahmetb/kubectl-aliases#syntax-explanation

例如,别名kgpooyamlall代表命令 kubectl get pods -o yaml –all-namespaces

  • k→ kubectl
  • g→ get
  • po→ pods
  • oyaml→ -o yaml
  • all→ –all-namespaces

请注意,大多数选项组件的相对顺序无关紧要。因此,kgpooyamlall等同于kgpoalloyaml。

你不需要使用所有组件作为别名。例如, k
kg
klo
ksys
kgpo
也是有效的别名。此外,你可以在命令行上将别名与其他单词组合在一起。

例如,你可以使用 k proxy
来运行 kubectl proxy
。或使用 kg roles
来运行 kubectl get roles
(当前不存在Roles资源的别名组件)。要获得特定的Pod,你可以使用 kgpo my-pod
来运行 kubectl get pod my-pod

请注意,某些别名甚至需要在命令行上进一步输入参数。例如, kgpol
别名代表 kubectl get pods -l
-l
选项需要一个参数(标签规范)。因此,你必须使用此别名,例如:

因此,你只能在别名末尾使用 a
f
l
组件。
总而言之,一旦掌握了该方案,就可以从要执行的命令中直观地推断出别名,并节省大量输入!

要安装kubectl-aliases,只需从GitHub下载 .kubectl-aliases
文件,然后将其从 〜/ .bashrc
〜/ .zshrc
文件中获取即可:

source ~/.kubectl_aliases

重新加载shell后,你应该可以使用所有800个kubectl别名!

补全功能

如你所见,你经常在命令行上将其他单词附加到别名上。例如:

kgpooyaml test-pod-d4b77b989

如果使用kubectl命令补全功能,则可能习惯于自动完成资源名称之类的事情。但是当你使用别名时仍然可以这样做吗?
这是一个重要的问题,因为如果补全功能无法正常工作,这些别名的某些好处将会被削弱。
那么,这一问题的答案取决于你所使用的shell。
对于Zsh,补全可以立即和别名一起使用。
对于Bash,默认情况下补全功能将不会正常工作。但是它可以通过一些额外的步骤来使其正常运行。
在Bash中同时启用别名和补全功能
Bash的问题在于,它会在别名名称上(而不是在别名命令上)尝试补全(无论何时按Tab键)。由于你没有所有800个别名的补全脚本,因此无法使用。

complete-alias项目提供了解决此问题的通用方法( https://github.com/cykerway/complete-alias
)。它利用别名的补全机制,在内部将别名扩展为别名命令,并返回扩展命令的补全建议。这意味着,别名的补全行为与别名命令的行为完全相同。
在下面的内容中,我将首先说明如何安装complete-alias,然后如何配置它以启用所有kubectl别名的补全。
安装complete-alias
首先,complete-alias依赖于bash-completion。因此,在安装complete-alias之前,你需要确保已安装bash-completion。前面已经针对Linux和macOS给出了相关说明。

对于macOS用户的重要说明:与kubectl补全脚本一样,complete-alias不适用于Bash 3.2,后者是macOS上Bash的默认版本。特别是,complete-alias依赖于bash-completion v2( brew install bash-completion@2
),至少需要Bash 4.1。这意味着,要在macOS上使用complete-alias,您需要安装较新版本的Bash。

要安装complete-alias,你只需要从GitHub存储库( https://github.com/cykerway/complete-alias
)下载bash_completion.sh脚本,并将其source到你的 〜/ .bashrc
文件中:

source ~/bash_completion.sh

重新加载你的shell之后,complete-alias将完成安装。
为kubectl别名启用补全功能

从技术上讲,complete-alias提供了 _complete_alias shell
函数。此函数检查别名,并返回别名命令的补全建议。

要将其与特定别名联系起来,你必须使用完整的Bash内置函数将 _complete_alias
设置为别名的补全功能。

例如,让我们使用 k
别名代表kubectl命令。要将 _complete_alias
设置为该别名的补全功能,你必须执行以下命令:

complete -F _complete_alias k

这样的效果是,每当你对k别名自动补全时,就会调用 _complete_alias
函数,该函数将检查别名并返回kubectl命令的补全建议。

再举一个例子,让我们使用代表 kubectl get
kg
别名:

complete -F _complete_alias kg

同样,这样做的效果是,当你对kg自动补全时,你将获得与kubectl get相同的补全建议。
请注意,可以通过这种方式对系统上的任何别名使用complete-alias。

因此,要为所有kubectl别名启用补全功能,只需为每个别名运行以上命令。如下所示(假设你将kubectl-aliases安装到 〜/ .kubectl-aliases
):

for _a in $(sed '/^alias /!d;s/^alias //;s/=.*$//' ~/.kubectl_aliases); do

  complete -F _complete_alias "$_a"

done

只需将此片段添加到你的 〜/ .bashrc
文件中,重新加载你的shell,现在你就可以对800个kubectl别名使用补全功能了!


6、使用插件扩展kubectl

从1.12版开始,kubectl包含插件机制,可让你使用自定义命令扩展kubectl。
这是一个可以作为kubectl hello调用的kubectl插件的示例:

如果你对此十分熟悉,其实kubectl插件机制与Git插件机制的设计十分相近。
本节将向您展示如何安装插件,你可以在其中找到现有插件以及如何创建自己的插件。
安装插件

Kubectl插件作为简单的可执行文件分发,名称形式为 kubectl-x
。前缀kubectl-是必填项,其后是允许调用插件的新的kubectl子命令。
例如,上面显示的hello插件将作为名为kubectl-hello的文件分发。
要安装插件,你只需要将kubectl-x文件复制到PATH中的任何目录并使其可执行(例如,使用chmod + x)。之后,你可以立即使用kubectl x调用插件。
你可以使用以下命令列出系统上当前安装的所有插件:

kubectl plugin list

如果你有多个具有相同名称的插件,或者存在无法执行的插件文件,此命令还会显示警告。

使用krew查找和安装插件

Kubectl插件使自己像软件包一样可以共享和重用。但是在哪里可以找到其他人共享的插件?

krew项目旨在为共享、查找、安装和管理kubectl插件提供统一的解决方案( https://github.com/GoogleContainerTools/krew
)。该项目将自己称为“ kubectl插件的软件包管理器”(krew与brew十分相似)。
Krew根据kubectl插件进行索引,你可以从中选择和安装。在这里,你可以看到实际操作:

如你所见,krew本身就是一个kubectl插件。这意味着,安装krew本质上就像安装其他任何kubectl插件一样。你可以在GitHub页面上找到krew的详细安装说明:
https://github.com/GoogleContainerTools/krew/#installation
最重要的krew命令如下:

# Search the krew index (with an optional search query)

kubectl krew search []

# Display information about a plugin

kubectl krew info 

# Install a plugin

kubectl krew install 

# Upgrade all plugins to the newest versions

kubectl krew upgrade

# List all plugins that have been installed with krew

kubectl krew list

# Uninstall a plugin

kubectl krew remove 

请注意,使用krew安装插件不会阻止你继续使用传统方式安装插件。即使你使用krew,你仍然可以通过其他方式安装在其他地方找到的插件(或创建自己的插件)。

此外, kubectl krew list
命令仅列出已与krew一起安装的插件,而kubectl plugin list命令列出了所有插件,即,与krew一起安装的插件和以其他方式安装的插件。

在其他地方寻找插件

Krew仍然是一个年轻的项目,目前krew索引中只有大约30个插件。如果找不到所需的内容,则可以在其他地方(例如,在GitHub上)查找插件。
我建议你查看kubectl-plugins GitHub主题。你会在这里找到几十个可用的插件:
https://github.com/topics/kubectl-plugins
创建自己的插件

当然,你也可以创建自己的kubectl插件,这并不困难。
你只需要创建一个执行所需操作的可执行文件,将其命名为kubectl-x,然后按照如上所述的方式安装即可。
可执行文件可以是任何类型,可以是Bash脚本、已编译的Go程序、Python脚本,这些类型实际上并不重要。唯一的要求是它可以由操作系统直接执行。
让我们现在创建一个示例插件。在上一节中,你使用了kubectl命令列出每个Pod的容器镜像。你可以轻松地将此命令转换为可以使用kubectl img调用的插件。

为此,只需创建一个名为 kubectl-img
的文件,其内容如下:

#!/bin/bash

kubectl get pods -o custom-columns='NAME:metadata.name,IMAGES:spec.containers[*].image'

现在,使用chmod + x kubectl-img使该文件可执行,并将其移动到PATH中的任何目录。之后,你可以立即将插件与kubectl img一起使用!
如前所述,kubectl插件可以用任何编程或脚本语言编写。如果使用Shell脚本,则具有可以轻松从插件调用kubectl的优势。但是,你可以使用真实的编程语言编写更复杂的插件,例如,使用Kubernetes客户端库。如果使用Go,还可以使用cli-runtime库,该库专门用于编写kubectl插件。

共享你的插件

如果你认为其中一个插件可能对其他人有用,欢迎在GitHub上共享。只需将其添加到kubectl-plugins主题,其他人就可以方便地找到它。
你还可以将插件添加到krew索引。你可以在krew GitHub存储库中找到有关如何执行此操作的说明。
命令补全功能
遗憾的是,目前插件机制尚不支持命令补全。这意味着你需要完整键入插件名称以及插件的所有参数。但是,kubectl GitHub存储库中对此有一个开放功能请求。因此,将来有可能实现此功能。

作者丨Daniel Weibel
原文链接:
https://learnk8s.io/blog/kubectl-productivity

推荐阅读

使用Kubectl管理Kubernetes的全解教程

kubectl+HPA!提升K8S容器资源利用的关键解决方案

你一定会用到的7条kubectl命令

About Rancher Labs

Rancher Labs由CloudStack之父梁胜创建。旗舰产品Rancher是一个开源的企业级Kubernetes管理平台,实现了Kubernetes集群在混合云+本地数据中心的集中部署与管理。Rancher一向因操作体验的直观、极简备受用户青睐,被Forrester评为2018年全球容器管理平台领导厂商,被Gartner评为2017年全球最酷的云基础设施供应商。
目前Rancher在全球拥有超过一亿的下载量,并拥有包括中国人寿、华为、中国平安、兴业银行、民生银行、平安证券、海航科技、厦门航空、上汽集团、海尔、米其林、丰田、本田、中船重工、中联重科、迪斯尼、IBM、Cisco、Nvidia、辉瑞制药、西门子、CCTV、中国联通等全球著名企业在内的共40000家企业客户。


轻量级K8S发行版k3s+边缘AI,等你探索!
↓↓↓