如何在Windows中的Docker linux容器中公开ASP.NET Core的端口?

时间:2018-04-22 19:09:32

标签: linux windows docker docker-compose containers

我在docker-compose中定义了几个ASP.NET核心服务。我需要能够在host网络中公开端口(我在Docker for Windows 18.03.0-ce上使用linux容器)。

样品:

  • 服务C1和C2正在容器中运行。
  • 服务H3直接在主机中运行,而不是在容器中运行。
  • 所有服务(C1,C2和H3)必须互相访问。

我不知道如何在docker-compose中为服务C1和C2设置网络。我试过这个:

version: '3'

services:
  c1:
    image: <some image name>
    build:
      context: .
      dockerfile: <path to dockerfile>
    environment:
      - ASPNETCORE_ENVIRONMENT=Development      
      - ASPNETCORE_URLS=http://localhost:9084
    ports:
      - "9084:9084"
    network_mode: "host"

  c2:
    image: <some image name>
    build:
      context: .
      dockerfile: <path to dockerfile>
    environment:
      - ASPNETCORE_ENVIRONMENT=Development      
      - ASPNETCORE_URLS=http://localhost:9085
    ports:
      - "9085:9085"
    network_mode: "host"

我在启动容器时在控制台中看到了这个:

Hosting environment: Development
Content root path: /app
Now listening on: http://localhost:9085
Application started. Press Ctrl+C to shut down.

但我无法从主机连接它们。 netstat -an未显示这些端口,telnet localhost 9084失败。

这是该容器docker inspect的输出:

"NetworkSettings": {
    "Bridge": "",
    "SandboxID": "df480d4d68cb109dc6b85f689f8b210a9f74e650c48a343cdd3d11eb3d10bec7",
    "HairpinMode": false,
    "LinkLocalIPv6Address": "",
    "LinkLocalIPv6PrefixLen": 0,
    "Ports": {},
    "SandboxKey": "/var/run/docker/netns/default",
    "SecondaryIPAddresses": null,
    "SecondaryIPv6Addresses": null,
    "EndpointID": "",
    "Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "MacAddress": "",
    "Networks": {
        "host": {
            "IPAMConfig": null,
            "Links": null,
            "Aliases": null,
            "NetworkID": "324d836f54fa685d56b416f01a18e3e75f88d4516dafac43bb1a4ff760a2b67a",
            "EndpointID": "9212f6a01e142ef9fb71116c9fe03c37567c60ed8a2add91fe28bf0bd6de001a",
            "Gateway": "",
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "",
            "DriverOpts": null
        }
    }
}

当我从network_mode: "host"删除docker-compose配置时(网络默认为bridge),我从应用程序中收到此消息:

warn: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to bind to http://localhost:9084 on the IPv6 loopback interface: 'Error -99 EADDRNOTAVAIL address not available'.

您能帮我设置网络配置吗?

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法:

  • 我没有在docker-compose中设置任何网络(使用生成的* _default并带有bridge驱动程序) - 已删除network_mode
  • 我在ASPNETCORE_URLS中删除了docker-compose个ENV变量。
  • APS.NET核心应用程序使用端口80(内部容器)。
  • 端口80暴露(例如)为9084,可从主机访问。
  • 应用程序配置为使用(例如)localhost:9085
  • docker-compose使用环境变量将端点覆盖为host.docker.internal.9085

现在,在容器中运行的所有服务都使用host.docker.internal和一些端口 连接到其他服务,因此这些服务可以连接在容器中运行或直接在主机中运行的其他服务。

在主机中运行的服务使用localhost和某个端口,因此它们可以连接在主机或容器中运行的其他服务。

这是docker-compose档案的样本:

version: '3'

services:
  c1:
    image: <some image name>
    build:
      context: .
      dockerfile: <path to dockerfile>
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    env_file:
      - docker-compose.override.env
    ports:
      - "9084:80"

  c2:
    image: <some image name>
    build:
      context: .
      dockerfile: <path to dockerfile>
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    env_file:
      - docker-compose.override.env
    ports:
      - "9085:80"

docker-compose.override.env档案的示例:

ApiOptions__DomainModelApiBaseUrl=http://host.docker.internal:9081/api
ApiOptions__SearchApiBaseUrl=http://host.docker.internal:9088/api

现在我可以在容器或Visual Studio中运行相同的服务并进行调试。