gce nginix-ingress type NodePort and port:80 connection refused

2017-09-24 nginx kubernetes google-cloud-platform google-kubernetes-engine google-compute-engine

In my gce kube-cluster, i'm using nginx ingress controller instead of google load balancer, by using "nginx-ingress" with NodePort instead of type LoadBalance as below:

helm install --name my-lb stable/nginx-ingress --set controller.service.type=NodePort

Since nginx-controller deployed as "conroller.service.type=NodePort", the nodePorts were opened/assigned(kubect get svc), also got external ip 104.196.xxx.xxx. At this point nginx-ingress-controller is running in kube-cluster and confirmed in console "networking/load balancing" that no cloud load balancer created.

kubectl get svc
NAME                                  CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
my-lb-nginx-ingress-controller   <nodes>       80:31181/TCP,443:31462/TCP   15h
my-lb-nginx-ingress-default-backend    <none>        80/TCP                       15h

After this, created a new firewall rule in console "networking/firewall" to allow node ports "tcp:31181;tcp:31462". Now using browser/curl to reach "http://104.196.xxx.xxx:31181" or "https://104.196.xxx.xxx:31462" gets response from ngnix controllers..works well.

But, port access through port 80 not working. When I do curl on "http://104.196.xxx.xxx:80", get back connection refused as below:

* connect to 104.196.xxx.xxx port 80 failed: Connection refused

Note, firewall rules have "default-allow-http" for "tcp:80" ngnix-ingress version = nginx-ingress-0.8.5 kube-server-version = Major:"1", Minor:"7", GitVersion:"v1.7.5"

helm ls
NAME        REVISION    UPDATED                     STATUS      CHART               NAMESPACE
my-lb       1           Fri Sep 22 23:05:30 2017    DEPLOYED    nginx-ingress-0.8.5 default  

kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"2017-01-12T04:57:25Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.5", GitCommit:"17d7182a7ccbb167074be7a87f0a68bd00d58d97", GitTreeState:"clean", BuildDate:"2017-08-31T08:56:23Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

Any idea why "https://104.196.xxx.xxx:80" gets "port 80: Connection refused" while "https://104.196.xxx.xxx:31462" is working fine?



When using a NodePort, as is very clearly described in the NodePort documentation, it translates the Service port number to a random(+/-) port in the high 30,000 range which that Service will use on the Node itself.

Think of it in that if Service alpha wants to listen on port 80, and Service beta wants to listen on port 80, without that translation mechanism alpha and beta could not exist in the cluster at the same time. Those two ports (31181 for 80, 31462 for 443) are assigned to the Service -- nothing else in the cluster will listen on those ports for as long as that Service is declared.