如何解决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 举报,一经查实,本站将立刻删除。