1.Bug描述
今天将一个服务器上写的Flask API服务重新用docker部署到另一台服务器上时,出现以下报错
File "/app/deeplab_client_trimap.py", line 32, in call
result = stub.Predict(request, 600.0)
File "/usr/local/lib/python3.6/dist-packages/grpc/_channel.py", line 562, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/usr/local/lib/python3.6/dist-packages/grpc/_channel.py", line 466, in _end_unary_response_blocking
raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "Connect Failed"
debug_error_string = "{"created":"@1558950972.886258245","description":"Failed to create subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":2715,"referenced_errors":[{"created":"@1558950972.886236548","description":"failed to connect to all addresses","file":"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc","file_line":456,"referenced_errors":[{"created":"@1558950972.886169280","description":"Connect Failed","file":"src/core/ext/filters/client_channel/subchannel.cc","file_line":963,"grpc_status":14,"referenced_errors":[{"created":"@1558950972.886090944","description":"Failed to connect to remote host: FD Shutdown","file":"src/core/lib/iomgr/lockfree_event.cc","file_line":194,"os_error":"Timeout occurred","referenced_errors":[{"created":"@1558950972.886067930","description":"connect() timed out","file":"src/core/lib/iomgr/tcp_client_posix.cc","file_line":119}],"target_address":"ipv4:172.17.0.1:9007"}]}]}]}"
我的Flask API服务由一个在另一个docker容器中TensorFlow Serving提供,通过与另一个服务器交叉调用可知我的TensorFlow服务和Flask服务都没有问题,问题出在同一个宿主机内的两个docker容器内通过端口调用的问题。
我通过Telnet也不能连接,连接结果如下
root@ad61e690f271:/etc/network# telnet 127.0.0.1 9007
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
2.解决办法
在Linux上宿主机上运行Docker时,您可以使用docker0接口的IP地址访问主机服务。从容器内部,这将是您的默认路由。在宿主机查看默认路由地址:
root@ubun:~/flask# ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:96:ab:b7:38 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:96ff:feab:b738/64 scope link
valid_lft forever preferred_lft forever
进入容器内安装iproute2包
root@ad61e690f271:/app# apt-get install iproute2
在容器内查看路由ip
root@ad61e690f271:/app# ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3
root@ad61e690f271:/app# read escape sequence
进入宿主机,修改主机上的iptables规则以允许来自Docker容器的连接:
root@ubun:~/flask# iptables -A INPUT -i docker0 -j ACCEPT
这将允许从Docker容器访问宿主机上的任何端口。
3.参考文献
How to access host port from docker container
docker 容器无法连接宿主机服务