Kubernetes集群内两个Flask容器REST API无法互相调用问题排查
问题排查与解决思路
你exec进入Pod内部可以正常调用http://deppredict:1080/predict,说明K8s的DNS解析、deppredict服务本身的连通性都是正常的,问题出在应用镜像配置或者代码的异常处理上。
必排查项
- 1. 确认镜像包含requests依赖
很多开发者打包镜像时会遗漏把requests写入requirements.txt,导致容器内运行代码时抛出导入错误,看起来和地址不可达的报错相似。你可以进入运行app.py的Pod,手动执行python3 -c "import requests"确认依赖是否正常安装。 - 2. 使用完整Service域名访问
如果两个Deployment不在同一个Namespace下,短服务名deppredict无法解析,需要使用K8s Service的完整FQDN格式:
如果你用的是默认default命名空间,访问地址应该写成http://<服务名>.<所在命名空间>.svc.cluster.local:<端口>http://deppredict.default.svc.cluster.local:1080。 - 3. 检查deppredict服务端口配置
执行kubectl get svc deppredict确认:- PORT(S)列的前端端口确实是1080
- 创建Service时指定的
targetPort和deppredict服务容器内Flask实际监听的端口一致(很多人Flask默认跑5000端口,expose时没有指定targetPort=5000会导致转发失败)
- 4. 确认Flask绑定地址为0.0.0.0
两个Flask服务的启动代码必须指定host="0.0.0.0",如果绑定的是127.0.0.1,只能容器本地访问,Service转发的请求会被拒绝,示例:if __name__ == '__main__': app.run(host="0.0.0.0", port=容器监听端口) - 5. 增加异常打印定位具体问题
你当前的代码没有错误处理,无法区分是域名解析失败、连接超时还是服务返回错误,修改成如下版本打印具体报错:
改完后重新打包镜像发布,执行import requests from flask import Flask import traceback app = Flask(__name__) @app.route("/testpredict", methods=["POST"]) def testpredict(): try: response = requests.post(url="http://deppredict.default.svc.cluster.local:1080/predict", timeout=5) return response.text, 200 except Exception as e: print(f"调用失败原因:{str(e)}") print(traceback.format_exc()) return f"调用失败:{str(e)}", 500kubectl logs <你的app.py所在Pod名>就能看到具体的错误原因。
内容的提问来源于stack exchange,提问作者Doudda
相关产品推荐
相关产品推荐

