kubernetes集群管理命令(二)

By | 2019年6月20日

上一节我们介绍了一些基本的命令,这一节我们介绍一些更为复杂的命令.

pod排序
使用kubectl get pod获取pod资源默认是以名称排序的,有些时候我们可能希望按其它顺序排序.比如说我们想要按照节点来排序.以便可以看到不同的节点上都运行着哪些pod.

这个需求可以使用linux命令很简单实现.使用kubectl get pod加上-owide参数就可以显示pod所在的节点.我们再使用linux sort命令就可以对结果按照特定字段排序了.以下示例是按节点排序后的结果

[centos@k8s-master ~]$ kubectl get pod -owide|sort -k 7
sagent-b4dd8b5b9-5m2jc                     1/1     Running   0          15h     10.244.5.17   k8s-node1              
consul-0                                   1/1     Running   0          2d17h   10.244.2.27   k8s-node2              
consul-2                                   1/1     Running   0          2d17h   10.244.2.28   k8s-node2              
stodagent-6f47976ccb-8fzmv                 1/1     Running   0          2d17h   10.244.2.23   k8s-node2              
stodagent-6f47976ccb-vf7kx                 1/1     Running   0          2d17h   10.244.2.22   k8s-node2              
trackingapi-gateway-dep-79bb86bb57-x9xzp   1/1     Running   0          2d17h   10.244.2.24   k8s-node2              
sagent-b4dd8b5b9-6mmst                     1/1     Running   0          15h     10.244.6.6    k8s-node3              
sagent-b4dd8b5b9-zq649                     1/1     Running   0          15h     10.244.7.7    k8s-node4              
stodagent-6f47976ccb-j7m8b                 1/1     Running   0          2d17h   10.244.3.6    k8s-node5              
consul-1                                   1/1     Running   0          2d17h   10.244.3.13   k8s-node5              
easymock-dep-84767b6f75-l84r4              1/1     Running   0          15h     10.244.8.8    k8s-node6              
NAME                                       READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES

我们可以看到,已经以节点名称来排序的,这里不太优雅的是标题被排在了最后面.但是无伤大雅.

其实kubectl get命令有一个–sort-by参数.我们可以通过它来指定要按照资源的哪一个字段来排序,而不局限于展示出的字段.以下是使用–sort-by参数按节点名称排序后的结果.

[centos@k8s-master ~]$ kubectl get pod --sort-by='{.spec.nodeName}' -owide
NAME                                       READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
sagent-b4dd8b5b9-5m2jc                     1/1     Running   0          15h     10.244.5.17   k8s-node1              
consul-0                                   1/1     Running   0          2d17h   10.244.2.27   k8s-node2              
stodagent-6f47976ccb-8fzmv                 1/1     Running   0          2d17h   10.244.2.23   k8s-node2              
consul-2                                   1/1     Running   0          2d17h   10.244.2.28   k8s-node2              
stodagent-6f47976ccb-vf7kx                 1/1     Running   0          2d17h   10.244.2.22   k8s-node2              
trackingapi-gateway-dep-79bb86bb57-x9xzp   1/1     Running   0          2d17h   10.244.2.24   k8s-node2              
sagent-b4dd8b5b9-6mmst                     1/1     Running   0          15h     10.244.6.6    k8s-node3              
sagent-b4dd8b5b9-zq649                     1/1     Running   0          15h     10.244.7.7    k8s-node4              
consul-1                                   1/1     Running   0          2d17h   10.244.3.13   k8s-node5              
stodagent-6f47976ccb-j7m8b                 1/1     Running   0          2d17h   10.244.3.6    k8s-node5              
easymock-dep-84767b6f75-l84r4              1/1     Running   0          15h     10.244.8.8    k8s-node6              

除了展示出来的字段外,我们还可以按照没有展示出来的字段进行排序.比如我们可以按照startTime来排序,看看哪些pod运行的时间较长.

[centos@k8s-master ~]$ kubectl get pod --sort-by='{.status.startTime}'
NAME                                       READY   STATUS             RESTARTS   AGE
stodagent-6f47976ccb-vf7kx                 1/1     Running            0          2d18h
stodagent-6f47976ccb-j7m8b                 1/1     Running            0          2d18h
stodagent-6f47976ccb-8fzmv                 1/1     Running            0          2d18h
trackingapi-gateway-dep-79bb86bb57-x9xzp   1/1     Running            0          2d18h
consul-0                                   1/1     Running            0          2d18h
consul-1                                   1/1     Running            0          2d17h
consul-2                                   1/1     Running            0          2d17h
sagent-b4dd8b5b9-5m2jc                     1/1     Running            0          16h
sagent-b4dd8b5b9-zq649                     1/1     Running            0          16h
sagent-b4dd8b5b9-6mmst                     1/1     Running            0          16h
easymock-dep-84767b6f75-l84r4              1/1     Running            0          15h
redis-cache-f87d8488c-v4zjx                0/1     ErrImagePull       0          57s
redis-cache-f87d8488c-4d9dl                0/1     ImagePullBackOff   0          57s
redis-cache-f87d8488c-kxc89                0/1     ImagePullBackOff   0          57s

看了以后输出内容以后,大家可能一头雾水,以上到底是不是按启动时间排序的?如何直接地看到是按启动时间排序的呢?其实实际上确实是按照启动时间排序了,为民展示此示例,我刚刚不久启动了三个无法运行的redis实例,它们被排在了最下面.

我们能不能把startTime字段也输出出来呢,这样就可以直接地看到输出时间了,是不是按这个时间排序的也就一目了然了.答案是肯定的.

自定义显示字段
前面一节我们遇到一个问题,我们有一个需求把pod的startTime显示出来.其实这个需求是可以实现的,kubectl get的输入格式参数-o(或–output)接收一个custom-columns自定义列的格式.我们可以通过它来实现自定义输出格式.

格式为:
-o=custom-columns=列名:字段值,列名:字段值

其中字段值是通过资源的定义文件选择出来的.

以下示例我们展示出pod的name和startTime

[centos@k8s-master ~]$  kubectl get pod --sort-by=.status.startTime  -o=custom-columns=name:.metadata.name,startTime:.status.startTime
name                                       startTime
stodagent-6f47976ccb-vf7kx                 2019-05-14T07:19:05Z
stodagent-6f47976ccb-j7m8b                 2019-05-14T07:19:05Z
stodagent-6f47976ccb-8fzmv                 2019-05-14T07:19:05Z
trackingapi-gateway-dep-79bb86bb57-x9xzp   2019-05-14T07:19:06Z
consul-0                                   2019-05-14T07:19:28Z
consul-1                                   2019-05-14T07:25:06Z
consul-2                                   2019-05-14T07:25:16Z
sagent-b4dd8b5b9-5m2jc                     2019-05-16T09:20:17Z
sagent-b4dd8b5b9-zq649                     2019-05-16T17:09:37Z
sagent-b4dd8b5b9-6mmst                     2019-05-16T17:19:59Z
easymock-dep-84767b6f75-l84r4              2019-05-16T18:00:07Z
redis-cache-f87d8488c-v4zjx                2019-05-17T01:21:54Z
redis-cache-f87d8488c-4d9dl                2019-05-17T01:21:54Z
redis-cache-f87d8488c-kxc89                2019-05-17T09:11:11Z

这样就可以一目了解地看到它们是按时间先后顺序排序的.但是我们可以看到,命令变得有点复杂了,如果想要和像默认输出一样把那些字段都展示出来,是不是需要定义更多的自定义输出字段,能不能在默认的输出字段后面追加自定义字段呢.答案是否定的,目前无法做到.有用户建议增加–extra-columns参数在默认输出的基础上增加额外输出字段.但是截至目前这个pr还没有合并.待正式发布可有还需要等待数月.

按时间排序kubernetes里的事件资源
有时候为了排查错误,我们可能需要查看kubernetes里的事件资源,我们可以按照时间顺序以方便查看

kubectl get events –sort-by=.metadata.creationTimestamp
分别使用go-template,jsonpath,yq,jq来获取一个pod里的镜像
以下我们使用四个示例来展示如何获取一个叫作consul-0的pod的image(大家可以使用任意一个pod来做练习)

一句话,条条大路通罗马,只要能熟悉掌握其中一种方法便可以完成我们日常工作中的任务,大家不必把所有工具都掌握,根据实际情况和自己知识体系来选择.

使用to-template获取
命令如下

[centos@k8s-master ~]$ kubectl get pod consul-0 -ogo-template='{{range .spec.containers}}{{.image}}{{end}}'
consul:latest

range函数用来遍历集合对象.end用于结束遍历

使用jsonpath

kubectl get pod consul-0 -ojsonpath='{range .spec.containers[*]}{.image}{end}'
consul:latest

这里和上面的go-template非常类似,不同的是数组对象后面要跟中括号[]以表明是数组,中括号里带上星号(*)表示索引所有.

jsonpath与go-template不同的是,jsonpath除了可以使用星号*号索引所有的集群元素以外,还可以使用数字索引(同其它编程语言一样,0代表第一个元素)或者范围索引(例如[0:1],[:1])

以上命令都不够简洁.使用jsonpath还有一种更为简洁的方法,那就是递归查找,这样可以在不知道文档的详细结构但是知道具体的属性名的时候进行查找.示例如下

[centos@k8s-master ~]$ kubectl get pod consul-0 -ojsonpath='{..image}'
consul:latest consul:latest

同上面相比,这里的结果里多出了一条记录.其实这是因为status字段里的containerStatuses字段里也有image属性.我们可以通过以下命令来进一步缩小查找范围

[centos@k8s-master ~]$ kubectl get pod consul-0 -ojsonpath='{.spec..image}'
consul:latest

使用yq工具

[centos@k8s-master ~]$ kubectl get po consul-0 -oyaml|yq r - spec.containers[*].image
- consul:latest

使用jq工具
示例如下:

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq .spec.containers[].image
"consul:latest"

yq也可以使用递归查询方式,只不不是特别优雅,并且限制也非常大,只适合简单查看

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq '..|.image?'
null
null
null
null
null
"consul:latest"
null
null
null
null
null
null
null
null
null
null
null
"consul:latest"
null
null
null

以上输出了很多null影响观看,我们可以使用grep管道把它们过滤掉

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq '..|.image?'|grep -v null
"consul:latest"
"consul:latest"

对象输出
以上示例我们仅仅输出了某一个字段的值,但是如果在可编程环境中使用,我们需要的可能不仅仅是普通的数值,也有可能是更为复杂的对象类似,常见的为json对象.这里我们介绍如何使用jq工具把结果输出为对象类型

以下示例我们把image的名称和image镜像的名称做为一个json对象输出

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq '{name:.spec.containers[0].name,image:.spec.containers[0].image}'
{
  "name": "consul",
  "image": "consul:latest"
}

以上仅输出了一个对象,如果我们想要输出的是数组对象呢,这里有些处理技术,请看以下示例:

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq .status.conditions
[
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2019-05-14T07:19:28Z",
    "status": "True",
    "type": "Initialized"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2019-05-14T07:25:06Z",
    "status": "True",
    "type": "Ready"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2019-05-14T07:25:06Z",
    "status": "True",
    "type": "ContainersReady"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2019-05-14T07:19:28Z",
    "status": "True",
    "type": "PodScheduled"
  }
]

我们要把以下结果重新组装,保存为仅包含lastTransitionTime的集群类型

以下是一种常见的错误操作方法:

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq '.status.conditions[]|{lastTransitionTime:.lastTransitionTime}'
{
  "lastTransitionTime": "2019-05-14T07:19:28Z"
}
{
  "lastTransitionTime": "2019-05-14T07:25:06Z"
}
{
  "lastTransitionTime": "2019-05-14T07:25:06Z"
}
{
  "lastTransitionTime": "2019-05-14T07:19:28Z"
}

我们可以看到,我们实际上是取到了多个对象,但是它们并不是一个数组,想要获取一个数组对象,正确的操作如下:

[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|jq '[.status.conditions[]|{lastTransitionTime:.lastTransitionTime}]'
[
  {
    "lastTransitionTime": "2019-05-14T07:19:28Z"
  },
  {
    "lastTransitionTime": "2019-05-14T07:25:06Z"
  },
  {
    "lastTransitionTime": "2019-05-14T07:25:06Z"
  },
  {
    "lastTransitionTime": "2019-05-14T07:19:28Z"
  }
]

大家仔细看看其中的差别在哪里

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注