如何使用jq Filter移除包含指定列表元素的字段值?
解决jq中基于内部数组包含匹配过滤并移除元素的问题
问题背景
需要筛选出仍从Docker Hub拉取镜像的K8s Pod,但要排除指定命名空间的Pod,同时移除镜像列表中包含特定关键词(如istio、私有仓库地址)的项;如果处理后images或initImages数组为空,则移除整个Pod对象。
输入的Pod JSON数据示例:
{ "namespace": "namespace1", "name": "some-pod1", "images": [ "acr1.azurecr.io/some_project/some_project_image@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc" ], "initImages": [ "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc" ] } { "namespace": "namespace1", "name": "some-pod2", "images": [ "acr1.azurecr.io/some_project/some_project_image@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc" ], "initImages": [ "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc" ] }
之前的命令无法正确移除包含$excludedImages元素的镜像,原因是contains()函数不支持直接传入数组,需要遍历数组元素做包含匹配。
解决方案
使用以下jq命令可以实现需求:
jq ' ["kube-system", "kube-public", "gatekeeper-system", "istio-system", "istio-operator"] as $excludedNamespaces | ["istio", "registry.k8s", "mcr.microsoft.com", "azurecr.io"] as $excludedImages # 过滤掉排除列表中的命名空间 | select(.namespace | IN($excludedNamespaces[]) | not) # 筛选出initImages或images中包含docker.io的Pod | select((.initImages[] | contains("docker.io")) or (.images[] | contains("docker.io"))) # 清理images数组:移除包含$excludedImages中任意关键词的镜像 | .images |= [.[] | select(any($excludedImages[]; . contains $item) | not)] # 清理initImages数组:同上逻辑 | .initImages |= [.[] | select(any($excludedImages[]; . contains $item) | not)] # 移除images和initImages都为空的Pod | select(.images != [] or .initImages != []) ' pods.json
命令解释
- 定义变量:将排除的命名空间和镜像关键词存入变量,方便后续统一修改维护。
- 过滤命名空间:用
IN()函数精确匹配排除的命名空间,保留不在列表中的Pod。 - 筛选目标Pod:只保留
initImages或images中包含docker.io的Pod,确保只处理从Docker Hub拉取镜像的对象。 - 清理镜像数组:使用
any()遍历$excludedImages中的每个关键词,判断当前镜像是否包含任意关键词,保留不匹配的镜像项。这里用|=操作符直接修改原数组。 - 过滤空数组Pod:如果处理后
images和initImages都为空,说明该Pod没有需要关注的镜像,直接移除。
内容的提问来源于stack exchange,提问作者termil0r
相关产品推荐
相关产品推荐

