GRPC Server written in Node in Docker Container on GCE VM - ERROR 14

Viewed 239

I cannot manage to establish a connection when my docker container is deployed to GCE. If I build and run the docker container locally then I have no issues.

I am exposing port 50051 in my Dockerfile and deploying my built image to GCR.

I have an ubuntu 20.04LTS VM, I have installed docker.

I have tried launching my server using the following

server.bindAsync('0.0.0.0:50051', grpcLibrary.ServerCredentials.createInsecure(), (error, port) => {
                try {
                    if (error)
                        reject(error);
                    server.start();
                    console.log('started on ' + port);
                    resolve(server);
                }
                catch (e) {
                    reject(e);
                }
            });

and

server.bindAsync('127.0.0.1:50051', grpcLibrary.ServerCredentials.createInsecure(), (error, port) => {
                try {
                    if (error)
                        reject(error);
                    server.start();
                    console.log('started on ' + port);
                    resolve(server);
                }
                catch (e) {
                    reject(e);
                }
            });

I am running my container using the following docker run -p 50051:50051 -it -d eu.gcr.io/myimage

IP tables on the VM shows

sudo iptables -t nat -n -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:50051

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:50051 to:172.17.0.2:50051

docker ps shows

CONTAINER ID        IMAGE                                                   COMMAND                  CREATED             STATUS              PORTS                      NAMES
4e32bdcae366        eu.gcr.io/myimage:latest   "docker-entrypoint.s…"   18 minutes ago      Up 18 minutes       0.0.0.0:50051->50051/tcp   youthful_wright

and ss -tulpn in the container

ss -tulpn
Netid State      Recv-Q Send-Q                                                Local Address:Port                                                               Peer Address:Port              
tcp   LISTEN     0      511                                                               *:50051                                                                         *:*                   users:(("node",pid=1,fd=18))

I also have the following firewall rule on VPC network which gets hit

    
Name
Type
Targets
Filters
Protocols / ports
Action
Priority
Network
Logs
Hit count 
Last hit 
Insights
allow-grpc
Ingress
Apply to all    
IP ranges: 0.0.0.0/0
tcp:50051
Allow
1000
default
On  
85
2020-07-08 (11:33:00)

Has anyone got any idea on why I cannot connect from my local machine or had the same issue?

I feel it is something in the routing but I just cannot work it out

1 Answers

I reproduced in one of my instances and I had no issues.
I am using the default nginx official image for the quick test.
Perhaps you're missing something in the firewall rule. Apart from that, there's nothing special to be done.

I launched a dummy nginx image. I chose to publish :8095 and forward traffic to :80 inside the container:

docker run --name some-nginx -d -p 8095:80 nginx

I can reach it locally with no additional step:

# curl localhost:8095
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

From the outside world is not yet accessible, because there's no firewall rule to allow ingress on the port that I chose to publish:

neo@neo-desktop:~$ telnet 34.107.14.223 80
Trying 34.107.14.223...
telnet: Unable to connect to remote host: Connection refused

I added a network tag on my instance:
enter image description here


Then created a firewall rule that allows ingress on the published port and I applied to rule to all instances that have the tag assigned to the instance in the previous step:
enter image description here

After adding the rule, I can curl without problems in the nginx running in my container:

neo@neo-desktop:~$ curl 34.107.14.223:8095
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Related