1.命令自动补全
命令补全是提高生产力最有用但也是经常被忽略的技巧之一。命令补全允许你使用 tab 键自动补全 kubectl 的相关命令,包括子命令、选项和参数,以及资源名称等一些复杂的内容。
在下图中我们可以看到使用 kubectl 命令自动补全的相关演示:
kubectl 自动补全
命令补全可用于 Bash 和 Zsh shell 终端。
官方文档中就包含了一些关于命令补全的相关说明,当然也可以参考下面我们为你提供的一些内容。
命令补全的工作原理
一般来说,命令补全是通过执行一个补全脚本的 shell 功能,补全脚本也是一个 shell 脚本,用于定义特定命令的补全功能。
kubectl 在 Bash 和 Zsh 下可以使用下面的命令自动生成并打印出补全脚本:
$ kubectl completion bash
# 或者
$ kubectl completion zsh
理论上在合适的 shell 中 source 上面命令的输出就可以开启 kubectl 的命令补全功能了。但是,在实际使用的时候,Bash(包括 Linux 和 Mac 之间的差异)和 Zsh 有一些细节上的差异,下面是关于这些差异的相关说明。
Bash on Linux
Bash 的命令补全脚本依赖bash-completion项目,所以需要先安装该项目。
我们可以使用各种包管理器来安装bash-completion,例如:
$ sudo apt-get install bash-completion
# 或者
$ yum install bash-completion
安装完成后可以使用一下命令测试是否安装成功了:
$ type _init_completion
如果输出一段 shell 函数,则证明已经安装成功了,如果输出未找到的相关错误,则可以将下面的语句添加到你的~/.bashrc文件中去:
source /usr/share/bash-completion/bash_completion
是否必须将上面内容添加到~/.bashrc文件中,这取决于你使用的包管理工具,对于 apt-get 来说是必须的,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 的自动补全功能应该就可以正常使用了!
2.快速查找资源
我们在使用 YAML 文件创建资源时,需要知道这些资源的一些字段和含义,一个比较有效的方法就是去 API 文档中查看这些资源对象的完整规范定义。
但是如果每次要查找某些内容的时候都切换到浏览器去查询也是很麻烦的一件事情,所以,kubectl 为我们提供了一个 kubectl explain 命令,可以在终端中直接打印出来所有资源的规范定义。kubectl explain命令的用法如下所示:
$ kubectl explain resource[.field]...
该命令可以输出请求的资源或者属性的一些规范信息,通过该命令显示的信息和 API 文档中的信息是相同的,参考下面使用示例:
默认情况下,kubectl explain命令只会显示属性的一级数据,我们可以使用--recursive参数来显示整个属性的数据:
$ kubectl explain deployment.spec --recursive
该命令会将 deployment.spec 属性下面所有的规范都打印出来。
如果你不太确定可以使用kubectl explain的资源名,可以使用下面的命令来获取所有资源名称:
$ kubectl api-resources
该命令会线上资源名称的复数形式(比如显示 deployments 而不是 deployment),还会显示一个资源的简写(比如 deploy),不过不用担心,我们可以用任意一个名称来结合kubectl explain命令使用的:
$ kubectl explain deployments.spec
# 或者
$ kubectl explain deployment.spec
# 或者
$ kubectl explain deploy.spec
3.使用自定义列格式化输出
kubectl get命令(读取集群资源)的默认输出格式如下:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app-76b6449498-86b55 1/1 Running 0 23d
nginx-app-76b6449498-nlnkj 1/1 Running 0 23d
opdemo-64db96d575-5mhgg 1/1 Running 2 23d
上面的输出结果是一种比较友好的格式,但是它包含的信息比较有限,比如上面只显示了 Pod 资源中的一些信息(与完整资源定义相比)。
所以这个时候就有自定义输出格式的用武之地了,它允许我们自由定义要显示的列和数据,可以选择要在输出中显示为单独列的资源的任何字段。
自定义列输出的用法如下:
-o custom-columns=<header>:<jsonpath>[,<header>:<jsonpath>]...
需要将每个输出列定义为
-
是列的名称,可以选择任何想要显示的内容。 是一个选择资源属性的表达式。
我们来看一个简单的例子:
$ kubectl get pods -o custom-columns='NAME:metadata.name'
NAME
nginx-app-76b6449498-86b55
nginx-app-76b6449498-nlnkj
opdemo-64db96d575-5mhgg
我们可以看到上面的命令输出了一个包含所有 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
nginx-app-76b6449498-86b55 ydzs-node2
nginx-app-76b6449498-nlnkj ydzs-node1
opdemo-64db96d575-5mhgg ydzs-node2
节点名称的表达式是spec.nodeName,这是因为已调度 Pod 的节点信息被保存在了 Pod 的spec.nodeName字段中(可以通过kubectl explain pod.spec.nodeName查看)。
注意,Kubernetes 资源字段是区分大小写的。
我们可以通过这种方式将资源的任何字段设置为输出列的数据,只需要去查看资源规范并使用我们需要的任何字段即可!
但首先,我们还是来仔细来看看这些字段的选择表达式吧!
JSONPath 表达式
选择资源字段的表达式是基于 JSONPath 的。
JSONPATH 是一种从 JSON 文件中提取数据的一种语言(类似于 XPath for XML)。选择单个字段只是 SJONPath 的最基本的用法,它还有很多其他的功能,比如列表选择器、过滤器等。
但是我们在使用kubectl explain命令的时候只支持部分 JSONPath 功能,下面我们用一些简单的示例来介绍下这些支持的功能:
# 选择一个列表的说有元素
$ kubectl get pods -o custom-columns='DATA:spec.containers[*].image'
# 选择一个列表的指定元素
$ kubectl get pods -o custom-columns='DATA:spec.containers[0].image'
# 选择和一个过滤表达式匹配的列表元素
$ kubectl get pods -o custom-columns='DATA:spec.containers[?(@.image!="nginx")].image'
# 选择特定位置下的所有字段(无论名称是什么)
$ kubectl get pods -o custom-columns='DATA:metadata.*'
# 选择具有特定名称的所有字段(无论其位置如何)
$ kubectl get pods -o custom-columns='DATA:..image'
另外一个非常重要的操作符是[],Kubernetes 的资源很多字段都是列表,改操作符可以让我们选择这些列表中的一些元素,它通常与通配符[*]一起使用来选择列表中的所有元素。
示例演示
使用自定义列输出格式的结果是多种多样的,因为我们可以在输出中显示资源的任何字段或者字段的组合,下面是一些示例演示,当然也可以根据自己的实际需求就自行实践。
提示:如果你经常使用某一个命令,那么我们可以为这个命令创建一个 shell alias 别名,可以提高效率。
显示 Pod 的所有容器镜像
下面的命令显示 default 命名空间下面的每个 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 的容器镜像会在同一列中用逗号隔开显示。
显示节点的可用区域
$ 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来获得,集群在公有云上面运行的话,会自动创建该标签的,并将其值设置为节点的可用区名称。
Label 标签不是 Kubernetes 资源规范的一部分,所以无法在 API 文档中找到上面的标签,不过我们可以将节点信息输出为 YAML 或者 JSON 格式,这样就可以看到标签信息了:
$ kubectl get nodes -o yaml
# 或者
$ kubectl get nodes -o json
这种方法除了用来查看资源规范之外,这也是用来发现资源更多信息的一种很好的方式。