![如何使用 jq 组合两个 JSON 对象](https://linux22.com/image/214045/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20jq%20%E7%BB%84%E5%90%88%E4%B8%A4%E4%B8%AA%20JSON%20%E5%AF%B9%E8%B1%A1.png)
我有两个文件:kube-apiserver.json
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
[...]
},
"spec": {
"containers": [
{
"command": [
"kube-apiserver",
"--advertise-address=192.168.49.2",
"--allow-privileged=true",
"--authorization-mode=Node,RBAC",
"--client-ca-file=/var/lib/minikube/certs/ca.crt",
"--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota",
"--enable-bootstrap-token-auth=true",
"--etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt",
"--etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt",
"--etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key",
"--etcd-servers=https://127.0.0.1:2379",
"--kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt",
"--kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key",
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
"--proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt",
"--proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key",
"--requestheader-allowed-names=front-proxy-client",
"--requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt",
"--requestheader-extra-headers-prefix=X-Remote-Extra-",
"--requestheader-group-headers=X-Remote-Group",
"--requestheader-username-headers=X-Remote-User",
"--secure-port=8443",
"--service-account-issuer=https://kubernetes.default.svc.cluster.local",
"--service-account-key-file=/var/lib/minikube/certs/sa.pub",
"--service-account-signing-key-file=/var/lib/minikube/certs/sa.key",
"--service-cluster-ip-range=10.96.0.0/12",
"--tls-cert-file=/var/lib/minikube/certs/apiserver.crt",
"--tls-private-key-file=/var/lib/minikube/certs/apiserver.key"
],
[...]
"volumeMounts": [
{
"mountPath": "/etc/ssl/certs",
"name": "ca-certs",
"readOnly": true
},
{
"mountPath": "/etc/ca-certificates",
"name": "etc-ca-certificates",
"readOnly": true
},
{
"mountPath": "/var/lib/minikube/certs",
"name": "k8s-certs",
"readOnly": true
},
{
"mountPath": "/usr/local/share/ca-certificates",
"name": "usr-local-share-ca-certificates",
"readOnly": true
},
{
"mountPath": "/usr/share/ca-certificates",
"name": "usr-share-ca-certificates",
"readOnly": true
}
]
}
],
[...]
"volumes": [
{
"hostPath": {
"path": "/etc/ssl/certs",
"type": "DirectoryOrCreate"
},
"name": "ca-certs"
},
{
"hostPath": {
"path": "/etc/ca-certificates",
"type": "DirectoryOrCreate"
},
"name": "etc-ca-certificates"
},
{
"hostPath": {
"path": "/var/lib/minikube/certs",
"type": "DirectoryOrCreate"
},
"name": "k8s-certs"
},
{
"hostPath": {
"path": "/usr/local/share/ca-certificates",
"type": "DirectoryOrCreate"
},
"name": "usr-local-share-ca-certificates"
},
{
"hostPath": {
"path": "/usr/share/ca-certificates",
"type": "DirectoryOrCreate"
},
"name": "usr-share-ca-certificates"
}
]
},
"status": {
[...]
}
}
和 patch.json
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
},
"spec": {
"containers": [
{
"command": [
"--audit-policy-file=/etc/kubernetes/audit-policy.yaml",
"--audit-log-path=/var/log/kubernetes/audit/audit.log"
],
"volumeMounts": [
{
"mountPath": "/etc/kubernetes/audit-policy.yaml",
"name": "audit",
"readOnly": true
},
{
"mountPath": "/var/log/kubernetes/audit/",
"name": "audit-log",
"readOnly": true
}
]
}
],
"volumes": [
{
"hostPath": {
"path": "/etc/kubernetes/audit-policy.yaml",
"type": "FileOrCreate"
},
"name": "audit"
},
{
"hostPath": {
"path": "/var/log/kubernetes/audit/",
"type": "DirectoryOrCreate"
},
"name": "audit-log"
}
]
},
"status": {
}
}
当我尝试执行jq -s '.[0] * .[1]' kube-apiserver.json patch.json > patched-apiserver.json
patch.json 中的项目时,会覆盖 kube-apiserver.json 中的项目,因此它看起来像这样:
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
[...]
"spec": {
"containers": [
{
"command": [
"--audit-policy-file=/etc/kubernetes/audit-policy.yaml",
"--audit-log-path=/var/log/kubernetes/audit/audit.log"
],
"volumeMounts": [
{
"mountPath": "/etc/kubernetes/audit-policy.yaml",
"name": "audit",
"readOnly": true
},
{
"mountPath": "/var/log/kubernetes/audit/",
"name": "audit-log",
"readOnly": true
}
]
}
],
[..].
"volumes": [
{
"hostPath": {
"path": "/etc/kubernetes/audit-policy.yaml",
"type": "FileOrCreate"
},
"name": "audit"
},
{
"hostPath": {
"path": "/var/log/kubernetes/audit/",
"type": "DirectoryOrCreate"
},
"name": "audit-log"
}
]
},
"status": {
[...]
}
}
我希望我的文件看起来像这样:
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
[...]
},
"spec": {
"containers": [
{
"command": [
"kube-apiserver",
"--advertise-address=192.168.49.2",
"--allow-privileged=true",
"--authorization-mode=Node,RBAC",
"--client-ca-file=/var/lib/minikube/certs/ca.crt",
"--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota",
"--enable-bootstrap-token-auth=true",
"--etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt",
"--etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt",
"--etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key",
"--etcd-servers=https://127.0.0.1:2379",
"--kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt",
"--kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key",
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
"--proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt",
"--proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key",
"--requestheader-allowed-names=front-proxy-client",
"--requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt",
"--requestheader-extra-headers-prefix=X-Remote-Extra-",
"--requestheader-group-headers=X-Remote-Group",
"--requestheader-username-headers=X-Remote-User",
"--secure-port=8443",
"--service-account-issuer=https://kubernetes.default.svc.cluster.local",
"--service-account-key-file=/var/lib/minikube/certs/sa.pub",
"--service-account-signing-key-file=/var/lib/minikube/certs/sa.key",
"--service-cluster-ip-range=10.96.0.0/12",
"--tls-cert-file=/var/lib/minikube/certs/apiserver.crt",
"--tls-private-key-file=/var/lib/minikube/certs/apiserver.key",
"--audit-policy-file=/etc/kubernetes/audit-policy.yaml",
"--audit-log-path=/var/log/kubernetes/audit/audit.log"
],
[...]
"volumeMounts": [
{
"mountPath": "/etc/ssl/certs",
"name": "ca-certs",
"readOnly": true
},
{
"mountPath": "/etc/ca-certificates",
"name": "etc-ca-certificates",
"readOnly": true
},
{
"mountPath": "/var/lib/minikube/certs",
"name": "k8s-certs",
"readOnly": true
},
{
"mountPath": "/usr/local/share/ca-certificates",
"name": "usr-local-share-ca-certificates",
"readOnly": true
},
{
"mountPath": "/usr/share/ca-certificates",
"name": "usr-share-ca-certificates",
"readOnly": true
},
{
"mountPath": "/etc/kubernetes/audit-policy.yaml",
"name": "audit",
"readOnly": true
},
{
"mountPath": "/var/log/kubernetes/audit/",
"name": "audit-log",
"readOnly": true
}
]
}
],
[...]
"volumes": [
{
"hostPath": {
"path": "/etc/ssl/certs",
"type": "DirectoryOrCreate"
},
"name": "ca-certs"
},
{
"hostPath": {
"path": "/etc/ca-certificates",
"type": "DirectoryOrCreate"
},
"name": "etc-ca-certificates"
},
{
"hostPath": {
"path": "/var/lib/minikube/certs",
"type": "DirectoryOrCreate"
},
"name": "k8s-certs"
},
{
"hostPath": {
"path": "/usr/local/share/ca-certificates",
"type": "DirectoryOrCreate"
},
"name": "usr-local-share-ca-certificates"
},
{
"hostPath": {
"path": "/usr/share/ca-certificates",
"type": "DirectoryOrCreate"
},
"name": "usr-share-ca-certificates"
},
{
"hostPath": {
"path": "/etc/kubernetes/audit-policy.yaml",
"type": "FileOrCreate"
},
"name": "audit"
},
{
"hostPath": {
"path": "/var/log/kubernetes/audit/",
"type": "DirectoryOrCreate"
},
"name": "audit-log"
}
]
},
"status": {
[...]
}
}
有谁知道如何用 jq/python/bash/whatever 解决它?