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

本文来自Rancher Labs
 html

若是你正在使用Kubernetes,那么kubectl必定是你最常使用的工具。不管你须要学习任何工具,都应该先提早了解kubectl并有效地使用它。本文包含了一系列技巧,可让你更高效并且有效地使用kubectl。同时,能够加深你对Kubernetes各个方面工做方式的理解。node

 

本文的目标不只是使你使用Kubernetes的平常工做更高效,并且更愉快!
 nginx

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

目  录

 

  • 什么是kubectl?git

  • 使用命令补全功能保存输入github

  • 迅速查找资源规范web

  • 使用自定义列输出格式shell

  • 轻松在集群和命名空间之间切换express

  • 使用自动生成别名(Aliases)保存输入macos

  • 使用插件扩展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请求:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
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资源定义)。哪些因素会致使集群中出现这种状况?以下:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
执行kubectl create -f replicaset.yaml以后,API server将会在存储后端保存你的ReplicaSet资源定义。
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
这将触发controller manager中的ReplicaSet controller,后者监视ReplicaSet资源的建立,更新和删除。
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
ReplicaSet controller为每一个ReplicaSet副本建立了一个Pod定义(根据在ReplicaSet定义中的Pod模板建立)并将它们保存到存储后端。
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
这触发了scheduler,它监视还没有被分配给worker节点的Pod。
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
Scheduler为每一个Pod选择一个合适的worker节点,并在存储后端中添加该信息到Pod定义中。

 

请注意,到目前为止,集群中任何地方都没有运行工做负载的代码。至今,咱们所完成的事就是在master节点上的存储后端中建立和更新资源。
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
这触发了在Pod所调度到的worker节点上的kubelet,它监视调度到其worker节点上的pod。
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
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的生产力。
 

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

 

命令补全是提升kubectl生产率的最有用但常常被忽略的技巧之一。

 

命令补全功能使你可使用Tab键自动完成kubectl命令的各个部分。这适用于子命令、选项和参数,包括诸如资源名称之类难以键入的内容。

 
在这里,你能够看到kubectl命令的完成状况:
 
万字硬核干货!6大技巧,极速提高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

 

二、迅速查看资源规范

 
当你建立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

 

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

 

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=<header>:<jsonpath>\[,<header>:<jsonpath>\]...

 
你必须将每一个输出列定义为&lt;header&gt;:&lt;jsonpath&gt;对:
 

  • &lt;header&gt;是列的名称,你能够选择任何所需的内容。

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

 

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

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

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

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

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

 

默认的kubeconfig文件是〜/ .kube / config。该文件一般是经过某些命令自动建立或更新的(例如,若是使用托管的Kubernetes服务,则为aws eks update-kubeconfiggcloud 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文件实际包含什么:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
如你所见,kubeconfig文件由一组上下文组成。上下文包含如下三个元素:
 

  • 集群:集群的API server的URL

  • 用户:集群中特定用户的身份验证凭据

  • 命名空间:链接到集群时要使用的命名空间

     

实际上,人们一般在其kubeconfig文件中为每一个集群使用单个上下文。可是,每一个集群也能够有多个上下文,它们的用户或命名空间不一样。但这彷佛不太常见,所以集群和上下文之间一般存在一对一的映射。

 

在任何给定时间中,这些上下文其中之一均可以被设置为当前上下文(经过kubeconfig文件中的专用字段):
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
当kubectl读取kubeconfig文件时,它老是使用当前上下文中的信息。所以,在上面的示例中,kubectl将链接到Hare集群。
 

所以,要切换到另外一个集群时,你只需在kubeconfig文件中更改当前上下文便可:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
在上面的示例中,kubectl如今将链接到Fox集群。
 

并切换到同一集群中的另外一个命名空间,能够更改当前上下文的命名空间元素的值:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
在上面的示例中,kubectl如今将在Fox集群中使用Prod命名空间(而不是以前设置的Test命名空间)。

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

 

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

 

Kubectx

 

Kubectx能够有效帮助集群和命名空间之间进行切换。该工具提供了kubectx和kubens命令,使你能够分别更改当前上下文和命名空间。
 

如前所述,若是每一个集群只有一个上下文,则更改当前上下文意味着更改集群。

 
在这里,你能够看到这两个命令的做用:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
如上一节所述,这些命令仅需在后台编辑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相似的功能。在这里,你能够看到它们的做用:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
请注意,别名使用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更改命名空间?

 

我建立了两个能够实现这一功能的插件:

 

 
在内部,插件创建在上一部分的别名基础上。
 

在这里,你能够看到正在使用的插件:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
请注意,插件使用fzf提供的交互式模糊搜索界面。这意味着,您须要安装fzf才能使用这些插件。

 

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

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

 

Shell别名一般是保存输入内容的好方法。kubectl-aliases项目则是这一想法的具体体现,并为常见的kubectl命令提供了约800个别名:
 
https://github.com/ahmetb/kubectl-aliases

 

你可能想知道如何记住800个别名?实际上,你不须要记住它们,由于它们都是根据简单的方案生成的,以下所示:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!

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

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

万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
如你所见,别名由组件组成,每一个组件表明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

 

你不须要使用全部组件做为别名。例如,kkgkloksyskgpo也是有效的别名。此外,你能够在命令行上将别名与其余单词组合在一块儿。
 
 

例如,你可使用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选项须要一个参数(标签规范)。所以,你必须使用此别名,例如:
 
万字硬核干货!6大技巧,极速提高kubectl的生产力!
 
所以,你只能在别名末尾使用afl组件。
 

总而言之,一旦掌握了该方案,就能够从要执行的命令中直观地推断出别名,并节省大量输入!

 

安装

 

要安装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 getkg别名:
 

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别名使用补全功能了!
 

六、使用插件扩展kubectl

 

从1.12版开始,kubectl包含插件机制,可以让你使用自定义命令扩展kubectl。

 

这是一个能够做为kubectl hello调用的kubectl插件的示例:
 
万字硬核干货!6大技巧,极速提高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插件的软件包管理器”(krewbrew十分类似)。

 

Krew根据kubectl插件进行索引,你能够从中选择和安装。在这里,你能够看到实际操做:
 
万字硬核干货!6大技巧,极速提高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 [<query>]
# Display information about a plugin
kubectl krew info <plugin>
# Install a plugin
kubectl krew install <plugin>
# 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 <plugin>

 
请注意,使用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