Share via


Ocelot ile API Ağ Geçitleri Uygulama

İpucu

Bu içerik, .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan Kapsayıcılı .NET Uygulamaları için .NET Mikro Hizmet Mimarisi e-Kitabı'ndan bir alıntıdır.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Önemli

Başvuru mikro hizmet uygulaması eShopOnContainers şu anda, daha önce başvurulan Ocelot yerine API Gateway'i uygulamak için Envoy tarafından sağlanan özellikleri kullanıyor. Envoy'un WebSocket protokolü için eShopOnContainers'da uygulanan yeni gRPC hizmetler arası iletişimler için gerekli olan yerleşik desteği nedeniyle bu tasarım seçimini yaptık. Ancak, Ocelot'u üretim sınıfı senaryolara uygun basit, yetenekli ve basit bir API Gateway olarak düşünebilmeniz için kılavuzda bu bölümü koruduk. Ayrıca en son Ocelot sürümü, json şemasında hataya neden olan bir değişiklik içerir. Ocelot < v16.0.0 kullanmayı göz önünde bulundurun veya ReRoutes yerine anahtar Routes'u kullanın.

API Gateway'lerinizi tasarlama ve tasarlama

Aşağıdaki mimari diyagramında API Gateway'lerin eShopOnContainers'da Ocelot ile nasıl uygulandığı gösterilmektedir.

Diagram showing the eShopOnContainers architecture.

Şekil 6-28. API Ağ Geçitleri ile eShopOnContainers mimarisi

Bu diyagram, uygulamanın tamamının "Windows için Docker" veya "Mac için Docker" ile tek bir Docker konağına veya geliştirme bilgisayarına nasıl dağıtıldığını gösterir. Bununla birlikte, herhangi bir düzenleyiciye dağıtım benzer olabilir, ancak diyagramdaki tüm kapsayıcılar orchestrator'da ölçeklendirilebilir.

Ayrıca veritabanları, önbellek ve ileti aracıları gibi altyapı varlıkları düzenleyiciden boşaltılmalı ve Azure SQL Veritabanı, Azure Cosmos DB, Azure Redis, Azure Service Bus veya şirket içi herhangi bir HA kümeleme çözümü gibi altyapı için yüksek kullanılabilir sistemlere dağıtılmalıdır.

Diyagramda da fark ettiğiniz gibi, birkaç API Gateway'e sahip olmak, mikro hizmetlerini ve kendi ilgili API Gateway'lerini geliştirirken ve dağıtırken birden çok geliştirme takımının otonom olmasına (bu örnekte Pazarlama özellikleri ve Alışveriş özellikleri) olanak tanır.

Tek bir monolitik API Gateway'iniz varsa, bu da tüm mikro hizmetleri uygulamanın tek bir bölümüyle birleştirilebilir ve birkaç geliştirme ekibi tarafından güncelleştirilecek tek bir nokta anlamına gelir.

Tasarımda çok daha ileri giderek, bazen ayrıntılı bir API Gateway, seçilen mimariye bağlı olarak tek bir iş mikro hizmetiyle de sınırlandırılabilir. API Gateway sınırlarının işletme veya etki alanı tarafından dikte edilmiş olması, daha iyi bir tasarım elde etmenize yardımcı olur.

Örneğin, API Gateway katmanındaki ince taneciklik, özellikle mikro hizmetleri temel alan daha gelişmiş bileşik UI uygulamaları için yararlı olabilir çünkü ayrıntılı API Gateway kavramı kullanıcı arabirimi oluşturma hizmetine benzer.

Önceki bölümde mikro hizmetlere dayalı bileşik kullanıcı arabirimi oluşturma bölümünde daha fazla ayrıntıya göz atacağız.

Önemli bir çözüm olarak, birçok orta ve büyük boyutlu uygulama için özel yerleşik API Gateway ürünü kullanmak genellikle iyi bir yaklaşımdır, ancak API Gateway otonom mikro hizmetler oluşturan çeşitli geliştirme ekipleri için birden fazla bağımsız yapılandırma alanına izin vermediği sürece tek bir monolitik toplayıcı veya benzersiz bir merkezi özel API Gateway olarak değildir.

API Ağ Geçitleri aracılığıyla yeniden yönlendirecek örnek mikro hizmetler/kapsayıcılar

Örneğin, eShopOnContainers aşağıdaki görüntüde gösterildiği gibi API Gateway'ler aracılığıyla yayımlanması gereken yaklaşık altı iç mikro hizmet türüne sahiptir.

Screenshot of the Services folder showing its subfolders.

Şekil 6-29. Visual Studio'da eShopOnContainers çözümündeki mikro hizmet klasörleri

Kimlik hizmeti hakkında, tasarımda API Gateway yönlendirmesinin dışında bırakılır çünkü sistemdeki tek çapraz kesme sorunu bu olsa da, Ocelot ile yeniden yönlendirme listelerine dahil etmek de mümkündür.

Koddan anlayabileceğiniz gibi bu hizmetlerin tümü şu anda ASP.NET Core Web API hizmetleri olarak uygulanıyor. Katalog mikro hizmet kodu gibi mikro hizmetlerden birine odaklanalım.

Screenshot of Solution Explorer showing Catalog.API project contents.

Şekil 6-30. Örnek Web API mikro hizmeti (Katalog mikro hizmeti)

Katalog mikro hizmetinin aşağıdaki kodda olduğu gibi çeşitli denetleyicilere ve yöntemlere sahip tipik bir ASP.NET Core Web API projesi olduğunu görebilirsiniz.

[HttpGet]
[Route("items/{id:int}")]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType(typeof(CatalogItem),(int)HttpStatusCode.OK)]
public async Task<IActionResult> GetItemById(int id)
{
    if (id <= 0)
    {
        return BadRequest();
    }
    var item = await _catalogContext.CatalogItems.
                                          SingleOrDefaultAsync(ci => ci.Id == id);
    //…

    if (item != null)
    {
        return Ok(item);
    }
    return NotFound();
}

HTTP isteği, mikro hizmet veritabanına erişen bu tür C# kodunu ve gerekli ek eylemleri çalıştırır.

Mikro hizmet URL'si ile ilgili olarak, kapsayıcılar yerel geliştirme bilgisayarınıza (yerel Docker konağı) dağıtıldığında, her mikro hizmetin kapsayıcısının her zaman dockerfile dosyasında belirtilen bir iç bağlantı noktası (genellikle 80 numaralı bağlantı noktası) aşağıdaki dockerfile dosyasında olduğu gibi bulunur:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

Kodda gösterilen 80 numaralı bağlantı noktası Docker konağı içindedir, bu nedenle istemci uygulamaları tarafından ulaşılamaz.

İstemci uygulamaları ile docker-composedağıtılırken yalnızca yayımlanan dış bağlantı noktalarına (varsa) erişebilir.

Bu dış bağlantı noktaları bir üretim ortamına dağıtılırken yayımlanmamalıdır. Bu özel nedenden dolayı, istemci uygulamalarıyla mikro hizmetler arasındaki doğrudan iletişimi önlemek için API Gateway'i kullanmak istiyorsunuz.

Ancak, geliştirirken mikro hizmete/kapsayıcıya doğrudan erişmek ve Swagger aracılığıyla çalıştırmak istiyorsunuz. Bu nedenle eShopOnContainers'da dış bağlantı noktaları, API Gateway veya istemci uygulamaları tarafından kullanılmayacak olsalar bile yine de belirtilir.

Aşağıda Katalog mikro hizmeti için bir dosya örneği docker-compose.override.yml verilmişti:

catalog-api:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - ASPNETCORE_URLS=http://0.0.0.0:80
    - ConnectionString=YOUR_VALUE
    - ... Other Environment Variables
  ports:
    - "5101:80"   # Important: In a production environment you should remove the external port (5101) kept here for microservice debugging purposes.
                  # The API Gateway redirects and access through the internal port (80).

docker-compose.override.yml yapılandırmasında Katalog kapsayıcısının iç bağlantı noktasının 80 numaralı bağlantı noktası olduğunu ancak dış erişim bağlantı noktasının 5101 olduğunu görebilirsiniz. Ancak bu bağlantı noktası, uygulama tarafından API Gateway kullanılırken kullanılmamalıdır; yalnızca Katalog mikro hizmetinin hatalarını ayıklamak, çalıştırmak ve test etmek için kullanılmalıdır.

Normalde, mikro hizmetler için doğru üretim dağıtım ortamı Kubernetes veya Service Fabric gibi bir düzenleyici olduğundan docker-compose ile üretim ortamına dağıtım yapmazsınız. Bu ortamlara dağıtım yaparken, mikro hizmetler için doğrudan herhangi bir dış bağlantı noktası yayımlamayacağınız farklı yapılandırma dosyaları kullanırsınız, ancak her zaman API Gateway'den ters ara sunucuyu kullanırsınız.

Katalog mikro hizmetini yerel Docker konağınızda çalıştırın. Visual Studio'dan tam eShopOnContainers çözümünü çalıştırın (docker-compose dosyalarındaki tüm hizmetleri çalıştırır) veya CMD'de aşağıdaki docker-compose komutuyla Katalog mikro hizmetini başlatın veya ve'nin docker-compose.override.yml yerleştirildiği docker-compose.yml klasörde bulunan PowerShell'de aşağıdaki docker-compose komutunu kullanın.

docker-compose run --service-ports catalog-api

Bu komut yalnızca catalog-api hizmet kapsayıcısını ve docker-compose.yml belirtilen bağımlılıkları çalıştırır. Bu durumda, SQL Server kapsayıcısı ve RabbitMQ kapsayıcısı.

Ardından Doğrudan Katalog mikro hizmetine erişebilir ve yöntemlerini doğrudan bu "dış" bağlantı noktası üzerinden erişen Swagger kullanıcı arabirimi aracılığıyla görebilirsiniz. Bu durumda http://host.docker.internal:5101/swagger:

Screenshot of Swagger UI showing the Catalog.API REST API.

Şekil 6-31. Swagger kullanıcı arabirimiyle Katalog mikro hizmetini test etme

Bu noktada Visual Studio'da C# kodunda bir kesme noktası ayarlayabilir, mikro hizmeti Swagger kullanıcı arabiriminde kullanıma sunulan yöntemlerle test edebilir ve son olarak komutuyla docker-compose down her şeyi temizleyebilirsiniz.

Ancak, mikro hizmetle doğrudan erişim iletişimi, bu durumda dış bağlantı noktası 5101 aracılığıyla, uygulamanızda tam olarak kaçınmak istediğiniz şey. Api Gateway'in ek dolaylı düzeyini ayarlayarak bunu önleyebilirsiniz (bu örnekte Ocelot). Bu şekilde, istemci uygulaması mikro hizmete doğrudan erişmez.

Ocelot ile API Gateway'lerinizi uygulama

Ocelot temel olarak belirli bir sırada uygulayabileceğiniz bir ara yazılım kümesidir.

Ocelot yalnızca ASP.NET Core ile çalışacak şekilde tasarlanmıştır. Paketin en son sürümü 18.0'dır ve .NET 6'yi hedefler ve bu nedenle .NET Framework uygulamaları için uygun değildir.

Visual Studio'dan Ocelot'un NuGet paketiyle ASP.NET Core projenize Ocelot'u ve bağımlılıklarını yüklersiniz.

Install-Package Ocelot

eShopOnContainers'da API Gateway uygulaması basit bir ASP.NET Core WebHost projesidir ve Ocelot'un ara yazılımı, aşağıdaki görüntüde gösterildiği gibi tüm API Gateway özelliklerini işler:

Screenshot of Solution Explorer showing Ocelot API gateway project.

Şekil 6-32. eShopOnContainers'da OcelotApiGw temel projesi

Bu ASP.NET Core WebHost projesi iki basit dosyayla derlenir: Program.cs ve Startup.cs.

Program.cs yalnızca tipik ASP.NET Core BuildWebHost'u oluşturması ve yapılandırması gerekir.

namespace OcelotApiGw
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args)
        {
            var builder = WebHost.CreateDefaultBuilder(args);

            builder.ConfigureServices(s => s.AddSingleton(builder))
                    .ConfigureAppConfiguration(
                          ic => ic.AddJsonFile(Path.Combine("configuration",
                                                            "configuration.json")))
                    .UseStartup<Startup>();
            var host = builder.Build();
            return host;
        }
    }
}

Ocelot için buradaki önemli nokta, oluşturucuya yöntemiyle AddJsonFile() sağlamanız gereken dosyadırconfiguration.json. Burada configuration.json tüm API Gateway ReRoute'larını belirtirsiniz; başka bir deyişle, genellikle farklı bağlantı noktaları kullanan belirli bağlantı noktalarına sahip dış uç noktalar ve bağıntılı iç uç noktalar.

{
    "ReRoutes": [],
    "GlobalConfiguration": {}
}

Yapılandırmada iki bölüm vardır. ReRoutes dizisi ve GlobalConfiguration. ReRoute'lar, Ocelot'a yukarı akış isteğini nasıl ele alacaklarını belirten nesnelerdir. Genel yapılandırma, ReRoute'a özgü ayarların geçersiz kılınmasına izin verir. Çok sayıda ReRoute özel ayarlarını yönetmek istemiyorsanız kullanışlıdır.

Aşağıda, eShopOnContainers API Gateway'lerinden birinden ReRoute yapılandırma dosyasının basitleştirilmiş bir örneği verilmiştir.

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "catalog-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/c/{everything}",
      "UpstreamHttpMethod": [ "POST", "PUT", "GET" ]
    },
    {
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "basket-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/b/{everything}",
      "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
    }

  ],
    "GlobalConfiguration": {
      "RequestIdKey": "OcRequestId",
      "AdministrationPath": "/administration"
    }
  }

Ocelot API Gateway'in temel işlevi, gelen HTTP isteklerini almak ve şu anda başka bir HTTP isteği olarak aşağı akış hizmetine iletmektir. Ocelot'lar, bir isteğin başka bir istekte Yeniden Yönlendirme olarak yönlendirilmesiyle ilgili açıklamalarda bulunur.

Örneğin, yukarıdan configuration.json, Sepet mikro hizmetinin yapılandırmasındaki ReRoutes'lardan birine odaklanalım.

{
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "basket-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/b/{everything}",
      "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
}

DownstreamPathTemplate, Scheme ve DownstreamHostAndPorts, bu isteğin iletileceği iç mikro hizmet URL'sini oluşturur.

Bağlantı noktası, hizmet tarafından kullanılan iç bağlantı noktasıdır. Kapsayıcılar kullanılırken, dockerfile dosyasında belirtilen bağlantı noktası.

Host, kullandığınız hizmet adı çözümlemesine bağlı olan bir hizmet adıdır. docker-compose kullanılırken, hizmet adları docker-compose dosyalarında sağlanan hizmet adlarını kullanan Docker Konağı tarafından sağlanır. Kubernetes veya Service Fabric gibi bir düzenleyici kullanılıyorsa, bu ad her düzenleyici tarafından sağlanan DNS veya ad çözümlemesi tarafından çözümlenmelidir.

DownstreamHostAndPorts, istekleri iletmek istediğiniz tüm aşağı akış hizmetlerinin ana bilgisayarını ve bağlantı noktasını içeren bir dizidir. Genellikle bu yapılandırma yalnızca bir giriş içerir, ancak bazen aşağı akış hizmetlerinize yönelik isteklerin yükünü dengelemek isteyebilirsiniz ve Ocelot birden fazla giriş eklemenize ve ardından bir yük dengeleyici seçmenize olanak tanır. Ancak Azure ve herhangi bir düzenleyici kullanıyorsanız bulut ve orchestrator altyapısıyla yük dengeleme yapmak muhtemelen daha iyi bir fikirdir.

UpstreamPathTemplate, Ocelot'un istemciden gelen belirli bir istek için hangi DownstreamPathTemplate'ın kullanılacağını belirlemek için kullanacağı URL'dir. Son olarak, Ocelot'un aynı URL'ye yönelik farklı istekleri (GET, POST, PUT) ayırt edebilmesi için Yukarı AkışHttpMethod kullanılır.

Bu noktada, bir veya birden çok birleştirilmiş configuration.json dosyası kullanarak tek bir Ocelot API Gateway 'iniz (ASP.NET Core WebHost) olabilir veya yapılandırmayı bir Consul KV deposunda da depolayabilirsiniz.

Ancak mimari ve tasarım bölümlerinde açıklandığı gibi, otonom mikro hizmetlere gerçekten sahip olmak istiyorsanız, tek tek tek API Ağ Geçidini birden çok API Gateway'e ve/veya BFF'ye (Ön Uç için Arka Uç) bölmek daha iyi olabilir. Bu amaçla Docker kapsayıcılarıyla bu yaklaşımın nasıl uygulandığını görelim.

Birden çok farklı API Gateway / BFF kapsayıcı türünü çalıştırmak için tek bir Docker kapsayıcı görüntüsü kullanma

eShopOnContainers'da Ocelot API Gateway ile tek bir Docker kapsayıcı görüntüsü kullanıyoruz, ancak çalışma zamanında farklı bir configuration.json dosyası sağlayarak her api-Gateway/BFF türü için farklı hizmetler/kapsayıcılar oluşturuyoruz ve her hizmet için farklı bir bilgisayar klasörüne erişmek için bir docker birimi kullanıyoruz.

Diagram of a single Ocelot gateway Docker image for all API gateways.

Şekil 6-33. Birden çok API Gateway türü arasında tek bir Ocelot Docker görüntüsünü yeniden kullanım

eShopOnContainers'da "Generic Ocelot API Gateway Docker Image", 'OcelotApiGw' adlı proje ve docker-compose.yml dosyasında belirtilen "eshop/ocelotapigw" görüntü adıyla oluşturulur. Ardından, Docker'a dağıtım yaparken, docker-compose.yml dosyasından aşağıdaki ayıklamada gösterildiği gibi aynı Docker görüntüsünden dört API-Gateway kapsayıcısı oluşturulur.

  mobileshoppingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

  mobilemarketingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

  webshoppingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

  webmarketingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

Ayrıca, aşağıdaki docker-compose.override.yml dosyasında görebileceğiniz gibi, bu API Gateway kapsayıcıları arasındaki tek fark, her hizmet kapsayıcısı için farklı olan ve bir Docker birimi aracılığıyla çalışma zamanında belirtilen Ocelot yapılandırma dosyasıdır.

mobileshoppingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5200:80"
  volumes:
    - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:/app/configuration

mobilemarketingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5201:80"
  volumes:
    - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:/app/configuration

webshoppingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5202:80"
  volumes:
    - ./src/ApiGateways/Web.Bff.Shopping/apigw:/app/configuration

webmarketingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5203:80"
  volumes:
    - ./src/ApiGateways/Web.Bff.Marketing/apigw:/app/configuration

Önceki kod nedeniyle ve aşağıdaki Visual Studio Gezgini'nde gösterildiği gibi, dört API Gateway aynı Docker görüntüsünü temel alan her bir iş/BFF API Gateway'i tanımlamak için gereken tek dosya yalnızca bir configuration.json dosyasıdır.

Screenshot showing all API gateways with configuration.json files.

Şekil 6-34. Ocelot ile her API Gateway /BFF'yi tanımlamak için gereken tek dosya bir yapılandırma dosyasıdır

API Gateway'i birden çok API Gateway'e bölerek, mikro hizmetlerin farklı alt kümelerine odaklanan farklı geliştirme ekipleri bağımsız Ocelot yapılandırma dosyalarını kullanarak kendi API Gateway'lerini yönetebilir. Ayrıca, aynı zamanda aynı Ocelot Docker görüntüsünü yeniden kullanabilirler.

Şimdi api Gateways ile eShopOnContainers çalıştırırsanız (eShopOnContainers-ServicesAndWebApps.sln çözümü açarken veya "docker-compose up" çalıştırırken varsayılan olarak VS'de bulunur), aşağıdaki örnek yollar gerçekleştirilir.

Örneğin, webshoppingapigw API Gateway tarafından sunulan yukarı akış URL'sini http://host.docker.internal:5202/api/v1/c/catalog/items/2/ ziyaret ettiğinizde, aşağıdaki tarayıcıda olduğu gibi Docker konağındaki iç Aşağı Akış URL'sinden http://catalog-api/api/v1/2 de aynı sonucu alırsınız.

Screenshot of a browser showing a response going through API gateway.

Şekil 6-35. API Gateway tarafından sağlanan bir URL aracılığıyla mikro hizmete erişme

Test veya hata ayıklama nedenlerinden dolayı, 'catalog-api' Docker konağına (docker-compose hizmet adları tarafından işlenen hizmet bulma) yönelik bir DNS çözümlemesi olduğundan, Api Gateway'den geçmeden Katalog Docker kapsayıcısına (yalnızca geliştirme ortamında) doğrudan erişmek istiyorsanız, kapsayıcıya doğrudan erişmenin tek yolu docker-compose.override.yml yayımlanan dış bağlantı noktası üzerinden, yalnızca aşağıdaki tarayıcıda olduğu gibi http://host.docker.internal:5101/api/v1/Catalog/items/1 geliştirme testleri için sağlanır.

Screenshot of a browser showing a direct response to the Catalog.api.

Şekil 6-36. Test amacıyla mikro hizmete doğrudan erişim

Ancak uygulama yapılandırıldığından, doğrudan bağlantı noktası "kısayolları" üzerinden değil API Gateway'ler aracılığıyla tüm mikro hizmetlere erişir.

eShopOnContainers'da Ağ Geçidi toplama düzeni

Daha önce de açıklandığı gibi, istek toplamayı uygulamanın esnek bir yolu, koda göre özel hizmetlerdir. Ocelot'taki İstek Toplama özelliğiyle istek toplama da uygulayabilirsiniz, ancak bu özellik ihtiyacınız olan kadar esnek olmayabilir. Bu nedenle, eShopOnContainers'da toplama uygulamak için seçilen yol, her toplayıcı için açık bir ASP.NET Core Web API hizmetidir.

Bu yaklaşıma göre API Gateway oluşturma diyagramı, daha önce gösterilen basitleştirilmiş genel mimari diyagramında gösterilmeyen toplayıcı hizmetleri göz önünde bulundurulduğunda gerçekte biraz daha genişletilmiştir.

Aşağıdaki diyagramda, toplayıcı hizmetlerinin ilgili API Gateway'leriyle nasıl çalıştığını da görebilirsiniz.

Diagram of eShopOnContainers architecture showing aggregator services.

Şekil 6-37. Toplayıcı hizmetleriyle eShopOnContainers mimarisi

Daha da yakınlaştırarak, aşağıdaki görüntüdeki "Alışveriş" iş alanında, API Gateway'lerde toplayıcı hizmetleri kullanılırken istemci uygulamaları ile mikro hizmetler arasındaki sohbetin azaldığını görebilirsiniz.

Diagram showing eShopOnContainers architecture zoom in.

Şekil 6-38. Toplayıcı hizmetlerinin vizyonunu yakınlaştırma

Diyagramda API Gateway'lerden gelen olası isteklerin nasıl karmaşık hale gelebileceğini fark edebilirsiniz. Öte yandan, toplayıcı desenini kullandığınızda mavi renkli okların istemci uygulaması perspektifinden iletişimi nasıl basitleştireceğini görebilirsiniz. Bu desen, iletişimdeki sohbeti ve gecikme süresini azaltmaya yardımcı olmakla birlikte, uzak uygulamalar (mobil ve SPA uygulamaları) için kullanıcı deneyimini önemli ölçüde geliştirir.

"Pazarlama" iş alanı ve mikro hizmetler söz konusu olduğunda, basit bir kullanım örneğidir, bu nedenle toplayıcıları kullanmaya gerek yoktu, ancak gerekirse bu da mümkün olabilir.

Ocelot API Ağ Geçitlerinde kimlik doğrulaması ve yetkilendirme

Ocelot API Gateway'de, kimlik doğrulama belirtecini api Gateway'in dışında veya içinde sağlayan IdentityServer kullanarak ASP.NET Core Web API hizmeti gibi kimlik doğrulama hizmetini kullanabilirsiniz.

eShopOnContainers, BFF ve iş alanlarına dayalı sınırları olan birden çok API Gateway kullandığından, Kimlik/Kimlik Doğrulama hizmeti aşağıdaki diyagramda sarıyla vurgulandığı gibi API Gateway'lerin dışında bırakılır.

Diagram showing Identity microservice beneath the API gateway.

Şekil 6-39. eShopOnContainers'da Kimlik hizmetinin konumu

Ancak Ocelot, bu diğer diyagramda olduğu gibi API Gateway sınırında Identity/Auth mikro hizmetinin oturmasını da destekler.

Diagram showing authentication in an Ocelot API Gateway.

Şekil 6-40. Ocelot'ta kimlik doğrulaması

Önceki diyagramda gösterildiği gibi, Kimlik mikro hizmeti API ağ geçidinin (AG) altında olduğunda: 1) AG kimlik mikro hizmetten kimlik doğrulama belirteci ister, 2) Kimlik mikro hizmeti kimlik doğrulama belirtecini kullanarak mikro hizmetlerden ag, 3-4) AG isteklerine belirteç döndürür. eShopOnContainers uygulaması API Gateway'i birden çok BFF (Ön Uç için Arka Uç) ve iş alanları API Gateway'lerine böldüğünden, çapraz kesme endişeleri için ek bir API Gateway oluşturmak başka bir seçenek olurdu. Bu seçim, birden çok çapraz kesme sorunu mikro hizmet ile daha karmaşık bir mikro hizmet tabanlı mimaride adil olacaktır. eShopOnContainers'da tek bir çapraz kesme sorunu olduğundan, basitlik adına yalnızca API Gateway bölgesi dışında güvenlik hizmetini işlemeye karar verildi.

Her durumda, uygulama API Gateway düzeyinde güvenlik altına alınırsa, güvenli bir mikro hizmet kullanılmaya çalışılırken ilk olarak Ocelot API Gateway'in kimlik doğrulama modülü ziyaret edilir. Bu, http isteğini kimlik veya kimlik doğrulama mikro hizmetini ziyaret etmek üzere yönlendirir ve böylece access_token korumalı hizmetleri ziyaret edebilmeniz için erişim belirtecini alır.

API Gateway düzeyindeki herhangi bir hizmetin kimlik doğrulamasıyla güvenliğini sağlamanın yolu, configuration.json ilgili ayarlarında AuthenticationProviderKey'i ayarlamaktır.

    {
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "basket-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/b/{everything}",
      "UpstreamHttpMethod": [],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
    }

Ocelot çalıştırıldığında ReRoutes AuthenticationOptions.AuthenticationProviderKey'e bakar ve verilen anahtarla kaydedilmiş bir Kimlik Doğrulama Sağlayıcısı olup olmadığını denetler. Yoksa Ocelot başlatılmaz. Varsa, ReRoute yürütürken bu sağlayıcıyı kullanır.

Ocelot WebHost ile authenticationProviderKey = "IdentityApiKey"yapılandırıldığından, hizmetin kimlik doğrulama belirteci olmadan herhangi bir isteği olduğunda kimlik doğrulaması gerektirir.

namespace OcelotApiGw
{
    public class Startup
    {
        private readonly IConfiguration _cfg;

        public Startup(IConfiguration configuration) => _cfg = configuration;

        public void ConfigureServices(IServiceCollection services)
        {
            var identityUrl = _cfg.GetValue<string>("IdentityUrl");
            var authenticationProviderKey = "IdentityApiKey";
                         //…
            services.AddAuthentication()
                .AddJwtBearer(authenticationProviderKey, x =>
                {
                    x.Authority = identityUrl;
                    x.RequireHttpsMetadata = false;
                    x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                    {
                        ValidAudiences = new[] { "orders", "basket", "locations", "marketing", "mobileshoppingagg", "webshoppingagg" }
                    };
                });
            //...
        }
    }
}

Ardından, aşağıdaki Sepet mikro hizmet denetleyicisinde olduğu gibi mikro hizmetler gibi erişilecek herhangi bir kaynakta [Authorize] özniteliğiyle yetkilendirme ayarlamanız gerekir.

namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
{
    [Route("api/v1/[controller]")]
    [Authorize]
    public class BasketController : Controller
    {
      //...
    }
}

"Sepet" gibi ValidAudience'lar, aşağıdaki kodda olduğu gibi Başlangıç sınıfının ConfigureServices() içinde ile her mikro hizmette tanımlanan hedef kitleyle AddJwtBearer() ilişkilendirilir.

// prevent from mapping "sub" claim to nameidentifier.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

var identityUrl = Configuration.GetValue<string>("IdentityUrl");

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

}).AddJwtBearer(options =>
{
    options.Authority = identityUrl;
    options.RequireHttpsMetadata = false;
    options.Audience = "basket";
});

Gibi http://host.docker.internal:5202/api/v1/b/basket/1API Gateway'i temel alan bir ReRoute URL'si ile Sepet mikro hizmeti gibi güvenli bir mikro hizmete erişmeye çalışırsanız, geçerli bir belirteç sağlamadığınız sürece 401 Yetkisiz alırsınız. Öte yandan, bir Yeniden Yönlendirme URL'si doğrulanırsa, Ocelot onunla ilişkili aşağı akış düzenini (iç mikro hizmet URL'si) çağırır.

Ocelot'un ReRoutes katmanında yetkilendirme. Ocelot, kimlik doğrulamasından sonra değerlendirilen talep tabanlı yetkilendirmeyi destekler. ReRoute yapılandırmasına aşağıdaki satırları ekleyerek yetkilendirmeyi bir yol düzeyinde ayarlarsınız.

"RouteClaimsRequirement": {
    "UserType": "employee"
}

Bu örnekte, yetkilendirme ara yazılımı çağrıldığında Ocelot, kullanıcının belirteçte 'UserType' talep türüne sahip olup olmadığını ve bu talebin değerinin 'çalışan' olup olmadığını bulur. Değilse, kullanıcı yetkilendirilmeyecek ve yanıt 403 yasak olacaktır.

Kubernetes Giriş artı Ocelot API Ağ Geçitlerini kullanma

Kubernetes kullanırken (Azure Kubernetes Service kümesinde olduğu gibi), genellikle Nginx tabanlı Kubernetes Giriş katmanı aracılığıyla tüm HTTP isteklerini bir araya getirebilirsiniz.

Kubernetes'te herhangi bir giriş yaklaşımı kullanmıyorsanız hizmetleriniz ve podlarınız yalnızca küme ağı tarafından yönlendirilebilen IP'lere sahiptir.

Ancak bir giriş yaklaşımı kullanırsanız, İnternet ile hizmetleriniz (API Gateway'leriniz dahil) arasında ters ara sunucu olarak çalışan bir orta katmana sahip olursunuz.

Bir tanım olarak, Giriş, gelen bağlantıların küme hizmetlerine erişmesine izin veren bir kural koleksiyonudur. Giriş, hizmetlere dışarıdan erişilebilen URL'ler, yük dengeleme trafiği, SSL sonlandırma ve daha fazlasını sağlayacak şekilde yapılandırılır. Kullanıcılar, Giriş kaynağını API sunucusuna sunarak giriş isteğinde bulunur.

eShopOnContainers'da yerel olarak geliştirme yaparken ve docker konağı olarak yalnızca geliştirme makinenizi kullanırken herhangi bir giriş değil, yalnızca birden çok API Ağ Geçidi kullanıyorsunuz.

Ancak, Kubernetes tabanlı bir "üretim" ortamını hedeflerken, eShopOnContainers API ağ geçitlerinin önünde bir giriş kullanıyor. Bu şekilde, istemciler yine aynı temel URL'yi çağırır, ancak istekler birden çok API Gateway'e veya BFF'ye yönlendirilir.

API Gateway'ler yalnızca hizmetleri kullanan ön uçlar veya cephelerdir, ancak genellikle kapsamları dışında olan web uygulamalarını kapsamaz. Buna ek olarak, API Ağ Geçitleri bazı iç mikro hizmetleri gizleyebilir.

Ancak giriş yalnızca HTTP isteklerini yeniden yönlendiriyor ancak herhangi bir mikro hizmeti veya web uygulamasını gizlemeye çalışmıyor.

Aşağıdaki diyagramda gösterildiği gibi, Web uygulamalarının yanı sıra çeşitli Ocelot API Gateways / BFF'nin önünde Kubernetes'te bir giriş Nginx katmanına sahip olmak ideal mimaridir.

A diagram showing how an ingress tier fits into the AKS environment.

Şekil 6-41. Kubernetes'e dağıtıldığında eShopOnContainers'daki giriş katmanı

Kubernetes Girişi, Api ağ geçidi kapsamı dışında olan web uygulamaları da dahil olmak üzere uygulamaya yönelik tüm trafik için ters ara sunucu işlevi görür. Kubernetes'e eShopOnContainers dağıttığınızda, giriş yoluyla yalnızca birkaç hizmeti veya uç noktayı kullanıma sunar; temelde URL'lerdeki aşağıdaki postfixes listesidir:

  • / istemci SPA web uygulaması için
  • /webmvc istemci MVC web uygulaması için
  • /webstatus durum/sistem durumu denetimlerini gösteren istemci web uygulaması için
  • /webshoppingapigw web BFF ve alışveriş iş süreçleri için
  • /webmarketingapigw web BFF ve pazarlama iş süreçleri için
  • /mobileshoppingapigw mobil BFF ve alışveriş iş süreçleri için
  • /mobilemarketingapigw mobil BFF ve pazarlama iş süreçleri için

Kubernetes'e dağıtım yaparken her Ocelot API Gateway, API Gateway'leri çalıştıran her pod için farklı bir "configuration.json" dosyası kullanıyor. Bu "configuration.json" dosyaları, 'ocelot' adlı bir Kubernetes yapılandırma eşlemesi temelinde oluşturulan bir birimi bağlayarak (başlangıçta deploy.ps1 betiğiyle) sağlanır. Her kapsayıcı, ilgili yapılandırma dosyasını kapsayıcının adlı /app/configurationklasörüne bağlar.

eShopOnContainers kaynak kodu dosyalarında, özgün "configuration.json" dosyaları klasörün içinde k8s/ocelot/ bulunabilir. Her BFF/APIGateway için bir dosya vardır.

Ocelot API Gateway'de ek çapraz kesme özellikleri

Aşağıdaki bağlantılarda açıklanan, Ocelot API Gateway kullanırken araştırıp kullanmanız gereken başka önemli özellikler de vardır.