Node.js 与kubernetes一起部署时无法与gRPC连接

Node.js 与kubernetes一起部署时无法与gRPC连接,node.js,docker,kubernetes,grpc,Node.js,Docker,Kubernetes,Grpc,我正在尝试部署一个带有kubernetes的gRPC服务器,并在集群外部连接到它。 服务器的相关部分: function main() { var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld; var server = new grpc.Server(); server.addService(hello_proto.Greeter.service, {sayHello: sayHello

我正在尝试部署一个带有kubernetes的gRPC服务器,并在集群外部连接到它。 服务器的相关部分:

function main() {
  var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
  var server = new grpc.Server();
  server.addService(hello_proto.Greeter.service, {sayHello: sayHello});
  const url = '0.0.0.0:50051'
  server.bindAsync(url, grpc.ServerCredentials.createInsecure(), () => {
    server.start();
    console.log("Started server! on " + url);
  });
}

function sayHello(call, callback) {
  console.log('Hello request');
  callback(null, {message: 'Hello ' + call.request.name + ' from ' + require('os').hostname()});
}
以下是客户的相关部分:

function main() {
  var target = '0.0.0.0:50051';
  let pkg = grpc.loadPackageDefinition(packageDefinition);
  let Greeter = pkg.helloworld["Greeter"];
  var client = new Greeter(target,grpc.credentials.createInsecure());
  var user = "client";
  
  client.sayHello({name: user}, function(err, response) {
    console.log('Greeting:', response.message);
  });
}
当我使用nodeJS手动运行它们时,以及在docker容器中运行服务器时(客户机仍然使用没有容器的节点运行),都可以正常工作

带有命令的docker文件:
docker run-it-p 50051:50051 helloapp

FROM node:carbon
 
# Create app directory
WORKDIR /usr/src/appnpm 
 
COPY package.json .
COPY package-lock.json .
 
RUN npm install
 
COPY . .
 
CMD npm start
但是,当我使用kubernetes部署服务器时(同样,客户端不是在容器中运行的),我无法连接

yaml文件如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloapp
  strategy: {}
  template:
    metadata:
      labels:
        app: helloapp
    spec:
      containers:
        image: isolatedsushi/helloapp
        name: helloapp
        ports:
        - containerPort: 50051
          name: helloapp
        resources: {}
status: {}
---
apiVersion: v1
kind: Service
metadata:
  name: helloservice
spec:
  selector:
    app: helloapp
  ports:
  - name: grpc
    port: 50051
    targetPort: 50051
部署和服务启动得很好

kubectl get svc
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
helloservice   ClusterIP   10.105.11.22   <none>        50051/TCP   17s


kubectl get pods      
NAME                     READY   STATUS    RESTARTS   AGE
helloapp-dbdfffb-brvdn   1/1     Running   0          45s
kubectl获取svc
名称类型CLUSTER-IP外部IP端口年龄
helloservice ClusterIP 10.105.11.22 50051/TCP 17s
kubectl得到豆荚
名称就绪状态重新启动
helloapp dbdfffb brvdn 1/1运行0 45s
但是当我运行客户端时,它无法到达服务器


你知道我做错了什么吗?

如评论中所述


服务类型 如果您已将服务公开为群集IP它仅在群集中内部可见,如果您不想在外部公开服务,则必须使用节点端口负载平衡器

发布服务(服务类型)

对于应用程序的某些部分(例如前端),您可能希望将服务公开到集群外部的外部IP地址。 Kubernetes服务类型允许您指定所需的服务类型。默认值是ClusterIP

类型值及其行为是:

集群IP:在集群内部IP上公开服务。选择此值将使服务只能从集群内访问。这是默认的服务类型

节点端口:在静态端口(节点端口)的每个节点的IP上公开服务。自动创建NodePort服务路由到的ClusterIP服务。您可以通过请求从集群外部联系NodePort服务:

负载平衡器:使用云提供商的负载平衡器对外公开服务。自动创建外部负载平衡器路由到的NodePort和ClusterIP服务

ExternalName:通过返回CNAME记录及其值,将服务映射到ExternalName字段的内容(例如foo.bar.example.com)。未设置任何类型的代理

关于那件事


米尼库贝 使用minikube,您可以使用
minikube服务
命令来实现这一点

有关于minikube的服务,还有一个


grpc http/https 如@murgatroid99所述

gRPC库无法识别地址的https://方案,因此目标名称将导致它尝试解析错误的名称。您应该改为使用grpc服务器xxx.com:9090或dns:grpc服务器xxx.com:9090或dns:///grpc-server-xxx.com:9090. 有关gRPC如何解释通道目标名称的更多详细信息,请参见本文档

由于它不识别https,我假设它与http相同,所以这是不可能的


库贝特港前进 此外,如@IsolatedSushi所述

当我使用命令
kubectl-n hellospace port forward svc/helloservice 8080:50051进行portforward时,它也可以工作

如上所述

Kubectl port forward允许您从本地主机访问内部Kubernetes群集进程并与之交互。您可以使用此方法调查问题并在本地调整服务,而无需事先公开它们


文档中有一个错误。

结果证明我必须使用minikube服务helloservice运行它,然后使用它吐出的IP,而不使用http部分。然后它工作了,我不知道为什么我必须这样做…1.你的客户在哪里,在你的本地pc上?如果您已将服务公开为ClusterIP,则它仅在集群内部可见。看看服务类型。在minikube上,LoadBalancer类型通过
minikube服务
命令使服务可访问,使用此命令可以从外部公开服务。看一看。2.如果在ip之前添加http,会出现什么错误?@Jakub 1。客户机确实位于我的本地pc上。它给出一个错误:代码14,详细信息:“”目标dns的名称解析失败:'。我不明白的是,当我使用节点端口(比如30007)时,它也不允许我连接grpc服务器。你的minikube版本和驱动程序是什么?关于http部分,我不确定是否可能?有一个关于https的问题,所以我认为它可能与您的问题有关。关于节点端口,它应该可以工作。您是否可以尝试将服务类型从ClusterIP更改为nodePort,并使用前面提到的
minikube服务--url$service
?是的,http部分不可能。至于其余部分,它与以前一样工作。当我使用命令portforward
kubectl-n hellospace port-forward svc/helloservice 8080:50051时,它也能工作。哇,回答得好!我现在明白我的误解了。谢谢你的清理,非常感谢你的帮助!