kubernetes 集群内的 C# gRPC 无法将 DNS 名称解析为其他服务
C# gRPC inside kubernetes cluster cannot resolve DNS name to other service
我调试了几个小时都没有效果。我要么知道如何 google 它要么就是它不寻常的问题。
我在 google 云上有 Kubernetes Engine 集群。为了测试它,我部署了简单的应用程序:
https://github.com/iniside/uSpark
它由三个控制台应用程序组成:
- GreeterServer - 带有 gRPC 和 Google 端点的前端
- Greeter.Backend - 具有 gRPC 服务的后端。
- uSpark - 客户端控制台应用程序。
他们都在使用 .NET Core 2.1、gRPC 1.12 和 C#。 Kubernetes 引擎是 1.10
我已经尝试查看服务 dns 是否在集群内解析。
我也试过在创建频道时直接通过它的IP调用服务。
其中任何一个以:
结尾
Grpc.Core.RpcException: 'Status(StatusCode=Unavailable, Detail="Name resolution failure")'
GreeterServer 正在尝试与 Greeter.Backend:
对话
public override Task<HelloReply> SayHelloAgain(HelloRequest request, ServerCallContext context)
{
Channel channel = new Channel("grpc-greeter-backend.default.svc.cluster.local", 9000, ChannelCredentials.Insecure);
var backendClient = new GreeterBackend.GreeterBackendClient(channel);
var reply = backendClient.SayHelloFromBackend(new BackendHelloRequest { Name = "iniside" });
channel.ShutdownAsync().Wait(); //not neeed to wait, but easier to debug now.
return Task.FromResult<HelloReply>(new HelloReply { Message = "Hello Again " + request.Name + " " + reply.Message });
}
这是我的后端代码:
class GreeterBackendImpl : GreeterBackend.GreeterBackendBase
{
public override Task<BackendHelloReply> SayHelloFromBackend(BackendHelloRequest request, ServerCallContext context)
{
return Task.FromResult<BackendHelloReply>(new BackendHelloReply { Message = "Hello " + request.Name + " From Backend"});
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Server server = new Server
{
Services = { GreeterBackend.BindService(new GreeterBackendImpl()) },
Ports = { new ServerPort("127.0.0.1", 9000, ServerCredentials.Insecure) }
};
server.Start();
Console.WriteLine("Gretter server is linstening on port 50051");
Console.WriteLine("Press any key to stop server");
int read = Console.Read();
while (read < 0)
{
}
}
}
前端配置:
apiVersion: v1
kind: Service
metadata:
name: esp-grpc-greeter
spec:
ports:
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 80
targetPort: 9100
protocol: TCP
name: http2
selector:
app: esp-grpc-greeter
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: esp-grpc-greeter
spec:
replicas: 1
template:
metadata:
labels:
app: esp-grpc-greeter
spec:
containers:
- name: esp
image: gcr.io/endpoints-release/endpoints-runtime:1
args: [
"--http2_port=9100",
"--service=hellohorld3.endpoints.sa-game-206414.cloud.goog",
"--rollout_strategy=managed",
"--backend=grpc://127.0.0.1:9000"
]
ports:
- containerPort: 9100
- name: greeter
image: eu.gcr.io/sa-game-206414/greeter-service:v1
ports:
- containerPort: 8000
后端配置:
apiVersion: v1
kind: Service
metadata:
name: grpc-greeter-backend
spec:
ports:
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 8080
targetPort: 9000
protocol: TCP
name: http2
- port: 9000
targetPort: 9000
protocol: TCP
name: http2900
selector:
app: grpc-greeter-backend
type: ClusterIP
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-greeter-backend
spec:
replicas: 1
template:
metadata:
labels:
app: grpc-greeter-backend
spec:
containers:
- name: greeter-backend
image: eu.gcr.io/sa-game-206414/greeter-backend:b1
ports:
- containerPort: 9000
我解决了问题,它是两倍。首先,正如@spender 所建议的,我确实将后端和前端的 gRPC 地址更改为 0.0.0.0。
但是更改没有被集群接收。因为一直以来它都在拉错图像。
每次我进行更改时,我都会删除带有旧标签的旧图像(本地和 GCR 上的)。使用相同的远程存储库和标签创建新图像并将它们推送到 GCR。
由于某些原因,图片没有更新。
我调试了几个小时都没有效果。我要么知道如何 google 它要么就是它不寻常的问题。
我在 google 云上有 Kubernetes Engine 集群。为了测试它,我部署了简单的应用程序: https://github.com/iniside/uSpark 它由三个控制台应用程序组成:
- GreeterServer - 带有 gRPC 和 Google 端点的前端
- Greeter.Backend - 具有 gRPC 服务的后端。
- uSpark - 客户端控制台应用程序。
他们都在使用 .NET Core 2.1、gRPC 1.12 和 C#。 Kubernetes 引擎是 1.10
我已经尝试查看服务 dns 是否在集群内解析。 我也试过在创建频道时直接通过它的IP调用服务。
其中任何一个以:
结尾Grpc.Core.RpcException: 'Status(StatusCode=Unavailable, Detail="Name resolution failure")'
GreeterServer 正在尝试与 Greeter.Backend:
对话public override Task<HelloReply> SayHelloAgain(HelloRequest request, ServerCallContext context)
{
Channel channel = new Channel("grpc-greeter-backend.default.svc.cluster.local", 9000, ChannelCredentials.Insecure);
var backendClient = new GreeterBackend.GreeterBackendClient(channel);
var reply = backendClient.SayHelloFromBackend(new BackendHelloRequest { Name = "iniside" });
channel.ShutdownAsync().Wait(); //not neeed to wait, but easier to debug now.
return Task.FromResult<HelloReply>(new HelloReply { Message = "Hello Again " + request.Name + " " + reply.Message });
}
这是我的后端代码:
class GreeterBackendImpl : GreeterBackend.GreeterBackendBase
{
public override Task<BackendHelloReply> SayHelloFromBackend(BackendHelloRequest request, ServerCallContext context)
{
return Task.FromResult<BackendHelloReply>(new BackendHelloReply { Message = "Hello " + request.Name + " From Backend"});
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Server server = new Server
{
Services = { GreeterBackend.BindService(new GreeterBackendImpl()) },
Ports = { new ServerPort("127.0.0.1", 9000, ServerCredentials.Insecure) }
};
server.Start();
Console.WriteLine("Gretter server is linstening on port 50051");
Console.WriteLine("Press any key to stop server");
int read = Console.Read();
while (read < 0)
{
}
}
}
前端配置:
apiVersion: v1
kind: Service
metadata:
name: esp-grpc-greeter
spec:
ports:
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 80
targetPort: 9100
protocol: TCP
name: http2
selector:
app: esp-grpc-greeter
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: esp-grpc-greeter
spec:
replicas: 1
template:
metadata:
labels:
app: esp-grpc-greeter
spec:
containers:
- name: esp
image: gcr.io/endpoints-release/endpoints-runtime:1
args: [
"--http2_port=9100",
"--service=hellohorld3.endpoints.sa-game-206414.cloud.goog",
"--rollout_strategy=managed",
"--backend=grpc://127.0.0.1:9000"
]
ports:
- containerPort: 9100
- name: greeter
image: eu.gcr.io/sa-game-206414/greeter-service:v1
ports:
- containerPort: 8000
后端配置:
apiVersion: v1
kind: Service
metadata:
name: grpc-greeter-backend
spec:
ports:
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 8080
targetPort: 9000
protocol: TCP
name: http2
- port: 9000
targetPort: 9000
protocol: TCP
name: http2900
selector:
app: grpc-greeter-backend
type: ClusterIP
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-greeter-backend
spec:
replicas: 1
template:
metadata:
labels:
app: grpc-greeter-backend
spec:
containers:
- name: greeter-backend
image: eu.gcr.io/sa-game-206414/greeter-backend:b1
ports:
- containerPort: 9000
我解决了问题,它是两倍。首先,正如@spender 所建议的,我确实将后端和前端的 gRPC 地址更改为 0.0.0.0。
但是更改没有被集群接收。因为一直以来它都在拉错图像。
每次我进行更改时,我都会删除带有旧标签的旧图像(本地和 GCR 上的)。使用相同的远程存储库和标签创建新图像并将它们推送到 GCR。
由于某些原因,图片没有更新。