gpt4 book ai didi

docker - 在 kubernetes 中的 asp.net 核心容器中登录重置/丢失

转载 作者:行者123 更新时间:2023-12-05 06:51:46 24 4
gpt4 key购买 nike

容器的新手,近十年后又回到了 asp.net,我认为这已经在某个地方得到了回答,但似乎无法找到它!我有一个在 3 个节点上运行的简单 asp.net 应用程序,登录显然是每个节点,当请求由不同的节点提供服务时会丢失。我假设会有分布式 session 管理教程,但这里没有任何指示/操作方法?

仅供引用 - 目前处于开发阶段,但面向公众的云解决方案 azure/linode/...运行 3 个 pod

配置/日志信息附在下面

Redis 在本地主机上工作 - 而不是在 docker 容器中

行为如下

  • 假设用户登录到 pod1,每当请求到达 pod1 时,它显示已登录,
  • 如果请求命中 pod2/pod3,则显示未登录!!!

看起来需要其他东西才能使 session 使用 redis !!!


public void ConfigureServices(IServiceCollection services)
{
var cx = Configuration["RedisCache:ConnectionString"];
var redis = ConnectionMultiplexer.Connect(cx);
services.AddDataProtection().PersistKeysToStackExchangeRedis(redis, "DataProtectionKeys");

services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
});
services.AddControllersWithViews();
services.AddRazorPages();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseDeveloperExceptionPage();
//app.UseExceptionHandler("/Error");
app.UseHsts();
}
if (env.IsDevelopment())
{
app.UseHttpsRedirection();
}

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

// Adds session middleware to pipeline
app.UseSession();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}

APPSETTINGS.JSON

{
"ConnectionStrings": {
"DefaultConnection": "Server=host.docker.internal;Database=SAMPLE;Trusted_Connection=false;user id=XXX;password=XXX;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"RedisCache": {
"ConnectionString": "host.docker.internal:6379,ssl=True,abortConnect=False"
},
"AllowedHosts": "*"
}

我在 Index.cshtml.cs 中有以下日志记录信息

public void OnGet()
{
var str = $"({Environment.MachineName}) || {HttpContext.Session.Id} || {DateTime.UtcNow.ToString("hh:mm:ss")}: Current({User.Identity.Name})";
_logger.LogWarning(str);

string sessionKey = "testKey1";

HttpContext.Session.SetString(sessionKey, str);
}

最佳答案

使用当前代码, session 存储在本地,因此每次负载均衡器重定向到新的 pod 时,您都将丢失先前请求的任何上下文。

您必须启用分布式缓存,以允许在您的服务器应用程序的多个实例之间共享 session 。参见 IDistributedCache interface

您还必须确保所有应用程序实例 shared the same keys for Data Protection related workflows .

这是一个使用 Redis 作为 DistributedCache 的工作示例:

public void ConfigureServices(IServiceCollection services)
{
// ensure that several instances of the same application can share their session
services.AddDataProtection()
.SetApplicationName("myapp_session")
.PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect("redis:6379,password=cE3nNEXHmvGCwdq7jgcxxxxxxxxxx"),
"DataProtection-Keys");

services.AddControllersWithViews();

// add distributed caching based on Redis
services.AddStackExchangeRedisCache(action => {
action.InstanceName = "redis";
action.Configuration = "redis:6379,password=cE3nNEXHmvGCwdq7jgcxxxxxxxxxx";
});

services.AddSession(options => {
options.Cookie.Name = "myapp_session";
options.IdleTimeout = TimeSpan.FromMinutes(60 * 24);
});
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseHttpsRedirection();

app.UseRouting();

app.UseSession();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}

这里是对应的csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.1" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="5.0.3" />
</ItemGroup>
</Project>

此处提供完整示例:https://github.com/Query-Interface/SO-Answers/tree/master/dotNET/AspWithSessionOnMultipleNodes

另一种选择是在您的 Kubernetes 服务中启用SessionAffinity。它允许 LoadBalancer 将来自一个客户端的流量始终指向同一个 Pod。它可以帮助您,但不建议这样做,因为一旦 Pod 被删除(失败的 Pod 或由于缩放操作),LoadBalancer 将无法将您的请求路由到该特定的 Pod。在这个问题中有解释:https://stackoverflow.com/questions/56323438

关于docker - 在 kubernetes 中的 asp.net 核心容器中登录重置/丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66091085/

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