【问题标题】:TCP/Telnet from inside docker container来自 docker 容器内的 TCP/Telnet
【发布时间】:2021-07-09 22:29:12
【问题描述】:

我有一个 'mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim' Docker 容器,上面有 2 个东西: - 在其上运行的自定义 SDK - 一个通过 TCP 连接到 SDK 的 dotnet5 应用程序

如果我连接了 Docker 的 bash,我可以使用 telnet localhost 54321 成功连接到我的 SDK

如果我在我的开发计算机 (Windows) 上运行 Windows SDK 版本,并运行我的应用程序 IIS Express 而不是 Docker,我可以成功连接到 telnet 库(主机“localhost”,端口“54321”),这作品

但是,我想在 Docker 容器中运行 SDK 和我的 dotnet 应用程序,当我尝试从容器内部连接时(与 IIS 托管版本相同),这不起作用。通过从 docker 容器命令行运行“telnet localhost 54321”,我可以确认 SDK 正在运行。我做错了什么?

Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base

RUN apt-get update && apt-get install -y telnet
RUN apt-get update && apt-get install -y libssl1.1
RUN apt-get update && apt-get install -y libpulse0
RUN apt-get update && apt-get install -y libasound2
RUN apt-get update && apt-get install -y libicu63
RUN apt-get update && apt-get install -y libpcre2-16-0
RUN apt-get update && apt-get install -y libdouble-conversion1
RUN apt-get update && apt-get install -y libglib2.0-0


RUN mkdir /sdk

COPY ["Server/Sdk/SomeSDK*", "sdk/"]

WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Server/MyProject.Server.csproj", "Server/"]
COPY ["Shared/MyProject.Shared.csproj", "Shared/"]
COPY ["Client/MyProject.Client.csproj", "Client/"]
RUN dotnet restore "Server/MyProject.Server.csproj"
COPY . .
WORKDIR "/src/Server"
RUN dotnet build "MyProject.Server.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MyProject.Server.csproj" -c Release -o /app/publish

FROM base AS final

WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProject.Server.dll"]

代码(在 IIS 上工作,当 SDK 在 Windows 上运行时,但当 SDK 和代码都在同一个 Docker 容器中运行时):

var telnetClient = new TelnetClient("localhost", 54321, TimeSpan.FromSeconds(1), new CancellationToken());
await telnetClient.Connect();
Thread.Sleep(2000);
await telnetClient.Send("init");

命令行(在 Windows CLI 和 Docker bash 中都可以使用(所以当代码不工作时,它也可以工作):

$telnet localhost 54321
$init

问题可能是(但我不确定,因为我从 dotnet 中使用直接命令行 '$telnet localhost 54321' 收到此结果:'telnet:远程主机拒绝连接'

【问题讨论】:

  • 请检查容器中是否开启Telnet:dism /online /Enable-Feature /FeatureName:TelnetClient
  • 这两个部分是在一个容器中运行,还是在两个单独的容器中运行,或者一个在一个容器中而一个不在? SDK组件的网络监听器是如何配置的(监听什么地址和端口)?
  • @markus 我会检查并回复你,但 telnet 在 Docker 容器内的命令行中工作,所以我认为它可以工作
  • @David 都在同一个容器内。 SDK 监听 54321 端口上的 TCP 连接
  • 请将您的运行语句合并为一个语句

标签: docker .net-core


【解决方案1】:

如果您想离开容器或使用--network=bridge(例如使用另一个容器)创建网桥,请确保在您的docker run 命令中也使用--network=host 以使用相同的网络。

默认情况下,Docker 容器在您机器上的一个单独、专用和私有子网(主要是 172.17.0.0/16)上生成,该子网不同于您机器的默认/本地子网(127.0.0.0/8)。

在这种情况下,要连接到主机的子网127.0.0.0/8,您需要--network=host。用于在同一个容器内进行通信,虽然这不是必需的,而且开箱即用。

要从外部访问容器中的服务,您需要确保使用--publish HOST_PORT:DOCKER_PORT--publish-all 发布应用程序的端口(然后分配主机上的随机端口,请使用docker ps 检查) .

主机到容器(正常)

# host
telnet <container's IP> 8000  # connects, typing + return shows in netcat stdout

# container
docker run --rm -it --publish 8000:8000 alpine nc -v -l -p 8000

容器到主机(正常)

# host
nc -v -l -p 8000

# container, docker run -it alpine
apk add busybox-extras
telnet localhost 8000  # hangs, is dead

容器到主机(在主机网络上)

# host
nc -v -l -p 8000

# container, docker run -it --network=host alpine
apk add busybox-extras
telnet localhost 8000  # connects, typing + return shows in netcat stdout

容器内

# start container
docker run -it --name alpine alpine
apk add busybox-extras

# exec into container to create service on 4000
docker exec -it alpine nc -v -l -p 4000

# exec into container to create service on 5000
docker exec -it alpine nc -v -l -p 5000

# telneting from the original terminal (the one with apk add)
telnet localhost 4000  # connects, works 
telnet localhost 5000  # connects, works

【讨论】:

  • 只是为了确保我理解正确 - 两个应用程序都在同一个 docker 容器中运行。这仍然适用吗?
  • 是的,如果您想从主机或其他子网访问它们,您需要直接使用主机的网络或使用网桥。
  • 您通常不需要主机网络,如果您使用桥接网络,您通常不需要查找容器专用 IP 地址。这些东西都不能在 Windows 主机上运行。
  • 您有一个同时运行 SDK 和 dotnet 应用程序的容器,对吗?当您使用 localhost 进行容器内连接时,应该没有任何问题。我们可以看看 Dockerfile 吗?另一方面,容器应该有单一的责任,所以如果他们通过 TCP 连接,最好将 SDK 和应用程序分开(虽然我不知道你的用例,所以它可能对你的情况有意义)最后是你使用窗户? Windows 容器网络搞砸了
  • 我没有投反对票,我不知道为什么。两者都在同一个容器中运行。 @Yamuk 我将在一小时内添加 Docker 文件。关于你的另一点,我有业务限制,这使得这样做是必要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 2019-03-07
相关资源
最近更新 更多