gpt4 book ai didi

docker - ASP.NET Core 配置值有时在 Kubernetes 中返回空

转载 作者:行者123 更新时间:2023-12-02 12:10:14 26 4
gpt4 key购买 nike

我目前正在开发一个在 Kubernetes 上使用 .NET Core 2.1 运行的项目。我的应用程序从 appsettings.json 读取配置值文件和环境变量。
问题是当我尝试从 IConfiguration 读取配置时接口(interface),“大部分时间”值返回 null,但仅在 Kubernetes 中。它在我的开发机器和带有 Windows VM 和 IIS 的测试机器上完美运行。这些环境之间的区别在于开发和测试机器是 Windows,但产品是运行在 linux 容器上的 Kubernetes(基于 microsoft/dotnet:2.1-aspnetcore-runtime 图像)以及我如何实现环境变量。在我的开发机器中没有定义环境变量。在 Windows VM 中,我通过 web.config 使用环境变量。像这样的条目:

<aspNetCore processPath="dotnet" arguments="myapp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
<environmentVariables>
<environmentVariable name="Site:SiteId" value="1" />
<environmentVariable name="Site:Theme" value="MyTheme" />
</environmentVariables>
</aspNetCore>
我正在使用 WebHost.CreateDefaultBuilder()对于配置和文档说方法实现 appsettings.json , appsettings.{EnvironmentName}.json ,环境变量和配置源的命令行参数。
我的 appsettings.json文件:
{
"Site": {
"SiteId": 1,
"Theme": "Limitless"
},
"RemoteClient": {
"HostUrl": "http://localhost:59554/management/",
"AppKey": "test",
"AppSecret": "1"
}
}
最后是我的 Kubernetes 部署文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 1
selector:
matchLabels:
component: myapp
strategy: {}
template:
metadata:
labels:
component: myapp
spec:
nodeSelector:
beta.kubernetes.io/os: linux
containers:
- image: 'myregistry/myapp:latest'
imagePullPolicy: IfNotPresent
name: myapp
env:
- name: "Site__SiteId"
value: "1"
- name: "Site__Theme"
value: "Limitless"
- name: "RemoteClient__HostUrl"
value: "http://apphost/management"
- name: "RemoteClient__AppKey"
value: e824b2670e644824bdd5cdee1db9bd4b
- name: "RemoteClient__AppSecret"
value: 12d4deadf948
- name: "ASPNETCORE_ENVIRONMENT"
value: Production
ports:
- containerPort: 80
restartPolicy: Always
我说的是“大多数时候”,因为每次 pod 重新启动时它的行为都不同。有时它读取一个变量而不读取其他变量,有时它读取其余变量,最终它可以读取所有变量并且应用程序正常运行。您可以在 kubectl describe pod 中查看输出说
kubectl describe pod output
但是当我从 IConfiguration 读取值时服务并输出到控制台输出如下所示:
configuration output 1
和其他重启
configuration output 2
这两次运行之间我没有改变任何东西,它只是重新启动。它甚至没有读取 appsettings.json 中定义的默认值。
那么您认为为什么会发生这种情况?
编辑:
我正在使用此代码块进行初始配置, CreateDefaultBuilder()负责配置。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.AddPreConfigureServices();
CreateDefaultBinder() 的注释:
//
// Summary:
// Initializes a new instance of the Microsoft.AspNetCore.Hosting.WebHostBuilder
// class with pre-configured defaults.
//
// Parameters:
// args:
// The command line args.
//
// Returns:
// The initialized Microsoft.AspNetCore.Hosting.IWebHostBuilder.
//
// Remarks:
// The following defaults are applied to the returned Microsoft.AspNetCore.Hosting.WebHostBuilder:
// use Kestrel as the web server and configure it using the application's configuration
// providers, set the Microsoft.AspNetCore.Hosting.IHostingEnvironment.ContentRootPath
// to the result of System.IO.Directory.GetCurrentDirectory, load Microsoft.Extensions.Configuration.IConfiguration
// from 'appsettings.json' and 'appsettings.[Microsoft.AspNetCore.Hosting.IHostingEnvironment.EnvironmentName].json',
// load Microsoft.Extensions.Configuration.IConfiguration from User Secrets when
// Microsoft.AspNetCore.Hosting.IHostingEnvironment.EnvironmentName is 'Development'
// using the entry assembly, load Microsoft.Extensions.Configuration.IConfiguration
// from environment variables, load Microsoft.Extensions.Configuration.IConfiguration
// from supplied command line args, configures the Microsoft.Extensions.Logging.ILoggerFactory
// to log to the console and debug output, enables IIS integration, and enables
// the ability for frameworks to bind their options to their default configuration
// sections.
public static IWebHostBuilder CreateDefaultBuilder(string[] args);
编辑 2:
读取我的 Startup.cs 中的值像这样:
services.AddMvc(options => { })
.AddEntityBinders()
.AddRazorOptions(options =>
{
string theme = Configuration["Site:Theme"];

options.ViewLocationFormats.Clear();
options.ViewLocationFormats.Add($"~/Views/{theme}Theme/{{1}}/{{0}}.cshtml");
options.ViewLocationFormats.Add($"~/Views/{theme}Theme/Shared/{{0}}.cshtml");
})
.SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);

最佳答案

经过漫长而艰难的调试 session 。我终于可以查明问题所在了。
.Net Core 使用 :作为配置键分隔符,但 Kubernetes 配置文件在命名环境变量时不支持这样的字符。 EnvironmentVariablesConfigurationProvider通过接受 __ 来解决这个问题作为分隔符并替换为 :读取值时。
因此,我在 Kubernetes 部署文件中使用 __ 分隔符声明了我的环境变量(如上所示)。但是 Dockerfile 没有这个问题,我用 : 编写 ENV 定义分隔符(如下),这会创建重复的变量,.Net Core 会读取所有变量并产生不稳定的结果。

ENV RemoteClient:HostUrl ${HOST_URL}
ENV RemoteClient:AppKey ${APP_KEY}
ENV RemoteClient:AppSecret ${APP_SECRET}
ENV ASPNETCORE_ENVIRONMENT ${ENVIRONMENT_NAME}

关于docker - ASP.NET Core 配置值有时在 Kubernetes 中返回空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63721583/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com