ThreeMammals / Ocelot

.NET API Gateway
https://www.nuget.org/packages/Ocelot
MIT License
8.38k stars 1.64k forks source link

Kubernetes service discovery doesn't work with ingress controller? #1397

Closed akoken closed 3 years ago

akoken commented 3 years ago

Expected Behavior / New Feature

I am using Ocelot to create an API gateway for microservices running in Kubernetes environment. There is also an Ingress Controller in front of services. I can access services over ingress controller. E.g. curl http://myserver/service-name/health. When I request to service (http://myserver:80/apigateway/service-name/health) over API Gateway, I expect Ocelot to route it by resolving from service name.

Actual Behavior / Motivation for New Feature

I get an exception in gateway microservice as follows: "UnableToFindLoadBalancerError Message: unabe to find load balancer for /service-name/health|Get,Post,Put| exception is KubeClient.KubeClientException: Invalid KubeClientOptions: must specify a valid API end-point."

_Request starting HTTP/1.1 GET http://myserver:80/service-name/health application/json-patch+json dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: ocelot pipeline started dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: Upstream url path is /service-name/health dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: downstream templates are /health info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET http://172.14.41.4:80/swagger/index.html info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 0.2944ms 200 text/html;charset=utf-8 info: Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for /health info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: No authentication needed for /service-name/health info: Ocelot.Authorisation.Middleware.AuthorisationMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: /health route does not require user to be authorised dbug: Ocelot.LoadBalancer.Middleware.LoadBalancingMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: there was an error retriving the loadbalancer, setting pipeline error warn: Ocelot.Responder.Middleware.ResponderMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: Error Code: UnableToFindLoadBalancerError Message: unabe to find load balancer for /service-name/health|Get,Post,Put| exception is KubeClient.KubeClientException: Invalid KubeClientOptions: must specify a valid API end-point. at KubeClient.KubeClientOptions.EnsureValid() at KubeClient.KubeApiClient.Create(KubeClientOptions options) at KubeClient.ClientRegistrationExtensions.<>c.gResolveWithOptions|0_1(IServiceProvider serviceProvider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.b0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at Ocelot.Provider.Kubernetes.KubernetesProviderFactory.GetKubeProvider(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamRoute route, IOcelotLoggerFactory factory) at Ocelot.Provider.Kubernetes.KubernetesProviderFactory.<>c.<.cctor>b__2_0(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamRoute route) at Ocelot.Provider.Kubernetes.OcelotBuilderExtensions.<>c.<.cctor>b__40(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamRoute reroute) in /app/src/Flex.ApiGateway/OcelotBuilderExtensions.cs:line 16 at Ocelot.ServiceDiscovery.ServiceDiscoveryProviderFactory.GetServiceDiscoveryProvider(ServiceProviderConfiguration config, DownstreamRoute route) at Ocelot.ServiceDiscovery.ServiceDiscoveryProviderFactory.Get(ServiceProviderConfiguration serviceConfig, DownstreamRoute route) at Ocelot.LoadBalancer.LoadBalancers.LoadBalancerFactory.Get(DownstreamRoute route, ServiceProviderConfiguration config) at Ocelot.LoadBalancer.LoadBalancers.LoadBalancerHouse.Get(DownstreamRoute route, ServiceProviderConfiguration config) errors found in ResponderMiddleware. Setting error response for request path:/service-name/health, request method: GET dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0] requestId: 0HM53BV3N856E:00000001, previousRequestId: no previous request id, message: ocelot pipeline finished info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 745.0592ms 404

Steps to Reproduce the Problem

  1. UsePodServiceAccount = false
  2. ocelot.json
    {
    "Routes": [   
    {
      "DownstreamPathTemplate": "/health",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/service-name/health",
      "ServiceName": "prod-service-name",
      "UpstreamHttpMethod": [
        "Get",
        "Post",
        "Put"
      ],
    }
    ],
    "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Namespace": "default",
      "Type": "kube"
    }
    }
    }

Specifications

akoken commented 3 years ago

I solved the problem by creating service account.

biubiue commented 3 years ago

I solved the problem by creating service account.

serviceAccount must ?