【问题标题】:Docker container port 6002 connection refusedDocker 容器端口 6002 连接被拒绝
【发布时间】:2019-09-06 00:33:47
【问题描述】:

操作系统:Docker for Windows。 操作系统类型:linux。 架构:x86_64

我有一个在 Docker 容器中运行的 ASP.NET 核心 Web 应用程序。下面是我的 Dockerfile。

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 6002

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["AdvPersonApi.csproj", "AdvPersonApi/"]
RUN dotnet restore "AdvPersonApi/AdvPersonApi.csproj"
COPY . ./AdvPersonApi/
WORKDIR "/src/AdvPersonApi"
RUN dotnet build "AdvPersonApi.csproj" -c Release -o /app

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
EXPOSE 6002
ENTRYPOINT ["dotnet", "AdvPersonApi.dll"]

应用程序构建成功。我还能够创建 Docker 映像并运行它。我希望可以在 localhost:6002 访问该应用程序。我使用以下命令创建容器:

docker run -p 6002:6002 --name advpersonapicontainerv2 advpersonapi:v2

我看到容器已创建并正在运行。

下面是docker ps的结果:

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
0484b184aeb8        advpersonapi:v2     "dotnet AdvPersonApi…"   About a minute ago   Up About a minute   0.0.0.0:6002->6002/tcp   advpersonapicontainerv2

问题是我无法在 Container 端口 6002 访问应用程序。以下命令给出连接被拒绝:

    docker exec 0484b184aeb8 curl http://localhost:6002/api/person/time
     % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (7) Failed to connect to localhost port 6002: Connection refused

但是,如果我尝试

docker exec 0484b184aeb8 curl http://localhost:80/api/person/time

,我得到了回应。我是 Docker 新手。主机端口 6002 正确映射到容器端口 6002 应该怎么做?

【问题讨论】:

  • 当您的应用程序不在 docker 中运行时,您的应用程序是否托管在端口 6002 上,或者您是否需要告诉它托管在该端口上?
  • @zero298 如果问题是关于从 Visual Studio 运行,在 IISExpress 中它被配置为在不同的端口 (44370) 上运行,并且工作正常。
  • 那么端口 80 很可能是默认端口。尝试 -p 6002:80 并从主机卷曲,而不是从容器本身内卷曲。它的 -p HOST_PORT:INNER_PORT。
  • 尝试进入容器 (shellhacks.com/docker-enter-container) 并运行 netstat。查看所需的端口是否已打开。可能 Web 应用程序没有打开您认为的端口号。

标签: docker dockerfile


【解决方案1】:

我知道发生了什么。我不得不通过将以下内容添加到 appsettings.json 来强制 Kestrel 监听端口 6002。

 "Kestrel": {
    "EndPoints": {
      "Http": {
        "Url": "http://+:6002"
      }
    }
  }

感谢@Timothy John Laird 在上述评论中提供的提示

【讨论】:

  • 容器内的端口无需更改。从外部而不是内部进行更改。
  • 请参阅我对您上面答案的评论。我尝试了该选项,并且在我的问题中明确提到了这一点 - docker run -p 6002:6002。
【解决方案2】:

容器内的应用正在监听 80,因此在 Dockerfile 中公开端口 80 而不是 6002。

EXPOSE 80

然后在运行容器时将主机端口 6002 映射到容器端口 80:

docker run -p 6002:80 --name advpersonapicontainerv2 advpersonapi:v2

最好让容器化应用在标准端口(如 80 或 8000)上进行侦听。您不想更新 Dockerfile 以使其侦听其他端口。这就是主机级别的运行时映射的工作。

【讨论】:

  • 我希望容器监听不同的端口(在本例中为 6002)。这是因为,这个容器是要部署在 K8s pod 中的其他几个容器之一。当 pod 中的所有这些容器都监听 80 端口时,第二个容器一部署,K8s 部署就失败了。此时,pod中失败容器的日志已经显示Kestrel抛出了一个异常,说80端口已经被使用。我相信这是因为 IP 地址和端口在 K8s 的 Pod 范围内。我尝试在 K8s 部署 yaml 中设置“containerPort”,但没有成功
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 2019-07-31
  • 2018-10-23
相关资源
最近更新 更多