如何配置 ASP.NET 核心多微服务应用程序和 Azure AKS 入口路由,使其不会中断 wwwroot 文件夹中的资源



我有两个 ASP.NET 核心应用程序。一个是无头CMS(API(,另一个是Razor Pages博客前端(带有与无头CMS/API通信的REST客户端(。

然后,我有一个 Azure AKS 群集。在其中,我有一个具有以下路由的入口资源(根据以下AKS文档中的说明:https://learn.microsoft.com/en-us/azure/aks/ingress-tls#create-an-ingress-route(。每个路由都映射到上述每个应用/服务:

spec:
rules:
- host: mydomain.westeurope.cloudapp.azure.com
http:
paths:
- backend:
serviceName: headless-cms-svc
servicePort: 80
path: /
- backend:
serviceName: blog-svc
servicePort: 80
path: /blog

当我现在导航到第一个路由时,mydomain.westeurope.cloudapp.azure.com,无头CMS应用程序按预期工作,但是当我导航到第二条路由时,mydomain.westeurope.cloudapp.azure.com/blog,我得到了一堆404:s,因为博客应用程序的根路径现在相对于/blog入口路由,这反过来又破坏了所有资源(css, JavaScript,图像等(在wwwroot文件夹中。

应如何配置 ASP.NET Core 博客应用和/或入口对象?

404:秒

https://mydomain.westeurope.cloudapp.azure.com/css/site.min.css?v=kHvJwvVAK1eJLN4w8xygUR3nbvlLmRwi5yr-OuAO90E
https://mydomain.westeurope.cloudapp.azure.com/images/banner1.svg
https://mydomain.westeurope.cloudapp.azure.com/images/banner2.svg
https://mydomain.westeurope.cloudapp.azure.com/js/site.min.js?v=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU

如果我添加 URL 段/blog资源将得到正确服务。https://mydomain.westeurope.cloudapp.azure.com/blog/images/banner1.svg<- 作品

这是Index.cshtmlRazor页面中的常规img标签(来自默认的 ASP.NET Core 2.1 Razor Pages Web应用程序(。我没有更改代码中的任何内容。

<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />

问题

您的代理似乎重写了路径。

  • 在代理之前:/blog/images/banner1.png
  • 代理后:/图像/横幅1.png

Asp 生成绝对(主机相对(链接(仅路径,但以斜杠"/"开头(。这意味着,我们必须告诉框架,它必须在所有URL前面加上"/blog"。

溶液

通过在 Startup 类中插入以下截图来执行此操作(对于 asp.net 核心 2.1(:

app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/blog");
return next();
});

代码示例来自: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1

将此截图插入到配置方法中的任何其他中间件之前。

您也可以在本地计算机上对此进行测试。所有生成的链接都应以"/blog"为前缀 - 因此它们将在开发计算机上断开。

使用配置

您需要使其可配置,例如:

var basePath = Configuration.GetSection("BASE_PATH").Value;
if (basePath != null)
{
Console.WriteLine($"Using base path '{basePath}'");
// app.Use().. goes here
}

(假设您在启动时从 env vars 读取配置。

。并在您的 Kubernetes Deoyment 中提供此 env var:

...
containers:
- name: myapp
image: myappimage
env:
- name: BASE_PATH
value: "/blog"

你想用nginx.ingress.kubernetes.io/rewrite-target注释你的入口。例如:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: mydnsname.westeurope.cloudapp.azure.com
http:
paths:
- backend:
serviceName: headless-cms-svc
servicePort: 80
path: /
- backend:
serviceName: blog-svc
servicePort: 80
path: /blog

希望对您有所帮助!

按照以下步骤运行代码:

  1. 部署:在K8S-yaml文件中传递具有路径基础的环境变量
apiVersion: apps/v1
kind: Deployment
# ..
spec:
# ..
template:
# ..
spec:
# ..
containers:
- name: test01
image: test.io/test:dev
# ...
env:
# define custom Path Base (it should be the same as 'path' in Ingress-service)
- name: API_PATH_BASE # <---
value: "blog"
  1. 程序:在程序中启用加载环境参数.cs
var builder = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
// ..
.ConfigureAppConfiguration((hostingContext, config) =>
{
// ..  
config.AddEnvironmentVariables(); // <---
// ..
})
// ..
  1. startup:在Startup中应用UsePathBaseMiddleware.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
private readonly IConfiguration _configuration;
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var pathBase = _configuration["API_PATH_BASE"]; // <---
if (!string.IsNullOrWhiteSpace(pathBase))
{
app.UsePathBase($"/{pathBase.TrimStart('/')}");
}
app.UseStaticFiles(); // <-- StaticFilesMiddleware must follow UsePathBaseMiddleware
// ..
app.UseMvc();
}
// ..
}

相关内容

  • 没有找到相关文章

最新更新