kubernetes - Ocelot api gateway - kubernetes - error: "namespace:serviceservice:managementservice Unable to use , it is invalid. Address must contain only host ...."
问题描述
我面临的问题是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 无法使用,无效。地址必须仅包含主机,例如 localhost 和端口必须大于 0
警告:Ocelot.Responder.Middleware.ResponderMiddleware[0] requestId:0HM93C93DL2T0:00000003,previousRequestId:没有以前的请求 id,消息:错误代码:ServicesAreEmptyError 消息:NoLoadBalancer 中没有服务在 ResponderMiddleware 中发现错误。请求路径设置错误响应:/api/management/User/3910,请求方法:GET
我怀疑我配置错误。我首先尝试使用有关 kubernetes 的 Ocelot 文档,但该文档已过时。(一个例子是类型 sugest value does not work for more info go this github issue Docs/Kubernetes provider are wrong)
然后我继续通过 github 问题、堆栈溢出帖子甚至源代码在线搜索。但我没有看到我的配置中缺少什么。
我目前使用 minikube 在本地运行 kubernetes。我在网上看到的唯一的事情是其他人错误配置了ocelot.json。但我没有看到我在配置中做错了什么。
(在 kubernetes 上尝试 ocelot 之前,我首先在本地主机上尝试它,以尝试它是否有效并查看它缺少什么。它显然缺乏可以控制具有不同角色的 jwt 的中间件,这些角色有权访问端点。我有现在我自己编写了中间件,它适用于 ocelot 的本地主机配置)
对于 kubernetes,我的 ocelot.json 配置文件如下所示:
{
"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
推荐阅读
- apache-kafka - Kafka 和 Kafka Streams 是否适合我们的案例?
- docker - 通过 SSH 使用不同用户的 Docker 上下文
- sql-server - SQL SERVER 到 DATA FACTORY 数据库的请求限制为 120 并且已达到
- sockets - nginx 服务器(在 WSL 上运行)和 Beeware 应用程序(从 windows anaconda 构建和运行)之间的网络配置
- flutter - 如何以列表形式显示flutter table_calendar?
- java - 如何在firebase实时数据库中引用特定节点
- python - 使用 Beautiful Soup 抓取一系列新闻文章 - 显示所有文章的问题。完整代码如下
- php - 数组中唯一值的总和
- powershell - 获取所有登录计算机的用户
- spring-boot - 有没有办法将业务中心嵌入自定义 Spring Boot 应用程序中?