系列目录html
前面一节咱们介绍了使用go-template截取属性,go-template功能很是强大,能够定义变量,使用流程控制等,这是jsonpath所不具有的.然而,jsonpth使用的时候更为灵活.经过上一节咱们发现,咱们想要找到某个具体属性,必须从最外层一层层向内找到具体属性,这对于嵌套层次很是深的yaml对象来讲操做是很是繁琐的.而使用jsonpath只须要知道顶层对象,而后能够省略中间的对象,递归查找直接找到咱们想要的属性,这在不少时候对咱们在不清楚对象的层次可是清楚知道某个属性名称的时候获取这个属性的值是很是有帮助的.而且jsonpath可使用下标索引数组对象,这在实际工做中也是很是有帮助的(好比虽然pod里能够包含多个containers,可是不少时候一个pod里只有一个container,使用go-template咱们为了找到这个对象须要写一个遍历表达式,而使用jsonpath能够直接取第0个对象,省去了写循环的麻烦),还有一点很重要的是jsonpath是一个标准,这对于熟悉jsonpath的开发者来讲使用起来方便不少.node
jsonpath模板使用一对花括号({}
)把jsonpath表达式包含在里面(go-template
是双花括号).除了标准jsonpath语法外,kubernetes jsonpath模板还额外支持如下语法:linux
用""双引号来引用JSONPath表达式中的文本json
使用range和end来遍历集合(这点和go-template相似)centos
使用负数来从尾部索引集合数组
$操做符是可选的由于表达式默认老是从根节点开始选择
对象经过它的String()
函数打印输出出来bash
假若有如下JSON字符串函数
{ "kind": "List", "items":[ { "kind":"None", "metadata":{"name":"127.0.0.1"}, "status":{ "capacity":{"cpu":"4"}, "addresses":[{"type": "LegacyHostIP", "address":"127.0.0.1"}] } }, { "kind":"None", "metadata":{"name":"127.0.0.2"}, "status":{ "capacity":{"cpu":"8"}, "addresses":[ {"type": "LegacyHostIP", "address":"127.0.0.2"}, {"type": "another", "address":"127.0.0.3"} ] } } ], "users":[ { "name": "myself", "user": {} }, { "name": "e2e", "user": {"username": "admin", "password": "secret"} } ] }
Function | Description | Example | Result |
---|---|---|---|
text | the plain text | kind is {.kind} | kind is List |
@ | the current object | {@} | the same as input |
. or [] | child operator | {.kind} or {[‘kind’]} | List |
.. | recursive descent | {..name} | 127.0.0.1 127.0.0.2 myself e2e |
* | wildcard. Get all objects | {.items[*].metadata.name} | [127.0.0.1 127.0.0.2] |
[start:end :step] | subscript operator | {.users[0].name} | myself |
[,] | union operator | {.items[*][‘metadata.name’, ‘status.capacity’]} | 127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8] |
?() | filter | {.users[?(@.name==“e2e”)].user.password} | secret |
range, end | iterate list | {range .items[*]}[{.metadata.name}, {.status.capacity}] {end} | [127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] |
“ | quote interpreted string | {range .items[*]}{.metadata.name}{’\t’}{end} | 127.0.0.1 127.0.0.2 |
使用jsonpath示例jsonp
kubectl get pods -o json kubectl get pods -o=jsonpath='{@}' kubectl get pods -o=jsonpath='{.items[0]}' kubectl get pods -o=jsonpath='{.items[0].metadata.name}' kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.startTime}{"\n"}{end}'
若是对象是集合类型,须要使用range关键字开始,以end关键字结果,同前面一节go-template相似.code
咱们经过如下示例来看如何经过jsonpath简单地获取到容器所在节点名称
[centos@k8s-master ~]$ kubectl get po consul-0 -ojsonpath='{..nodeName}' k8s-node1 [centos@k8s-master ~]$
固然以上也能够经过grep来获取到一样的信息,而且对于不少熟悉linux命令的童鞋来讲更为方便,若是仅仅是查看.grep确实更为方便,可是经过jsonpath是准确地获取到了一个属性的值,而grep则是截取的包含这个关键字的一行,若是咱们要把获取的值做为下一个命令的的输入值时,经过grep获取的结果每每是须要处理的.例如经过grep获取到的结果以下
"k8s-node1",[centos@k8s-master ~]$ kubectl get po consul-0 -ojson|grep nodeName "nodeName": "k8s-node1",
这里想要准备的获取结果,产生要截取第二列值,而后再去掉引号,操做起来不如jsonpath方便.尤为在不一样环境若是输出的格式不同的话,经过字符串截取获得的结果多是错误的.