azure - 无法在 Azure 上的 Linux 容器中为 .net Core Kestral 服务器配置 HTTPS 端点

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

我有一个 .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: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date ... at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)

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

我也尝试过:

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

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

  • 下载购买的应用程序证书并使用 open ssl 创建密码链接的 .pfk 文件并将其作为另一个私钥上传

  • 使用 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. 以下是我定义文件共享的方式: enter image description here

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

  • 以下是我在 Azure 应用服务配置中设置文件挂载的方法:
  • enter image description here

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

  • 这是完整的 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

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

    请注意,我正在使用开源应用程序模板/框架 cleanarchiecture。您可以看到我正在尝试使用 docker pull request存储库作为基本代码。我的目标是在 azure ci/cd 管道中“dockerize”这个基础框架,并将其部署到容器的 azure Web 应用程序 (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 设置证书吗?

    提前致谢

    最佳答案

    您的 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 存储的容器内的文件夹:

    The mount path setting corresponds to the folder inside the container that you want to mount to Azure Storage. Setting it to '/' mounts the entire container to Azure Storage.

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

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

    - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/security/mycert.pfx
    

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

    更新

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

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

    例如,按如下方式修改 docker-compose 文件 - 基本上,更改 argsenvironment 条目:

    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"]
    

    请根据您的需要进行修改。尤其要注意应该定义不同的 ARGENV 的时刻,因为它们的作用域是每个构建阶段的,并且不会在下一阶段保留。您可以按原样尝试,也可以在 base 中定义 ARG 并在 final 中定义 ENV,作为一个从另一个扩展,ARG 的变量应该在两者中都可见。

    关于azure - 无法在 Azure 上的 Linux 容器中为 .net Core Kestral 服务器配置 HTTPS 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64563312/

    相关文章:

    Azure Blockchain Workbench 应用程序未显示在企业应用程序中

    c# - Controller 中有两种方法时的 API 和 OData 行为

    c# - 更改 StringWriter xml 节点输出

    docker - 在 docker 上启用实时恢复并不能保持容器存活

    c# - 有没有办法让控制台应用程序仅使用 .NET Core 中的单个文件运行?

    mysql - 在 azure 中使用 java 函数应用程序获取 SSL 和连接错误

    azure - 入口规则无法解析 Azure AKS 上的后端服务器 IP 地址

    c# - 尝试连接时,Azure Vault 中的 GetSecret 抛出 NullReferenceException

    java - 如何在log4j2中使用docker传递的环境变量?

    docker - Centos 服务已启动但仍处于禁用状态