在我的主机上通过主动连接连接到 ftp 工作正常。在 docker 容器中执行此操作则不行。被动在两者上都工作正常,但我需要支持这两种连接类型。
我发现这个简单的图像可以用来说明问题
主持人
容器(包括默认为主动模式的稍旧版本的 ftp)
我的问题是,其他人是否可以使用该图像通过主动连接成功连接?我不认为服务器是问题所在,因为就像我说的,这在主机上运行良好。
答案1
您可能想要了解主动模式和被动模式 ftp 的区别:
主动 FTP 和被动 FTP 有什么区别?
您可以看到,主动模式 ftp 不适合容器化的 ftp 客户端,因为服务器会主动尝试启动与 ftp 客户端的数据连接,而这对于容器来说是不可能的。
另一方面,使用被动模式 ftp,服务器将告诉您的 ftp 客户端下一个数据连接需要使用哪个端口。
Linux 方法
在容器中使用主动 ftp 的简单方法是使用network: host
,但这可能会产生不良影响:
docker run [other flags] --network host <image_name>
有关详细信息,请参阅 Docker 文档 网络概述。
此方法在 Linux 上非常有效,但在 Windows 上无效。下面介绍如何在 Windows 上执行此操作。
Windows 方法
这个方法是在帖子中找到的 使用 Docker for Windows 进行桥接。
首先,在 Docker 上创建自定义网络。示例:
docker network create -d bridge --subnet 172.168.0.0/16 mynet
与 Linux 不同,在 Linux 中新网络会自动桥接至 NIC,但在 Windows 中这是不可能的,因为 Hyper-V 不为 Linux 容器提供桥接选项。
在 Windows 中,要将容器设置为从自定义网络响应并使用自定义 IP,此特定 IP 地址必须存在于
Docker 网络适配器,通常称为vEthernet (DockerNAT)
。操作方法如下:
- 去控制面板 > 网络和 Internet > 网络连接
- 右键单击
vEthernet (DockerNAT)
并选择属性 - 选择
Internet Protocol Version 4(TCP/IPv4)
并单击属性 - 为适配器提供一个在真实网络上有效的静态 IP 地址。确保 DNS 对容器也有效,以便解析网络上的域 5,单击高级,然后单击添加,然后输入要包含在列表中的 IP。子网掩码应自动填充(但可以根据需要更改)。对您想要使用的每个 IP 重复此操作,根据需要从相同或不同的网络获取尽可能多的 IP。
完成此步骤后,自定义网络即可使用。
文章举了一个例子:
例如,尝试安装 Portainer 以从您的自定义网络运行。操作方法如下:
首先,创建所需的 Portainer 卷(仅在 Windows 上才需要此步骤):
docker volume create portainer_data
然后使用以下命令创建 Portainer 容器:
docker run -d -p 9000:9000 --name portainer --network mynet --ip 172.168.0.254 --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data
波泰纳
注意到关键字
--network
和了--ip
吗?你甚至可以在 hosts 文件中设置一个自定义本地域(例如,docker.local),指向 IP 地址 172.168.0.254,这将允许你通过以下方式访问本地 Portainerhttp://docker.local:9000(或者 http://172.168.0.254:9000)。
Mac 方法
根据 Docker 文档文章 使用主机网络:
主机网络驱动程序仅适用于 Linux 主机,不支持 Mac 版 Docker Desktop、Windows 版 Docker Desktop 或 Windows Server 版 Docker EE。
您还可以通过传递给命令将
host
网络用于 Swarm 服务 。在这种情况下,控制流量(与管理 Swarm 和服务相关的流量)仍通过覆盖网络发送,但各个 Swarm 服务容器使用 Docker 守护进程的主机网络和端口发送数据。这会产生一些额外的限制。例如,如果服务容器绑定到端口 80,则只有一个服务容器可以在给定的 Swarm 节点上运行。--network host
docker service create
另请参阅帖子 从docker容器内访问主机。