【问题标题】:Unable to configure HTTPS endpoint for .net Core Kestral Server in Linux Container on Azure无法在 Azure 上的 Linux 容器中为 .net Core Kestral 服务器配置 HTTPS 端点
【发布时间】:2020-11-04 17:03:43
【问题描述】:

我有一个 .net core 3 应用程序在 本地/开发 运行良好,无论是单独运行还是在 linux 容器中运行。 然后,我使用该应用程序并将其内置到 azure 管道内的 docker 映像中。映像已加载到 Azure 容器注册表。

最后,我有一个Azure Web APP for Containers (Linux),它使用映像来运行。

我在本地设置了 docker-compose 文件,如下所示:

    environment:
      - "ASPNETCORE_ENVIRONMENT=Development"
      ...
      - "ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx"
      - "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
    volumes:
      - ~/.aspnet/https:/https:ro

对于生产,我有以下内容:

    environment:
      - UseInMemoryDatabase=false
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.pfx
      - "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
    ports:
      - "5000:5000"
      - "5001:5001"
    volumes:
       - fsmount001: /security:/security
       - /var/ssl/private:/https

我将“mycert”加载到 azure 门户中,并将其指纹添加到应用程序的配置设置中的 WEBSITE_LOAD_CERTIFICATES

我使用 Open SSL 创建了 mycert 文件,我可以在本地使用它,而 kestral 会使用它,但会出现警告。

问题

当我使用此图像运行应用程序时,我在 docker 日志中收到以下错误:

System.InvalidOperationException:无法配置 HTTPS 端点。 未指定服务器证书,默认开发者 证书找不到或已过期...在 Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)

我已经尝试了很多加载证书的变体,但无法让它们中的任何一个工作。 这是一个仅在生产中发生的问题。

我也试过了:

  1. 购买了 Azure 应用证书并使用了 thumbprint.p12 文件,例如:
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/var/ssl/private/<thumbprint>.p12
      - ASPNETCORE_Kestrel__Certificates__Default__Password=""

我没有使用密码,因为当您购买证书时没有设置密码

  1. 下载购买的 App Cert 并使用 open ssl 创建密码链接的 .pfk 文件并将其作为另一个私钥上传

  2. 使用 azure 文件挂载并上传我的开发证书文件并从文件挂载中引用它们,例如:

      - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.com.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123"
    volumes:
       - fsmount001: /security:/security

编辑 1:完整的 docker-compose 和 azure 文件设置

  1. 这是我定义文件共享的方式:

有一个安全文件夹,里面有 mycert.pfx 文件

  1. 这是我在 azure 应用服务配置中设置文件挂载的方法:

我将挂载路径设置为我的文件共享中的安全文件夹

  1. 这是完整的 docker compose 文件:
services:
  webui:
    image: ${DOCKER_REGISTRY-}webui
    build:
      context: .
      dockerfile: src/WebUI/Dockerfile
    environment:
      - UseInMemoryDatabase=false
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - "ConnectionStrings__DefaultConnection=****"
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/secure/mycert.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123"
    ports:
      - "5000:5000"
      - "5001:5001"
    volumes:
       - fsmount001: /secure
       - ~/var/ssl/private:/https
    restart: always

volumes:
  fsmount001:
    driver: azure_file
    driver_opts:
      share_name: st-*****tus
      storage_account_name: st********001

编辑 2:码头文件

有关更多上下文,您可以在下面找到我的 dockerfile

请注意,我使用的是开源应用程序模板/框架 cleanarchiecture。您可以看到我正在尝试将 docker pull request 用于 repo 作为基本代码。我的目标是在 azure ci/cd 管道中“dockerize”这个基础框架,并将其部署到 azure web app for containers (linux)


FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
ENV ASPNETCORE_URLS=https://+:5001;http://+:5000

WORKDIR /app
EXPOSE 5000 5001 2222

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt install -y nodejs
WORKDIR /src
COPY ["src/WebUI/WebUI.csproj", "src/WebUI/"]
COPY ["src/Application/Application.csproj", "src/Application/"]
COPY ["src/Domain/Domain.csproj", "src/Domain/"]
COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
RUN dotnet restore "src/WebUI/WebUI.csproj"
COPY . .
WORKDIR "/src/src/WebUI"
RUN dotnet build "WebUI.csproj" -c Release -o /app/build

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]

谁能帮我弄清楚如何在 Linux 容器中为 kestral 设置证书?

提前致谢

【问题讨论】:

    标签: azure docker .net-core docker-compose azure-web-app-service


    【解决方案1】:

    你的docker-compose文件是否有可能在服务volumes的定义中有错误?

    您的服务有以下docker-compose 片段:

        environment:
          - UseInMemoryDatabase=false
          - ASPNETCORE_ENVIRONMENT=Production
          - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.pfx
          - "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
        ports:
          - "5000:5000"
          - "5001:5001"
        volumes:
           - fsmount001: /security:/security
           - /var/ssl/private:/https
    

    使用此设置,您将尝试创建两个卷。

    一方面,您将主机系统中的/var/ssl/private 路径映射到/https 容器目的地。它应该可以正常工作。

    但是,另一方面,我认为您正在混合命名卷和基于路径映射的卷的语法。

    对于您的更新,您正在尝试使用 Azure 文件存储装载。然后你需要修改你的服务volumes定义如下:

        environment:
          ...
        ports:
          ...
        volumes:
           - fsmount001:/security
           - /var/ssl/private:/https
    

    documentation 中所示,重要的是要了解装载路径对应于容器内要装载到 Azure 存储的文件夹:

    装载路径设置对应于容器内要装载到 Azure 存储的文件夹。将其设置为“/”会将整个容器装载到 Azure 存储。

    另请注意,在您的docker-compose 文件中为fsmount001 提供的路径与您创建挂载时指定的挂载路径相同,在本例中为/security

    使用此设置,您需要像这样配置证书位置:

    - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/security/mycert.pfx
    

    第一个 /security 表示容器中的路径,第二个表示您的 pfx 包含在文件共享中的目录。

    更新

    在检查了您的 Dockerfiledocker-compose 文件后,我认为您的问题可能不是因为实际的文件共享,而是因为设置 HTTPS 所需的环境变量在 docker 容器中不可见,因为它们是仅在其构建阶段使用。请看this我认为相关的堆栈溢出问题。

    您需要在Dockerfile 中直接提供此环境信息,或在docker-compose 文件中间接使用ARGs 提供此环境信息。

    例如,如下修改您的 docker-compose 文件 - 基本上,将您的 environmententry 更改为 args

    services:
      webui:
        image: ${DOCKER_REGISTRY-}webui
        build:
          context: .
          dockerfile: src/WebUI/Dockerfile
        args:
          - UseInMemoryDatabase=false
          - ASPNETCORE_ENVIRONMENT=Production
          - ASPNETCORE_URLS=https://+:443;http://+:80
          - ConnectionStrings__DefaultConnection=****
          - ASPNETCORE_Kestrel__Certificates__Default__Path=/secure/mycert.pfx
          - ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123"
        ports:
          - "5000:5000"
          - "5001:5001"
        volumes:
           - fsmount001: /secure
           - ~/var/ssl/private:/https
        restart: always
    
    volumes:
      fsmount001:
        driver: azure_file
        driver_opts:
          share_name: st-*****tus
          storage_account_name: st********001
    

    他们修改您的Dockerfile 以读取提供的构建参数:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    
    ARG UseInMemoryDatabase
    ENV UseInMemoryDatabase=$UseInMemoryDatabase
    
    ARG ASPNETCORE_ENVIRONMENT
    ENV ASPNETCORE_ENVIRONMENT=$ASPNETCORE_ENVIRONMENT
          
    ARG ASPNETCORE_URLS=https://+:5001;http://+:5000
    ENV ASPNETCORE_URLS=$ASPNETCORE_URLS
    
    ARG ConnectionStrings__DefaultConnection
    ENV ConnectionStrings__DefaultConnection=$ConnectionStrings__DefaultConnection
          
    ARG ASPNETCORE_Kestrel__Certificates__Default__Path
    ENV ASPNETCORE_Kestrel__Certificates__Default__Path=$ASPNETCORE_Kestrel__Certificates__Default__Path
    
    ARG ASPNETCORE_Kestrel__Certificates__Default__Password
    ENV ASPNETCORE_Kestrel__Certificates__Default__Password=$ASPNETCORE_Kestrel__Certificates__Default__Password
    
    WORKDIR /app
    EXPOSE 5000 5001 2222
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
    RUN apt install -y nodejs
    WORKDIR /src
    COPY ["src/WebUI/WebUI.csproj", "src/WebUI/"]
    COPY ["src/Application/Application.csproj", "src/Application/"]
    COPY ["src/Domain/Domain.csproj", "src/Domain/"]
    COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
    RUN dotnet restore "src/WebUI/WebUI.csproj"
    COPY . .
    WORKDIR "/src/src/WebUI"
    RUN dotnet build "WebUI.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "WebUI.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    
    ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]
    

    请在您认为合适的情况下对其进行修改。特别是在应该定义不同的ARGs 和ENVs 的那一刻,因为它们是每个构建阶段的范围,并且不会在下一阶段保留。您可以按原样尝试,也可以在base 中定义ARGs 和在final 中定义ENVs,因为一个从另一个扩展,ARGs 变量应该在两者中都可见。

    【讨论】:

    • 感谢您的帮助,我还没有完全搞定它。我更新了我的问题以包含更多详细信息。你能根据我的设置确认我做对了吗?文件挂载设置为安全的挂载路径,这是我的文件共享中的一个文件夹。因此,我假设挂载文件的“根”是安全文件夹。
    • 欢迎您@JKing。很遗憾听到它仍然无法正常工作。我用更多信息更新了我的答案:对不起,我之前按照 docker 文档中的说明进行了 ACI 设置的步骤,但不适用于 Web 应用程序。拜托,你可以试试看它是否有效?您还可以尝试的一件事是使用应用服务的Development Tools 部分中提供的任何机制(主要是 SSH 或 Kudu)连接到容器,查看 /secure 路径是否存在以及您的证书是否在它应该存在的位置成为。
    • 这里发生了一些疯狂的事情。我已经进行了您建议的更改,并且轻松地对文件名和路径进行了十几个其他小的变体。同样的错误仍然存​​在。我无法 ssh 进入我的容器,因为它是一个自定义容器,我无法让 ssh 处理它。 kudu bash 终端由于某种原因引发错误,即使它在几天前工作,我也无法解决。在 azure ci/cd 中构建和检查日志的 10 分钟往返行程使这非常乏味。哈哈,我们热爱我们的工作吧?
    • 很好@JKing。请更新您的 Dockerfile,我认为您需要为构建中使用的每个环境变量定义 ARGS,并在您的 Dockerfile 中将其公开为 ENV,以使其对您的应用程序和 .net 框架可见。你明白了吗?
    • @JKing 我用我建议你做的改变更新了答案。我希望它有所帮助。
    猜你喜欢
    • 2022-01-16
    • 2022-01-01
    • 2019-02-26
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2021-11-19
    相关资源
    最近更新 更多