【问题标题】:Azure app service multi container - http request to internal container (docker compose)Azure 应用服务多容器 - 对内部容器的 http 请求(docker compose)
【发布时间】:2020-02-26 16:46:09
【问题描述】:

我已经使用 docker compose 文件(预览版)在 Azure 中部署了多容器应用服务。

web 应用程序公开了 80 端口,所以如果我转到 https://myproj.azurewebsites.net/,就会显示 web 应用程序(它是唯一可用的公共端口)。

我现在想做的是能够从网络向我的 api 发送一个 http 请求,这是另一个内部托管的容器。我尝试了不同的网址,但我无法成功提出请求。 api容器启动成功所以没有什么问题,只是不知道用哪个地址。

OrderApi Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["MyProj.OrderApi/MyProj.OrderApi.csproj", "MyProj.OrderApi/"]
COPY ["nuget.config", "MyProj.OrderApi/"]
RUN dotnet restore "v.OrderApi/MyProj.OrderApi.csproj" --configfile "MyProj.OrderApi/nuget.config"
RUN rm "MyProj.OrderApi/nuget.config"
COPY . .
WORKDIR "/src/MyProj.OrderApi"
RUN dotnet build "MyProj.OrderApi.csproj" -c Release -o /app/build

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

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

生产环境中使用的 Docker 组合文件 (Azure)

version: '3.4'

services:
web:
    image: myproj.azurecr.io/myproj/web
    ports:
    - '80:80'

orderapi:
    image: myproj.azurecr.io/myproj/orderapi

端点测试

https://localhost/orderapi/api - ERR_CONNECTION_REFUSED

http://localhost/orderapi/api - 被 CORS 策略阻止(我确定在 api 中正确配置了 cors)

https://host.docker.internal/orderapi/api - ERR_CONNECTION_TIMED_OUT

orderapi/api - 将当前站点添加为 baseurl.. 尝试发送请求到 https://mysite.azurewebsites.net/orderapi/api

http://host.docker.internal/orderapi/api - 此请求已被阻止;内容必须通过 HTTPS 提供

host.docker.internal/orderapi/api - 将当前站点添加为 baseurl.. 尝试发送请求到 https://mysite.azurewebsites.net/host.docker.internal/orderapi/api

【问题讨论】:

    标签: c# azure docker .net-core docker-compose


    【解决方案1】:

    不幸的是,Azure Web App for Container 只能将一个容器暴露给 Internet。这意味着如果您在 Web App 中部署多个容器,则只能从 Internet 访问一个容器。请参阅Multi-container with Docker Compose中有关我如何知道哪个容器可以访问互联网的详细信息。

    更新:

    当您在 docker-compose 文件中设置这样的服务时:

    redis:
      image: redis
      container_name: rediscache
    

    那么这里是连接容器redis的代码示例:

    [Route("api/[controller]")]
    [ApiController]
    public class NewsController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public async Task<ActionResult<IEnumerable<string>>> Get()
        {
            ConnectionMultiplexer connection = await ConnectionMultiplexer.ConnectAsync("redis");
            var db = connection.GetDatabase();
    
            //code to parse the XML
        }
    }
    

    【讨论】:

    • 是的,我知道!但是web应用程序不能访问内部网络,api和web是一起托管的,所以应该可以吗?或者可能是在网络外调用了javascript?
    • @Reft 同一个Web App内的容器可以通过你在docker-compose文件中设置的服务名称相互连接。你可以看看How to deploy multiple container application on web app
    • 是的,但那是来自服务器端。我想要的是从 web 应用程序向内部 api 发送一个 http 请求。它们都在同一个应用程序服务中,但我的猜测是 javascript http 请求是从内部网络外部触发的......
    • @Reft 你是什么意思?我看到你的 web 和 API 都在同一个 docker-compose 文件中,这意味着在同一个 web 应用程序和同一个主机中。就像前端和数据库一样,前端必须可以访问数据库。就像例子here。那么为什么他们不能互相交流呢?
    • 是的,那么这应该是可能的。我在 dockerfile 中公开端口并在撰写文件中定义正确的端口,但我仍然无法将 http 请求从 web 发送到 api。你可以看到我在我的问题中测试了哪些网址
    【解决方案2】:

    在 docker-compose 文件中,orderapi 不公开任何端口。如果没有暴露任何端口,它就无法处理请求。

    通常,浏览器获取 html 并将请求直接发送到 API。

    也许 orderapi 应该公开其他端口(例如 88),以便浏览器可以使用该端口使用来自 API 的数据。

    【讨论】:

    • 我在 dockerfile 中添加了 Expose 88,在 compose 文件中添加了 -p 88 并使用 localhost:88/api 进行了测试,但我仍然收到 ERR_CONNECTION_REFUSED
    • 在 dockerfile 中你可以使用端口 80 (EXPOSE 80) 但在 orderapi 服务的 docker-compose.yml 文件中,将主机的端口 88 暴露给容器的端口 80 ( ports: - "88: 80" ) ,在容器运行后列出使用“docker ps”或“docker-compose ps”暴露的端口
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2020-04-09
    • 2019-03-09
    • 2017-04-03
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多