提高您的kubectl生产力(第二部分):命令完成、资源规范快速查看和自定义列输出格式

本文翻译自《Boosting your kubectl productivity》

第一部分:什么是kubectl?

1. 通过命令完成(command completion)减少输入

命令完成是提高你的kubectl生产力的最有用但经常被忽视的技巧之一。

命令完成允许您使用Tab键自动完成kubectl命令的各个部分。这适用于子命令,选项和参数,包括资源名称等难以输入的内容。

在这里你可以看到kubectl命令完成的动作:

img{512x368}

命令完成在BashZsh shell下均可用。

官方文档中包含有关设置命令完成的详细说明,下面的章节我们再带着大家回顾一下。

命令完成的工作原理

通常,命令完成是一个shell功能,它通过completion script(完成脚本)的方式工作。完成脚本是一个shell脚本,用于定义特定命令的完成行为。获取完成脚本可以完成相应的命令。

Kubectl可以使用以下命令自动生成并打印出Bash和Zsh的完成脚本:

$kubectl completion bash
# or
$kubectl completion zsh

理论上,在适当的shell中获取此命令的输出可以完成kubectl命令。

但是,在实践中,Bash(包括Linux和macOS之间的差异)和Zsh的细节不同。以下部分解释了所有这些情况:

  • 在Linux上为Bash设置命令完成
  • 在macOS上设置Bash的命令完成
  • 设置Zsh的命令完成

在Linux上的Bash

Bash的完成脚本取决于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命令完成应该正常工作!

在MacOS上的Bash

有了macOS,就会出现轻微的复杂情况。原因是macOS上的Bash默认版本是3.2,这已经过时了。遗憾的是,kubectl完成脚本至少需要Bash 4.1,因此不适用于Bash 3.2。

Apple在macOS中包含过时版本的Bash的原因是较新版本使用Apple不支持的GPLv3许可证。

这意味着,要在macOS上使用kubectl命令完成,您必须安装较新版本的Bash。您甚至可以将它设为新的默认shell,这将为您节省很多此类麻烦。这实际上并不困难,您可以在我之前编写的macOS文章中的升级Bash中找到说明。

在继续之前,请确保您现在确实使用的是Bash 4.1或更新版本(请查看bash –version)

Bash的完成脚本取决于bash-completion项目,因此您必须先安装它。

您可以使用Homebrew安装bash-completion :

$brew install bash-completion@2

bash-completion v2的@2代表。kubectl完成脚本需要bash-completion v2,而bash-completion v2至少需要Bash 4.1。这就是您不能在低于4.1的Bash版本上使用kubectl完成脚本的原因。

该brew install命令的输出包含一个“警告”部分,其中包含将以下行添加到您的~/.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文件中。这能确保子shell中也可以使用bash-completion。

重新加载shell后,可以使用以下命令测试是否正确安装了bash-completion:

$type _init_completion

如果这输出shell函数的代码,那么你就完成了。

现在,您必须进行设置以便kubectl 完成脚本在所有shell会话中获取。

一种方法是将以下行添加到您的~/.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 howbrew formula放在/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参考文档中,那里包含了所有资源的完整规范。

但是,每次需要查找某些内容时都要切换到Web浏览器很乏味。因此,kubectl提供了kubectl explain命令,可以打印出终端中所有资源的资源规范。

kubectl explain用法如下:

$kubectl explain resource[.field]...

该命令输出所请求资源或字段的规范。kubectl explain显示的信息与API参考中的信息相同。

默认情况下,kubectl explain仅显示单个级别的字段。您可以使用显示整个字段树的标志:–recursive:

$kubectl explain deployment.spec --recursive

如果您不确定可以使用哪些资源名称,可以使用kubectl explain以下命令显示所有这些名称:

$kubectl api-resources

此命令以复数形式显示资源名称(例如,deployments而不是deployment)。对于拥有短名称的资源,它还显示该资源的短名称(例如:deploy)。不要担心这些差异,对于kubectl来说,所有这些名称变体都是等同的。也就是说,你可以在kubectl explain中使用它们中的任何一个。

例如,以下所有命令都是等效的:

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

您必须将每个输出列定义为一

<

header>:对:

  • <

header> 是列的名称,您可以选择任何您想要的。
* 是一个选择资源字段的表达式(在下面更详细地说明)。

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

$ 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名称的表达式是metadata.name。这样做的原因是Pod的名称在Pod资源字段的metadata的name字段中定义(您可以在API参考中查找或使用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

JSONPath是一种从JSON文档中提取数据的语言(类似于XPath for XML)。选择单个字段只是JSONPath的最基本用法。它有很多功能,如列表选择器,过滤器等。

但是,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资源的许多字段都是列表,此运算符允许您选择这些列表中的项目。它通常与通配符一起使用,[*]以选择列表中的所有项目。

您将在下面找到一些使用此表示法的示例。

示例应用程序

使用自定义列输出格式的可能性是无穷无尽的,因为您可以在输出中显示资源的任何字段或字段组合。以下是一些示例应用程序,但您可以自己探索并找到对您有用的应用程序!

提示:如果您经常使用其中一个命令,则可以为其创建shell别名。

显示Pods的容器镜像

$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参考中找到上述标签。但是,如果将节点输出为YAML或JSON,则可以看到它(以及所有其他标签):

$kubectl get nodes -o yaml
# or
$kubectl get nodes -o json

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


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网上线了,感谢小伙伴们学习支持!

我爱发短信:企业级短信平台定制开发专家 https://tonybai.com/
smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

我的联系方式:

微博:https://weibo.com/bigwhite20xx
微信公众号:iamtonybai
博客:tonybai.com
github: https://github.com/bigwhite

微信赞赏:
img{512x368}

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

提高您的kubectl生产力(第一部分):什么是kubectl

img{512x368}

本文翻译自《Boosting your kubectl productivity》

如果您使用Kubernetes,那么kubectl可能是您最常用的工具之一。每当您花费大量时间使用某种特定工具时,值得深入了解并了解如何有效地使用它。

本文包含一系列提示和技巧,使您对kubectl的使用更加高效和有效。同时,它旨在加深您对Kubernetes各方面工作的理解。

本文的目标是让您在Kubernetes的日常工作更高效、更愉快!

简介:什么是kubectl?

在学习如何更有效地使用kubectl之前,您应该基本了解它是什么以及它是如何工作的。

从用户的角度来看,kubectl是控制Kubernetes的驾驶舱。它允许您执行所有可能的Kubernetes操作。

从技术角度来看,kubectl是Kubernetes API的客户端。

Kubernetes API是一个HTTP REST API。此API是真正的Kubernetes用户接口。通过API我们可以完全控制Kubernetes。这意味着每个Kubernetes操作都作为API端点公开,并且可以通过对此端点的HTTP请求来执行。

因此,kubectl的主要工作是对Kubernetes API执行HTTP请求

img{512x368}

Kubernetes是一个完全以资源为中心的系统。这意味着,Kubernetes保持内部资源状态,所有Kubernetes操作都是对这些资源的CRUD操作。您可以通过操纵这些资源来完全控制Kubernetes(并且Kubernetes根据当前的资源状态确定要做什么)。因此,Kubernetes API的参考文档是按资源类型列表及其关联操作进行组织的。

让我们考虑一个例子。

想象一下,您想要创建ReplicaSet资源。为此,您需要在名为replicaset.yaml file 的文件中定义ReplicaSet ,然后运行以下命令:

kubectl create -f replicaset.yaml

显然,这会在Kubernetes中创建ReplicaSet。但是幕后会发生什么?

Kubernetes具有创建ReplicaSet操作,并且与所有Kubernetes操作一样,它作为API端点公开。此操作的特定API端点如下:

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

您可以在API参考文档中找到所有Kubernetes操作的API端点(包括上述端点)。要向端点发出实际请求,您需要将API服务器的URL添加到API参考中列出的端点路径。

因此,当您执行上述命令时,kubectl会向上述API端点发出HTTP POST请求。ReplicaSet定义(您在replicaset.yaml文件中提供的)定义在请求正文中传递。

这就是kubectl如何适用于与Kubernetes集群交互的所有命令。在所有这些情况下,kubectl只是向适当的Kubernetes API端点发出HTTP请求。

请注意,完全可以curl通过手动向Kubernetes API发出HTTP请求等工具来控制Kubernetes 。Kubectl让您更容易使用Kubernetes API。

这些是kubectl的基础知识以及它是如何工作的。但是每个kubectl用户应该知道的Kubernetes API还有很多。为此,让我们简要介绍一下Kubernetes的内部结构。

Kubernetes内部

Kubernetes由一组独立组件组成,这些组件在集群节点上作为单独的进程运行。某些组件在主节点上运行,而其他组件在工作节点上运行,每个组件都有一个非常特定的功能。

这些是主节点上最重要的组件:

  • 存储后端:存储资源定义(通常使用etcd)
  • API服务器:提供Kubernetes API并管理存储后端
  • 控制器管理器:确保资源状态符合规范
  • 调度程序:将Pod调度到工作节点

这是工作节点上最重要的组件:

  • Kubelet:负责管理工作节点上的容器执行

为了了解这些组件如何协同工作,让我们考虑一个例子。

假设您刚刚执行kubectl create -f replicaset.yaml。kubectl向创建ReplicaSet API端点发送HTTP POST请求(传递ReplicaSet资源定义)。

集群中有什么影响?观看以下内容:

img{512x368}

图:执行kubectl create -f replicaset.yaml,API服务器将ReplicaSet资源定义保存在存储后端中。

img{512x368}
图:这会触发控制器管理器中的ReplicaSet控制器,后者会监视ReplicaSet资源的创建,更新和删除。

img{512x368}
图:ReplicaSet控制器为ReplicaSet的每个副本创建一个Pod定义(根据ReplicaSet定义中的Pod模板)并将它们保存在存储后端中。

img{512x368}
图:这会触发监视尚未分配给工作节点的Pod的调度程序。

img{512x368}
图:调度程序为每个Pod选择合适的工作节点,并将此信息添加到存储后端中的Pod定义。

img{512x368}
图:这会触发已调度Pod的工作节点上的kubelet,后者监视已调度到其工作节点的Pod。

img{512x368}
图:kubelet从存储后端读取Pod定义,并指示容器运行时(例如Docker)在工作节点上运行容器。

以下是文字说明。

创建ReplicaSet端点的API请求由API服务器处理。API服务器对请求进行身份验证,并将ReplicaSet资源定义保存在存储后端中。

此事件触发ReplicaSet控制器,它是控制器管理器的子进程。ReplicaSet控制器监视存储后端中ReplicaSet资源的创建,更新和删除,并在发生这种情况时通过事件得到通知。

ReplicaSet控制器的工作是确保存在ReplicaSet所需数量的副本Pod。在我们的示例中,尚未存在Pod,因此ReplicaSet控制器会创建这些Pod定义(根据ReplicaSet定义中的Pod模板)并将它们保存在存储后端中。

新Pod 的创建会触发调度程序,后者监视尚未调度到工作节点的Pod定义。调度程序为每个Pod选择合适的工作节点,并使用此信息更新存储后端中的Pod定义。

请注意,到目前为止,集群中的任何位置都没有运行工作负载代码。到目前为止所做的就是在主节点上的存储后端创建和更新资源。

此事件触发监视调度到其工作节点的Pod的kubelet。已安排ReplicaSet Pods的工作节点的kubelet指示已配置的容器运行时(可能是Docker)下载所需的容器映像并运行容器。

此时,最后,您的ReplicaSet应用程序正在运行!

Kubernetes API的作用

从上面的示例中可以看出,Kubernetes组件(API服务器和存储后端除外)通过监视存储后端中的资源更改和操作存储后端中的资源来工作。

但是,这些组件不直接访问存储后端,而只能通过Kubernetes API访问存储后端。

请考虑以下示例:

  • ReplicaSet控制器使用列表ReplicaSets API端点 API操作以及watch用于监视ReplicaSet资源更改的参数。
  • ReplicaSet控制器使用create Pod API端点来创建Pod。
  • 调度程序使用修补程序Pod API端点来更新Pod,其中包含有关所选工作节点的信息。

如您所见,这与kubectl也使用的API相同。

Kubernetes API对内部组件和外部用户的双重使用是Kubernetes的基本设计概念。

有了这些知识,您可以总结Kubernetes的工作原理如下:

  • 存储后端存储Kubernetes的状态(即资源)。
  • API服务器以Kubernetes API的形式提供存储后端的接口。
  • 所有其他Kubernetes组件和用户通过Kubernetes API读取,观察和操纵Kubernetes的状态(即资源)。

熟悉这些概念将有助于您更好地理解kubectl并充分利用它!


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网上线了,感谢小伙伴们学习支持!

我爱发短信:企业级短信平台定制开发专家 https://tonybai.com/
smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

我的联系方式:

微博:https://weibo.com/bigwhite20xx
微信公众号:iamtonybai
博客:tonybai.com
github: https://github.com/bigwhite

微信赞赏:
img{512x368}

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats