Внутренние проблемы CORS в Kubernetes между службами - PullRequest
0 голосов
/ 12 мая 2019

1

Я пытаюсь сделать http-запрос от моего развертывания / pods внешнего интерфейса (приложение Angular 7, работающее внутри NGINX) к моей внутренней службе (NET Core WEB API).

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"
};

В моем 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();
        }
    }
}

Итак, возникает проблема: когда я делаю запрос, я получаю следующую ошибку консоли на угловой стороне:

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.

Примечания:

  • Все другие сервисы в кластере могут нормально взаимодействовать (т. Е. WEB API с MySQL, используя тот же подход)
  • Эти два контейнера могут разговаривать друг с другом, когда я запускаю их локально
  • Обе эти службы работают на 100%, когда я обращаюсь к ним по отдельности

Я думаю о реализации входа в API, но мое понимание того, что для этого нужно, ограничено.

Любая помощь будет оценена. Спасибо.

EDIT

Я использую следующие заголовки как часть моего углового запроса:

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

1 Ответ

4 голосов
/ 12 мая 2019

Хотя на первый взгляд все выглядит просто, есть много способов решить ваши проблемы. Сначала немного информации о CORS: браузер автоматически добавляет заголовок X-Requested-With, нет необходимости добавлять его в ваш угловой запрос. Браузер будет искать Access-Control-Allow-Origin в заголовках response - в противном случае вы можете указать браузеру доверять чему угодно, в точности, что мешает CORS. (Серверная сторона должна решить, разрешены ли запросы) Итак, если вы хотите включить CORS, вам нужно настроить это в вашем приложении asp.net, что вы и сделали

        app.UseCors( options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

Но вам не нужен CORS - ваша установка тщательно продумана, чтобы избежать необходимости: CORS станет активным только тогда, когда вы сделаете запрос из разных источников. Вы настроили обратный прокси-сервер nginx таким образом, чтобы можно было запрашивать API из того же источника, куда вы загрузили приложение Angular.

Причина, по которой это не работает, заключается в том, что ваш браузер не может подключиться к внутреннему имени хоста kubernetes k8s-demo-api, поскольку это внутреннее имя в кластере kubernetes.

Я предполагаю, что вы добавили hostPort в контейнер вашего модуля внешнего интерфейса, и что nginx работает на порте 4200, обслуживающем приложение Angular по корневому пути, а обратный путь прокси - /api.

Самое простое решение, если все остальные настройки работают: измените URL для API, чтобы использовать созданный обратный путь прокси

 api_url: "http://192.168.99.100:4200/api"

На скриншоте видно, что вы пытаетесь запросить API без надлежащего протокола (в данном случае http: //), убедитесь, что Angular HttpClient настроен правильно.

...