从主机连接到 docker-compose 介导的 docker 内的 python 套接字
Connect to a python socket inside a docker-compose mediated docker from host
我正在尝试在 docker 中创建一个 python 套接字,并将该端口转发到它的主机,到其他一些程序应该尝试连接的地方。
为此,dockerised 运行 python 正在执行以下操作:
# Python 3.8, inside docker
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 5000))
while True:
message, addrs = s.recvfrom(1480)
_log(f"DATA RECIEVED from {addrs}") # arbitrary logging function
由于其他程序事先不知道将为 dockers 网络确定哪个 ip 范围,我必须信任 docker 的端口通信。所以,我想要实现的是,当主机收到任何在其 5000 端口上进行连接的套接字时,它将被 dockerised python.
选中
服务器和docker化图像都是ubuntus。主机在本地网络的ip是192.168.1.141,docker子网在172.18.0.0,docker-compose for docker本身如下:
docker-compose file
version: "3"
services:
my_docker:
container_name: python_socket
image: registry.gitlab.com/my_group/my_project:latest
volumes:
- ./configs:/configs
- ./logs:/configs/logs
- ./sniffing:/app/sniffing
ports:
- "5000:5000"
- "3788:3788"
- "3787:80"
networks:
- app_network
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- rabbitmq
- backend
restart: always
networks:
app_network:
使用此配置,我无法连接。我已经看到,在主机中,如果我启动 Ipython 并尝试以下操作:
# Python 3.8, ipython console
data = "Hello"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('172.18.0.2', 5000))
s.send(data.encode())
然后此信息成功到达 docker。但是如果我尝试连接到 0.0.0.0:5000、localhost:5000 或 192.168.1.141:5000,那么我只会收到连接错误。 docker 也正在从机器外部获取信息。
我错过了什么?我在 docker 端口转发成功的地方配置了 web 服务器。
提前感谢您的宝贵时间和帮助。
您正在创建 UDP 套接字 (SOCK_DGRAM
)。 Compose ports:
is somewhat quiet on this feature, but the general Container networking 概述意味着端口转发默认为 TCP。
您可以明确指定您需要转发一个 UDP 端口:
ports:
- '5000:5000/udp'
然后您可以连接到主机的 DNS 或 IP 地址(或 localhost
或 127.0.0.1,如果您从容器外部但在同一主机上调用)和第一个端口号 5000。不要查找容器私有 IP 地址;这是不必要的,在大多数情况下都不起作用。
我正在尝试在 docker 中创建一个 python 套接字,并将该端口转发到它的主机,到其他一些程序应该尝试连接的地方。
为此,dockerised 运行 python 正在执行以下操作:
# Python 3.8, inside docker
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 5000))
while True:
message, addrs = s.recvfrom(1480)
_log(f"DATA RECIEVED from {addrs}") # arbitrary logging function
由于其他程序事先不知道将为 dockers 网络确定哪个 ip 范围,我必须信任 docker 的端口通信。所以,我想要实现的是,当主机收到任何在其 5000 端口上进行连接的套接字时,它将被 dockerised python.
选中服务器和docker化图像都是ubuntus。主机在本地网络的ip是192.168.1.141,docker子网在172.18.0.0,docker-compose for docker本身如下:
docker-compose file
version: "3"
services:
my_docker:
container_name: python_socket
image: registry.gitlab.com/my_group/my_project:latest
volumes:
- ./configs:/configs
- ./logs:/configs/logs
- ./sniffing:/app/sniffing
ports:
- "5000:5000"
- "3788:3788"
- "3787:80"
networks:
- app_network
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- rabbitmq
- backend
restart: always
networks:
app_network:
使用此配置,我无法连接。我已经看到,在主机中,如果我启动 Ipython 并尝试以下操作:
# Python 3.8, ipython console
data = "Hello"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('172.18.0.2', 5000))
s.send(data.encode())
然后此信息成功到达 docker。但是如果我尝试连接到 0.0.0.0:5000、localhost:5000 或 192.168.1.141:5000,那么我只会收到连接错误。 docker 也正在从机器外部获取信息。
我错过了什么?我在 docker 端口转发成功的地方配置了 web 服务器。
提前感谢您的宝贵时间和帮助。
您正在创建 UDP 套接字 (SOCK_DGRAM
)。 Compose ports:
is somewhat quiet on this feature, but the general Container networking 概述意味着端口转发默认为 TCP。
您可以明确指定您需要转发一个 UDP 端口:
ports:
- '5000:5000/udp'
然后您可以连接到主机的 DNS 或 IP 地址(或 localhost
或 127.0.0.1,如果您从容器外部但在同一主机上调用)和第一个端口号 5000。不要查找容器私有 IP 地址;这是不必要的,在大多数情况下都不起作用。