【问题标题】:HttpClient request on networked docker container网络 docker 容器上的 HttpClient 请求
【发布时间】:2021-05-17 22:51:58
【问题描述】:

我是 docker 容器的新手,我遇到了以下问题。我正在开发一个向公开的 api 发出请求的网页。它们都发布在通过网络链接的不同容器上。 这是我的 docker-compose.yml 文件:

version: '2'

services:
  api:
    image: my/api
    networks:
      - api
    ports:
      - "8080:5000"    
    container_name: api  

  web:
    build:
      context: ./DockerWeb      
    networks:
      - api      
    ports:
      - "80:5000"    
    container_name: web

networks:    
  api:
    driver: bridge

我注意到,如果我附加到运行我的网页的容器,我可以使用ping api ping api 容器而不会出现任何问题

尝试对 api 容器进行任何 Web 服务调用时会出现问题。我正在尝试初始化一个 HttpClient 对象,但是必须将此类对象的 BaseAddress 属性设置为有效的 Uri。

_client = new HttpClient();
_client.BaseAddress = new Uri(config.ApiUrl); //config.ApiUrl = "api"

这会引发以下错误

UriFormatException: Invalid URI: 无法确定 URI 的格式。

有没有办法 a) 以不同的方式公开容器名称,或 b) 无需使用 URI 即可调用 Web 服务? 我怎样才能做到这一点?

更新

我已更新 ApiUrl 以包含值 http:api:8080,但是现在执行调用时出现异常

System.AggregateException:发生一个或多个错误。 (发送请求时出错。) ---> System.Net.Http.HttpRequestException: 发送请求时出错。 ---> System.Net.Http.CurlException: 无法连接到服务器

我也尝试过使用 wget 直接从我的 Web 容器调用 api 端点

wget http://api:8080/ 

但是我仍然收到错误消息:

连接到 api (api)|172.24.0.4|:8080... 失败:连接被拒绝

这可能是 API 配置错误吗?

【问题讨论】:

    标签: c# docker asp.net-core-webapi docker-networking


    【解决方案1】:

    api 只是主机名。 URI 将是 http://api:8080(如果您设置了 SSL/TLS,则为 https://api:someotherport。)

    【讨论】:

    • 感谢您的回答。我已更新为调用 http:api:8080,但是我收到异常“System.Net.Http.CurlException:无法连接到服务器”我还从我的 Web 容器wget http://api:8080/ 中尝试了以下操作,我收到了回复以下错误:连接到 api (api)|172.24.0.4|:8080... 失败:连接被拒绝。
    • 我注意到,即使我为 api 公开了 8080 端口,这也不是容器之间使用的端口。同一网络中的容器之间,使用 EXPOSE 指令暴露的端口。在这种情况下,它将是 5000。尝试 api:5000 工作
    • @LuisBecerril 抱歉。我一定对 docker compose yml 文件中端口绑定的顺序感到困惑。
    【解决方案2】:

    这里有2种交流方式:

    容器 web > 容器 api

    在这种情况下,确实,您可以使用主机名“api”连接到您的 api。 如果您的 html 是在服务器端生成的,这就是您必须做的事情。

    Web 客户端 > 容器 api

    不过,我假设您正在使用某种 JavaScript Web 应用程序(Angular 或其他)。在这种情况下,html(和调用)不是从 web 容器生成的,而是直接从你的 web 浏览器生成的。

    所以在这种情况下你必须使用http://localhost:8080(我想Docker正在你的本地机器上运行)。

    希望对你有帮助

    【讨论】:

    • 我不能使用 localhost:8080 因为这会破坏容器命名链接。我需要使用api:8080 以便在运行时解析 api 容器的 IP 地址。我仍然无法连接
    • 我并不是要在 docker-compose 文件中使用 localhost。这里的问题是您的客户端从 Docker 外部连接,因此这里不使用容器链接。您是否可以至少确认使用 localhost 是否有效(在您的 Web 应用程序中)并确认您是否在使用 Angular 之类的 JavaScript Web 应用程序中使用此调用
    【解决方案3】:

    内部端口用于 docker 网络内部的连接。所以在这种情况下,请求需要转到 http://api:5000

    【讨论】:

      猜你喜欢
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 2017-12-03
      • 1970-01-01
      • 2020-05-10
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多