将K8s Deployment嵌套JSON插入MySQL JSON列失败排查
问题情况
用kubectl get deployment -o json depl_name拉取Kubernetes Deployment的JSON详情,往MySQL的meta_data JSON类型列插入时,报了这个错:
ERROR 3140 (22032): Invalid JSON text: "Missing a comma or '}' after an object member." at position 1035 in value for column
一开始怀疑是"message": "ReplicaSet \"wordpress-backend-abc123\" has successfully progressed."这行的转义引号搞的鬼,但删掉这行后问题还是存在。
问题根源
真正的问题出在metadata.annotations.kubectl.kubernetes.io/last-applied-configuration这个字段上——它本身是个已经转义过的JSON字符串,末尾还带了个换行符\n。MySQL的JSON解析器对这种内嵌的、带换行的转义内容兼容性不好,直接判定整个JSON结构无效。
解决办法
1. 用jq预处理JSON,清理换行符
直接用jq工具处理kubectl的输出,把内嵌JSON末尾的换行符去掉:
kubectl get deployment depl_name -o json | jq '.metadata.annotations."kubectl.kubernetes.io/last-applied-configuration" |= rtrimstr("\n")' > cleaned_deployment.json
处理完之后再把这个清理后的JSON插入MySQL就行。
2. 插入时用MySQL函数处理
要是不想预处理,也可以在插入语句里用MySQL的字符串函数直接处理有问题的字段:
INSERT INTO your_table (meta_data) VALUES (JSON_REPLACE( '你的完整JSON字符串', '$.uuid.demo[0].deployment_config.metadata.annotations."kubectl.kubernetes.io/last-applied-configuration"', REPLACE(JSON_UNQUOTE('你的完整JSON字符串'->'$.uuid.demo[0].deployment_config.metadata.annotations."kubectl.kubernetes.io/last-applied-configuration"'), '\n', '') ));
记得把your_table和你的完整JSON字符串换成你实际的表名和JSON内容。
3. 导出时直接排除这个注解字段
如果这个last-applied-configuration注解对你没用,干脆在导出的时候就删掉它:
kubectl get deployment depl_name -o json | jq 'del(.metadata.annotations."kubectl.kubernetes.io/last-applied-configuration")' > cleaned_deployment.json
验证是否有效
处理完的JSON可以用jq本地验证合法性:
jq . cleaned_deployment.json
如果没报错,说明JSON结构没问题,再插MySQL就不会出错了。
内容的提问来源于stack exchange,提问作者Santosh Kumar Sahoo

