当我使用“kubectl patch”删除数组中的特定对象时,我需要首先检查该特定对象的索引,然后使用 json/yaml 路径执行 kubectl patch。
例如,我有一个资源包含多个端口对象:
spec:
clusterIP: 100.12.143.76
externalTrafficPolicy: Cluster
ports:
- name: object1
nodePort: 30681
port: 1234
protocol: TCP
targetPort: 1234
- name: object2
nodePort: 31805
port: 9876
protocol: TCP
targetPort: 9876
如果我需要删除端口中的“object1”,这是我现在使用的命令(kong-proxy 是该服务资源的名称):
kubectl patch service kong-proxy --type=json -p='[{"op": "remove", "path": "/spec/ports/0"}]' -n kong
通过执行上面的命令,它会删除索引“0”处名为“object1”的对象。
但这需要人提前知道正确的索引号,如果数组中的对象太多,将很难管理和计算索引。
因此我想知道在不编写单独的 bash 脚本的情况下,有没有一种方法可以删除其中带有标识符的对象。
如:
kubectl patch service kong-proxy --type=json -p='[{"op": "remove", "path": "/spec/ports/{name:object1}"}]' -n kong
恐怕这是不可能的。
kubectl patch --type=json
命令在底层使用 JSON Patch,而后者又使用 JSON Pointer。 JSON Pointer 标准非常简单,不提供过滤/匹配功能。
您可以做的解决方法是在调用 kubectl patch
之前使用
jq查找数组索引:
INDEX=$(kubectl get svc kong-proxy -n kong -o json | jq '.spec.ports | map(.name == "object1") | index(true)')
kubectl patch svc kong-proxy --type=json -p="[{'op': 'remove', 'path': '/spec/ports/$INDEX'}]" -n kong
对于任何偶然发现这篇文章的人,不要使用补丁命令,请尝试以下操作:
kubectl get <resource> <resource-name> -o json | jq 'del(.<path-to-array>.<array-name>[] | select(."<field-name>"=="<field-value>"))' | kubectl apply -f -
将“<>”内的所有内容替换为适当的值。
说明:
首先获取资源的json输出,然后使用jq内联修改输出(删除数组元素),最后直接应用新形成的json。
编辑:
如果数组元素没有键/字段来选择它们,请使用此方法:
kubectl get <resource> <resource-name> -o json | jq ".<path-to-array>.<array-name> -= [\"<value-to-delete>\"]" | kubectl apply -f -