<p>I'm trying to deploy a gRPC server with kubernetes, and connect to it outside the cluster.
The relevant part of the server:</p>
<pre><code>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(), () =&gt; {
    server.start();
    console.log(&quot;Started server! on &quot; + url);
  });
}

function sayHello(call, callback) {
  console.log('Hello request');
  callback(null, {message: 'Hello ' + call.request.name + ' from ' + require('os').hostname()});
}
</code></pre>
<p>And here is the relevant part of the client:</p>
<pre><code>function main() {
  var target = '0.0.0.0:50051';
  let pkg = grpc.loadPackageDefinition(packageDefinition);
  let Greeter = pkg.helloworld[&quot;Greeter&quot;];
  var client = new Greeter(target,grpc.credentials.createInsecure());
  var user = &quot;client&quot;;
  
  client.sayHello({name: user}, function(err, response) {
    console.log('Greeting:', response.message);
  });
}
</code></pre>
<p>When I run them manually with nodeJS, as well as when I run the server in a docker container (client is still run with node without a container) it works just fine.</p>
<p>The docker file with the command: <code>docker run -it -p 50051:50051 helloapp</code></p>
<pre><code>FROM node:carbon
 
# Create app directory
WORKDIR /usr/src/appnpm 
 
COPY package.json .
COPY package-lock.json .
 
RUN npm install
 
COPY . .
 
CMD npm start
</code></pre>
<p>However, when I'm deploying the server with kubernetes (again, the client isnt run within a container) I'm not able to connect.</p>
<p>The yaml file is as follows:</p>
<pre><code>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
</code></pre>
<p>The deployment and the service start up just fine</p>
<pre><code>kubectl get svc
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
helloservice   ClusterIP   10.105.11.22   &lt;none&gt;        50051/TCP   17s


kubectl get pods      
NAME                     READY   STATUS    RESTARTS   AGE
helloapp-dbdfffb-brvdn   1/1     Running   0          45s
</code></pre>
<p>But when I run the client it can't reach the server.</p>
<p>Any ideas what I'm doing wrong?</p>

<p>As mentioned in comments</p>
<hr />
<h2>ServiceTypes</h2>
<p>If you have exposed your service as <strong>ClusterIP</strong> it's visible only internally in the cluster, if you wan't to expose your service externally you have to use either <strong>nodePort</strong> or <strong>LoadBalancer</strong>.</p>
<blockquote>
<p><strong>Publishing Services (ServiceTypes)</strong></p>
<p>For some parts of your application (for example, frontends) you may want to expose a Service onto an external IP address, that's outside of your cluster.
Kubernetes ServiceTypes allow you to specify what kind of Service you want. The default is ClusterIP.</p>
<p>Type values and their behaviors are:</p>
<p><strong>ClusterIP</strong>: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.</p>
<p><strong>NodePort</strong>: Exposes the Service on each Node's IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You'll be able to contact the NodePort Service, from outside the cluster, by requesting :.</p>
<p><strong>LoadBalancer</strong>: Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.</p>
<p><strong>ExternalName</strong>: Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. No proxying of any kind is set up.</p>
</blockquote>
<p>Related <a href="http://%5Bdocumentation%5D%5B3%5D" rel="nofollow noreferrer">documentation</a> about that.</p>
<hr />
<h2>Minikube</h2>
<p>With minikube you can achieve that with <code>minikube service</code> command.</p>
<p>There is <a href="https://minikube.sigs.k8s.io/docs/handbook/accessing/" rel="nofollow noreferrer">documentation</a> about minikube service and there is an <a href="https://kubernetes.io/docs/tutorials/hello-minikube/#create-a-service" rel="nofollow noreferrer">example</a>.</p>
<hr />
<h2>grpc http/https</h2>
<p>As mentioned <a href="https://stackoverflow.com/a/62136381/11977760">here</a> by @murgatroid99</p>
<blockquote>
<p>The gRPC library does not recognize the https:// scheme for addresses, so that target name will cause it to try to resolve the wrong name. You should instead use grpc-server-xxx.com:9090 or dns:grpc-server-xxx.com:9090 or dns:///grpc-server-xxx.com:9090. More detailed information about how gRPC interprets channel target names can be found in this <a href="https://github.com/grpc/grpc/blob/master/doc/naming.md" rel="nofollow noreferrer">documentation page</a>.</p>
</blockquote>
<p>As it does not recognize https I assume it's the same for http, so it's not possible.</p>
<hr />
<h2>kubectl port-forward</h2>
<p>Additionally as @IsolatedSushi mentioned</p>
<blockquote>
<p>It also works when I portforward with the command <code>kubectl -n hellospace port-forward svc/helloservice 8080:50051</code></p>
</blockquote>
<p>As mentioned <a href="https://phoenixnap.com/kb/kubectl-port-forward" rel="nofollow noreferrer">here</a></p>
<blockquote>
<p>Kubectl port-forward allows you to access and interact with internal Kubernetes cluster processes from your localhost. You can use this method to investigate issues and adjust your services locally without the need to expose them beforehand.</p>
</blockquote>
<p>There is an <a href="https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/" rel="nofollow noreferrer">example</a> in documentation.</p>
