微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Ocelot api 网关 - kubernetes - 错误:“namespace:serviceservice:managementservice 无法使用,无效地址必须仅包含主机......”

如何解决Ocelot api 网关 - kubernetes - 错误:“namespace:serviceservice:managementservice 无法使用,无效地址必须仅包含主机......”

我面临的问题是 ocelot kubernetservicediscorverProvider 似乎没有在 kubernetes 的命名空间上找到其他服务。我的目标是使用 api 网关调用同一命名空间中其他服务中的 api。我目前收到一个 http 404 Not Found 错误。以及 api 网关 pod,记录以下内容

Ocelot.Provider.Kubernetes.KubernetesServicediscoveryProvider[0] requestId: 0HM93C93DL2T0:00000003,prevIoUsRequestId: no prevIoUs request id,message: namespace:serviceservice:managementservice 无法使用,无效。地址必须仅包含主机,例如本地主机和端口必须大于0

警告:Ocelot.Responder.Middleware.ResponderMiddleware[0] requestId:0HM93C93DL2T0:00000003,prevIoUsRequestId:没有先前的请求ID,消息:错误代码:ServicesAreEmptyError 消息:在ResponderMiddleware 中没有发现NoLoadBalancer 错误中的服务。设置请求路径错误响应:/api/management/User/3910,请求方式:GET

我怀疑我配置错误。我首先尝试使用有关 kubernetes 的 Ocelot 文档,但该文档已过时。 (一个例子是 Type the sugest 值对更多信息不起作用,请转到这个 github 问题 Docs/Kubernetes provider are wrong

然后我继续通过 github 问题、堆栈溢出帖子甚至源代码在线搜索。但我没有看到我的配置中缺少什么。

我目前在本地运行 kubernetes,使用 minikube。我在网上看到的唯一一件事是其他人错误地配置了 ocelot.json。但我没有看到我在配置中做错了什么。

(在 kubernetes 上尝试 ocelot 之前,我首先在本地主机上尝试它,以尝试它是否有效并查看它缺少什么。它显然缺乏可以控制具有不同角色的 jwt 的中间件,这些角色有权访问端点。我现在已经自己编写了中间件,它可以在 ocelot 的本地主机配置上运行)

我的 ocelot.json 配置文件对于 kubernetes 是这样的:

{
  "Routes": [
    {
      "UpstreamPathTemplate": "/api/management/User/{everything}","UpstreamHttpMethod": [ "POST","PUT","GET" ],"DownstreamPathTemplate": "/api/management/User/{everything}","DownstreamScheme": "http","ServiceName": "managementservice","Authenticationoptions": {
        "AuthenticationProviderKey": "Bearer","AllowedScopes": [ "CompanyId","http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" ]
      },"RouteClaimsRequirement": { "role": "1,2,3" },"AddHeadersToRequest": {
        "CompanyId": "Claims[CompanyId] > value","UserId": "Claims[http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier] > value"
      }
    }
  ],"GlobalConfiguration": {
    "ServicediscoveryProvider": {
      "Host": "127.0.0.1","Port": 8083,"Namespace": "service","Type": "KubernetesServicediscoveryProvider"
    }
  }
}

我的 startup.cs ConfigureServices 方法看起来像这样

public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(c =>
            {
                c.AddPolicy("AllowOrigin",options => options.WithOrigins(Configuration["Cors:AllowOrigins"])
                    .AllowAnyHeader()
                    .AllowAnyMethod().AllowCredentials());
            });

            #region Authication settings

            TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Jwt:Key"])),ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = true,ClockSkew = TimeSpan.Zero
            };

            services.AddSingleton(tokenValidationParameters);
            services.AddAuthentication(
                    x =>
                    {
                        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                    }
                )
                .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,x =>
                {

                    x.RequireHttpsMetadata = false;
                    x.Savetoken = true;
                    x.TokenValidationParameters = tokenValidationParameters;
                });

            #endregion

       //Some more code

       services.AddOcelot().AddKubernetes();
       }

我的 startup.cs 配置方法看起来像这样

public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
        {
            // some more code

            app.USEOcelot(configuration);
        }

我的 program.cs CreateHostBuilder 方法看起来像这样

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration((hostingContext,config) =>
               {
                   config.AddJsonFile("secrets/appsettings.kubernetes.json",optional: true)
                         .AddJsonFile("ocelot.json");
               })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

解决方法

事实证明,我遇到的真正问题在于 kubernetes 的权限。 ocelot 文档也提到了这一点。但是文档中的命令不正确(很可能已经过时)。

这是我使用的命令。请注意 kubernetes 文档强烈建议不要使用此命令 permissive-rbac-permissions。但这至少是您在本地测试 ocelot 中的 api 网关的一种方式。

kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。