kubectl get -o jsonpath使用

【说明】

(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}"
相关推荐
让生命变得有价值5 天前
k8s 启用 ValidatingAdmissionPolicy 特性
java·容器·kubernetes·kubelet
SRExianxian2 个月前
kubelet组件的启动流程源码分析
云原生·kubelet
Mumunu-2 个月前
prometheus监控k8s1.24以上版本pod实时数据指标
kubernetes·prometheus·kubelet
misakivv2 个月前
CSI 插件如何注册到 kubelet 的
云原生·容器·kubernetes·kubelet
ghostwritten2 个月前
openshift node NotReady & kubelet http: TLS handshake error
http·openshift·kubelet
蟹黄堡㋡3 个月前
proxy负载均衡
运维·负载均衡·kubelet
菠萝炒饭pineapple-boss3 个月前
使用容器启动的kubelet无法使用subPathExpr
服务器·kubelet
富士康质检员张全蛋4 个月前
Kubelet 认证
云原生·kubernetes·kubelet
富士康质检员张全蛋4 个月前
Prometheus 监控Kubelet的运行状态
prometheus·kubelet
研究司马懿4 个月前
【云原生】MiniKube部署Kubernetes最小化集群
云原生·容器·kubernetes·minikube·k8s·kubelet·最小化集群