Kubernetes 服务之间的内部 CORS 问题

Bar*_*end 1 nginx kubernetes asp.net-core-webapi angular angular7

1

我试图从我的前端部署/pod(在 NGINX 中运行的 Angular 7 应用程序)向我的后端服务(NET Core WEB API)发出一个 http 请求。

URL,如图所示,是http://k8s-demo-api:8080/api/data

//environment.prod.ts in Angular App

export const environment = {
  production: true,
  api_url: "http://k8s-demo-api:8080/api"
};
Run Code Online (Sandbox Code Playgroud)

我的 API 中启用了 CORS:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using K8SDockerCoreWebApi.Contexts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace K8SDockerCoreWebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.Add(new ServiceDescriptor(typeof(K8SDemoContext), new K8SDemoContext(Configuration.GetConnectionString("DefaultConnection"))));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseCors( options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
            app.UseMvc();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以问题来了,当我提出请求时,我在 Angular 端收到以下控制台错误:

2

如果上面的图像有任何问题,错误基本上是:

Access to XMLHttpRequest at 'k8s-demo-api:8080/api/data' from origin 'http://192.168.99.100:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 集群内的所有其他服务都可以正常通信(即 WEB API 与 MySQL 使用相同的方法)
  • 当我在本地运行这两个容器时,它们可以相互通信
  • 当我单独访问它们时,这两个服务都运行 100%

我正在考虑在 API 上实现一个入口,但我对这将完成什么的理解是有限的。

任何帮助将不胜感激。谢谢。

编辑

我使用以下标头作为我的 Angular 请求的一部分:

headers: new HttpHeaders({
  'Content-Type': 'application/json',
  'X-Requested-With': 'XMLHttpRequest',
  'Access-Control-Allow-Origin' : '*'
})
Run Code Online (Sandbox Code Playgroud)

Tho*_*mas 5

虽然乍一看很简单,但有很多方法可以解决您的问题。首先是 CORS 的一些背景:浏览器会自动添加 X-Requested-With 标头,无需在您的 Angular 请求中添加它。浏览器将在响应标头中查找 Access-Control-Allow-Origin - 否则您可以告诉浏览器信任任何内容,这正是 CORS 阻止的内容。(服务器端必须决定是否允许请求)所以,如果你想启用 CORS,你需要在你的 asp.net 应用程序中配置它,你所做的

        app.UseCors( options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
Run Code Online (Sandbox Code Playgroud)

但是您不需要 CORS - 您的设置经过精心构建以避免需要:CORS 仅在您发出跨域请求时才会变为活动状态。您以这种方式配置了 nginx 反向代理,您可以从加载 Angular 应用程序的同一来源请求 API。

这不起作用的原因是您的浏览器无法连接到内部 kubernetes 主机名,k8s-demo-api因为这是 kubernetes 集群中的内部名称。

我假设您在前端 pod 的容器中添加了一个 hostPort,并且 nginx 在端口 4200 上运行,为根路径上的 Angular 应用程序提供服务,而反向代理路径为/api.

最简单的解决方案,因为您的其余设置都在工作:更改 API 的 URL 以使用创建的反向代理路径

 api_url: "http://192.168.99.100:4200/api"
Run Code Online (Sandbox Code Playgroud)

从屏幕截图来看,您似乎试图在没有正确协议的情况下请求 api(在本例中为 http://),请确保正确配置了 Angular HttpClient。

  • 这样做的问题是下次更新时,IP 会发生变化。入口控制器将是正确的选择。 (2认同)