【说明】
(1)本篇讲解kubectl get命令的输出格式化,即-o jsonpath=参数的使用格式(-o jsonpath= 与 -ojsonpath= 与 -o=jsonpath= 与 --output=jsonpath= 四者写法不一样,效果一样)
(2)官网:https://kubernetes.io/zh-cn/docs/reference/kubectl/jsonpath/
1. jsonpath语法讲解
python
jsonpath是一种用于从json数据中提取数据的查询语言,通过jsonpath表达式从json数据中选择和提取数据,jsonpath表达式就是由一系列操作符和表达式组成的
【jsonpath表达式的基本操作符】
(1)$ 根节点
(2)@ 当前节点,一般用于【子表达式】或者【过滤表达式】
(3). 或 [] 用于连接父节点, .点要求value本身是一个json对象才可以进行往下连接。
[] 也可以用于连接父节点,语法:$["data"]["studnet"]、$["name"] 等价于 $.name
【示例】
$.name则表示提取根节点下的name节点的值
$.data.student则表示提取根节点下的data节点下的student数组的值(student假设是一个数组的话则返回整个数组)
$.data.student[0]则表示提取根节点下的data节点下的student数组中的第1个值(student是一个数组的话则返回整个数组中第1个值)
$.data.student[0].name则表示提取根节点下的data节点下的student数组中的第1个值的name值
(4)*号 通配符星号表示所有
【示例】
$.* 表示提取根节点下的所有节点的值
$.data.student[*].name则表示提取根节点下的data节点下的student数组中的所有节点的name值
(5).. 表示深层递归
【示例】
$.name表示提取根节点下的name节点的值
$..name则表示提取根节点及其下所有子节点中的name节点的值(递归提取)
$.data..name则表示提取data节点及其data节点下边的所有节点的name节点的值(递归提取data节点所有name节点值)。
针对数组节点的处理:
一般来说,整对数组节点的提取,我们主要采用的方式有这么几种:【下标提取】、【过滤表达式】
【下标提取】又可以有3个方式,如下:
(1)提取单个元素:【语法】array[index] --> 表示提提数组中指定的index下标的值
(2)枚举方式:【语法】array[index1,index2,index3] --> 表示同时提取数组中的多个index下标元素值,使用逗号分隔index即可
(3)分片:【语法】array[start:end] --> 表示提取数组中半闭半开区间的值,即包含start,不包含end的下标元素值,start可以省略,省略时默认是0,end亦可省略,省略时默认是最后一个index下标
【示例】:
$.data.student[0] 提取student数组中第1个元素的值
$.data.student[1] 提取student数组中第2个元素的值
$.data.student[0,3] 提取student数组中第1个元素和第4个元素的值
$.data.student[*] 使用*号通配符表示提取student数组中全部元素的值
$.data.student[0:3] 提取student数组中[0,3)元素的值,换句话说就是012元素的值,不含元素3的值
$.data.student[:3] 省略start,start默认是0,则等价于$.data.student[0:3]
$.data.student[1:] 省略end,则表示到最后一个index,即提取数组中从下标1开始到最后一个元素的值
【过滤表达式】:对于复杂的业务需求,可以通过过滤表达式对数组中的元素进行过滤。
==、!=、<、<=、>、>= 等于、不等于、小于、小于等于、大于、大于等于
=~ 正则匹配
in 存在于
nin 不存在于
subsetof 子集
|| 或
&& 与
基本格式:$.data.studnet[?(表达式)]
@表示正在处理的当前节点
【示例】:
$.data.studnet[?(@.isVIP==true)] 提取data节点下student节点下isVIP=true的元素
$.data.studnet[?(@.isVIP==true)].name 提取data节点下student节点下isVIP=true的元素的name值
$.data.studnet[?(@.age>=20)] 提取data节点下student节点下年龄大于20的元素
$.data.studnet[?(@.age>=20 && @.sex=="man")] 提取data节点下student节点下年龄大于等于20并且性别是男生的元素
$.data.studnet[?(@.age==20 || @.age==25 )] 等价于 $.data.studnet[?(@.age in [20,25])]
$.data.studnet[?(@.age nin [20,25])]
2. kubectl get命令
python
Usage:
kubectl get
[(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...]
(TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags] [options]
Use "kubectl options" for a list of global command-line options (applies to all commands).
3. -o jsonpath= 讲解
jsonpath模板由 {} 包起来的 jsonpath表达式组成。kubectl 使用 jsonpath表达式来过滤 json对象中的特定字段并格式化输出。
kubectl 的 jsonpath 输出不支持正则表达式
3.1 测试数据
python
[root@k8s-node-32 ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master-31 Ready master 683d v1.17.9 192.168.20.31 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.12
k8s-node-32 Ready node 683d v1.17.9 192.168.20.32 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.12
k8s-node-33 Ready node 683d v1.17.9 192.168.20.33 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.12
vm.k8s-master-31 Ready <none> 683d v1.16.2 192.168.20.31 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 QEMU-KVM://4.2.0
vm.k8s-node-32 Ready <none> 683d v1.16.2 192.168.20.32 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 QEMU-KVM://4.2.0
vm.k8s-node-33 Ready <none> 683d v1.16.2 192.168.20.33 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 QEMU-KVM://4.2.0
3.2 提取单个元素
python
# 获取根节点下items数组中第1个元素的metadata节点下的name的值
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[0].metadata.name}"
k8s-master-31
# 获取根节点下items数组中第2个元素的metadata节点下的name的值
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[1].metadata.name}"
k8s-node-32
# 获取根节点下items数组中第3个元素的metadata节点下的name的值
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[2].metadata.name}"
k8s-node-33
# 获取根节点下items数组中所有元素的metadata节点下的name的值
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[*].metadata.name}"
k8s-master-31 k8s-node-32 k8s-node-33 vm.k8s-master-31 vm.k8s-node-32 vm.k8s-node-33
# 获取根节点下items数组中所有元素下status节点下capacity节点下的availPhysicalMemory值
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[*].status.capacity.availPhysicalMemory}"
39946Mi 125171Mi 32497Mi
3.2 枚举元素
python
# 同时获取多个值,使用['n1','n2',..]即可
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[*]['.metadata.name', '.status.capacity.availPhysicalMemory']}"
k8s-master-31 k8s-node-32 k8s-node-33 vm.k8s-master-31 vm.k8s-node-32 vm.k8s-node-33 39947Mi 125172Mi 32485Mi
3.3 分片
python
range, end 迭代列表
range, end 迭代列表可以进行常量的输出,还可以使用制表符换行符进行格式化,语法格式如下:
【语法格式】:{range .items[*]}{.metadata.name},{xxx},{xxx} {end}
-o jsonpath="{range .items[*]}{.metadata.name} {end}"
-o jsonpath="{range .items[*]}{.metadata.name}, {.status.capacity.availPhysicalMemory} {end}"
-o jsonpath="{range .items[*]}{.metadata.name}, {.status.capacity.availPhysicalMemory}{'\n'}{end}"
# 输出容器名字和容器容量,并使用制表符换行符进行格式化
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.status.capacity.availPhysicalMemory}{'\n'}{end}"
k8s-master-31
k8s-node-32
k8s-node-33
vm.k8s-master-31 39Gi
vm.k8s-node-32 125166Mi
vm.k8s-node-33 32487Mi
#{end}前面没有空格,输出结果都连接到一起了
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}{end}"
k8s-master-31k8s-node-32k8s-node-33vm.k8s-master-31vm.k8s-node-32vm.k8s-node-33
#{end}前面加了个空格
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name} {end}"
k8s-master-31 k8s-node-32 k8s-node-33 vm.k8s-master-31 vm.k8s-node-32 vm.k8s-node-33
#同时输出容器name和容器IP
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}, {.status.capacity.availPhysicalMemory} {end}"
k8s-master-31, k8s-node-32, k8s-node-33, vm.k8s-master-31, 39888Mi vm.k8s-node-32, 125141Mi vm.k8s-node-33, 32499Mi
#使用换行符美化结果
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}, {.status.capacity.availPhysicalMemory}{'\n'}{end}"
k8s-master-31,
k8s-node-32,
k8s-node-33,
vm.k8s-master-31, 39923Mi
vm.k8s-node-32, 125132Mi
vm.k8s-node-33, 32500Mi
#输出结果拼接其他信息
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{range .items[*]}avail:{.status.capacity.availPhysicalMemory}{'\n'}{end}"
avail:
avail:
avail:
avail:39925Mi
avail:125138Mi
avail:32507Mi
3.4 过滤
对于kubectl get 过滤符合条件的有以下方式
python
【1】使用标签
[root@k8s-node-32 ~]# kubectl get nodes -l asState=active,cpuShared='1' -o jsonpath="{.items[*].metadata.name}"
vm.k8s-node-32
【2】使用grep
[root@k8s-node-32 ~]# kubectl get nodes -o jsonpath="{.items[*].metadata.name}" | grep node-32
k8s-node-32 vm.k8s-node-32
【3】使用过滤表达式
kubectl get vm -o jsonpath="{range .items[?(@.spec.nodeName=='vm.k8s-node-32')]}name={.metadata.name},status={.spec.powerstate}}{'\n'}{end}"