上一節我們介紹了一些基本的命令,這一節我們介紹一些更為復雜的命令.
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 <none> <none>
consul-0 1/1 Running 0 2d17h 10.244.2.27 k8s-node2 <none> <none>
consul-2 1/1 Running 0 2d17h 10.244.2.28 k8s-node2 <none> <none>
stodagent-6f47976ccb-8fzmv 1/1 Running 0 2d17h 10.244.2.23 k8s-node2 <none> <none>
stodagent-6f47976ccb-vf7kx 1/1 Running 0 2d17h 10.244.2.22 k8s-node2 <none> <none>
trackingapi-gateway-dep-79bb86bb57-x9xzp 1/1 Running 0 2d17h 10.244.2.24 k8s-node2 <none> <none>
sagent-b4dd8b5b9-6mmst 1/1 Running 0 15h 10.244.6.6 k8s-node3 <none> <none>
sagent-b4dd8b5b9-zq649 1/1 Running 0 15h 10.244.7.7 k8s-node4 <none> <none>
stodagent-6f47976ccb-j7m8b 1/1 Running 0 2d17h 10.244.3.6 k8s-node5 <none> <none>
consul-1 1/1 Running 0 2d17h 10.244.3.13 k8s-node5 <none> <none>
easymock-dep-84767b6f75-l84r4 1/1 Running 0 15h 10.244.8.8 k8s-node6 <none> <none>
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 <none> <none>
consul-0 1/1 Running 0 2d17h 10.244.2.27 k8s-node2 <none> <none>
stodagent-6f47976ccb-8fzmv 1/1 Running 0 2d17h 10.244.2.23 k8s-node2 <none> <none>
consul-2 1/1 Running 0 2d17h 10.244.2.28 k8s-node2 <none> <none>
stodagent-6f47976ccb-vf7kx 1/1 Running 0 2d17h 10.244.2.22 k8s-node2 <none> <none>
trackingapi-gateway-dep-79bb86bb57-x9xzp 1/1 Running 0 2d17h 10.244.2.24 k8s-node2 <none> <none>
sagent-b4dd8b5b9-6mmst 1/1 Running 0 15h 10.244.6.6 k8s-node3 <none> <none>
sagent-b4dd8b5b9-zq649 1/1 Running 0 15h 10.244.7.7 k8s-node4 <none> <none>
consul-1 1/1 Running 0 2d17h 10.244.3.13 k8s-node5 <none> <none>
stodagent-6f47976ccb-j7m8b 1/1 Running 0 2d17h 10.244.3.6 k8s-node5 <none> <none>
easymock-dep-84767b6f75-l84r4 1/1 Running 0 15h 10.244.8.8 k8s-node6 <none> <none>
除了展示出來的字段外,我們還可以按照沒有展示出來的字段進行排序.比如我們可以按照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"
}
]
大家仔細看看其中的差別在哪里