我有一个。net核心API项目与以下dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:5.0.0-buster-slim AS base
WORKDIR /app
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["API/API.csproj", ""]
RUN dotnet restore "./API.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "API/API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "API/API.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API.dll"]
我已经成功地将这个映像推送到Google Cloud Artifact Registry,并使用它创建了一个Google Cloud Compute Engine实例。我只设置了https,没有调用它。邮差提示错误:connect ECONNREFUSED xxx . xxx . xxx:443。如果我从https切换到http,只有我可以到达实例,它按预期工作,但当然不是那么安全,所以我不想坚持下去。它设置了一个静态IP,这样我就可以把我的子域名指向它。我错过了什么?
您的问题可能与您的容器HTTPS配置有关。
在描述如何开发ASP时,请考虑查看微软提供的文档。. NET核心应用程序与Docker通过HTTPS和托管ASP。. NET Core images与Docker Compose通过HTTPS。这个相关的问题也会有所帮助。
基本上,您需要提供不同的环境配置属性,分别定义应用程序有效的url、HTTPS侦听端口、要使用的SSL证书的路径和保护该证书的密码:
ASPNETCORE_URLS="https://+;http://+"
ASPNETCORE_HTTPS_PORT=8001
ASPNETCORE_Kestrel__Certificates__Default__Password="password"
ASPNETCORE_Kestrel__Certificates__Default__Path=httpsaspnetapp.pfx
正如GCP文档中所指出的,您可以使用GCP Web控制台或gcloud
CLI提供此环境信息,在后一种情况下使用--container-env
或--container-env-file
标志。
正如前面提到的SO问题,我认为你可以利用多阶段Docker构建过程来传递这个环境信息。
由于部署在Compute Engine中的容器共享主机网络,请确保您已经配置了必要的防火墙规则以允许访问您的容器端口。
为了从你的容器访问你的证书,我想你可能有两个选择。
一方面,您可以将证书包含在映像中,作为构建过程的一部分。它有一个明显的缺点,它将使证书更容易访问,这是一个不太安全的解决方案,尽管如果您将映像部署到非公共存储库可以减轻它;此外,考虑到您仍然需要pfx的密码,因此,小心,这可能是一个有效的解决方案。
此外,正如GCP文档中所描述的,您可以挂载一个主机目录,并将其作为卷访问到您的容器,并将证书存储在该目录中。在某些映像中,为了自动化分发进程,您可以使用--metadata
标志和startup-script
密钥来提供有关如何访问证书的必要信息。但是…首先在哪里获得证书?理想情况下,它可能以加密形式存储在Google KMS中,或者可能存储在Google Secrets中。例如本文就建议使用这种方法,尽管我个人从未尝试过。
已经说过,在我看来,而不是试图自定义你的容器,一个更好的解决方案是在你的vm前面配置一个HTTPS负载平衡器:除了高可用性和可扩展性,易于维护等,关于HTTPS配置,你只需要在配置你的负载平衡器前端时提供你的证书细节;如果有必要,你也可以申请一个谷歌管理的证书。
请注意,如果您遵循第二个选项,则不再需要在应用程序本身中配置HTTPS,它可以安全地在端口80
上运行。其思想是将HTTPS处理委托给负载平衡器,并使用负载平衡器前端提供SSL终止,从而将应用程序从该责任中解放出来。
你必须告诉运行asp.net应用程序的docker映像的web服务器也使用https协议。
您应该通过使用以下值https://+;http://+
注入环境变量ASPNETCORE_URLS
来实现这一点。
关于这个env变量的更多信息可以在文档
中找到。