通过jq帮你解决k8s过滤信息的痛点

194 阅读1分钟

jq基本使用

可以参考:alingse.github.io/jq-manual-c…

# 使用.$name 来获取指定filed
$ echo '{"Name":"CloudNativeOps","Owner":"GoOps"}' | jq .Owner
$ echo '{"Skills": [{"name":"Python","type":"dev" }, {"name":"Golang","type":"dev" }]}' | jq .Skills[0].name
# 列表迭代
$ echo '{"Skills": [{"name":"Python","type":"dev" }, {"name":"Golang","type":"dev" }]}' | jq .Skills[0:2]
# 使用 管道符号 | 对结果进行再次处理,注意需要把jq语句用引号包起来
$ echo '{"Skills": [{"name":"Python","type":"dev" }, {"name":"Golang","type":"dev" }]}' | jq '.Skills[] | .name'
# 使用 分号 ; 表示分隔两个表达式,类似于管道符号

# select对数值计算选择
$ echo '{"num":18}' | jq 'select(.num > 10) | .num'
18
# map对每个元素操作
$ echo '{"num":[18,9,22]}' | jq '.num | map(select(. > 10))'
[
  18,
  22
]

# ==、!= 相等
select(.spec.template.spec.containers[].image == "myimage:mytag")
# contains 包含
select(.spec.template.spec.containers[].image | contains("myimage:mytag"))
# fromdate 格式化时间戳
{name: .metadata.name, creationTime: (.metadata.creationTimestamp | fromdate)}

kubectl结合jq来过滤想要的信息

apiVersion: v1
items: 
  status:
    containerStatuses:
    - containerID: docker://da9bf80ada177b07bd85e90ac043ecab3ff79d56418eadbb6b86d3f02329f298
      name: train-job
      ready: false
      restartCount: 0
      state:
        terminated:
          containerID: docker://da9bf80ada177b07bd85e90ac043ecab3ff79d56418eadbb6b86d3f02329f298
          exitCode: 1
          finishedAt: "2024-01-15T16:44:35Z"
          reason: Error
          startedAt: "2024-01-15T16:44:23Z"

找出状态为Error且超过180天的Pod

# 15552000 = 180天
# 7776000 = 90天
sudo kubectl get po -n test -o json | \
jq -r '.items[] | select(.status.containerStatuses != null) | select(any(.status.containerStatuses[]; .state.terminated.reason == "Error")) | select((now - (.metadata.creationTimestamp | fromdate)) > 15552000) | .metadata.name'
# .items[] 获取items的所有元素
# select(.status.containerStatuses != null) 选择containerStatuses不为空的
# select(any(.status.containerStatuses[]; .state.terminated.reason == "Error"))
#          一、.status.containerStatuses[]; .state.terminated.reason == "Error" 分号 ; 用于分隔两个不同的表达式,其先选择containerStatuses的所有元素,再对reason做判断
#        二、 any() 满足返回true,不满足返回false
#   三、选择true
# select((now - (.metadata.creationTimestamp | fromdate)) > 15552000) 再选择now - creationTimestamp 大于15552000的
# .metadata.name' 最后只输出name

sed ':a;N;$!ba;s/\n/|/g' errorpod
cat errorpod  |xargs -I {} sudo kubectl delete po {} -n test

找出状态为Completed且超过180天的Pod

sudo kubectl get po -n test -o json | \
jq -r '.items[] | select(.status.containerStatuses != null) | select(any(.status.containerStatuses[]; .state.terminated.reason == "Completed")) | select((now - (.metadata.creationTimestamp | fromdate)) > 15552000) | .metadata.name'

返回每个命名空间的 Pod 名称列表

kubectl get pods --all-namespaces -o json | jq '[.items | group_by(.metadata.namespace)[] | {namespace: (.[0].metadata.namespace), pods: map(.metadata.name)}]'

更多用例会定期更新