Exposing a service in Kubernetes using nginx reverse proxy - kubernetes

I am new to Kubernetes and wanted to understand how I can expose a service running in Kubernetes to the outside world. I have exposed it using a NodePort on the cluster.
So, for example: A service exposes port 31234 on the host and I can get to the service from another server through https://kubeserverIP:31234.
What I want to achieve is serve this service through nginx (on a different server, out of Kube control) via a url,say, http://service.example.com. I have tried deploying nginx with an upstream pointing to the service but that is not working and get a bad gateway error.
Is there something which I am missing here? Or is there a neater way of achieving this.
I have a baremetal installation of Kubernetes cluster and have no access to gce load balancer or other vendor LBs.
Thanks

Thanks for pointing in the right direction.
Essential steps broadly were:
Create an app and its service definition.
Create a namespace for ingress.
Create a default backend deployment and service for redirecting all requests not defined in Ingress rules. Create these in the ingress space
Create the nginx ingress controller deployment.
Create RBAC rules.
Finally create the ingress rule for the applications with the paths and the ports.
Found a very useful guide which explained things in details:
https://akomljen.com/kubernetes-nginx-ingress-controller/

You're almost there! Your next step will be to setup a ingress controller. There is an NGINX Ingress controller plugin that you can checkout here.
Edit: Here's an example configuration: https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/complete-example

Related

AWS EKS websocket based app - good approach?

I've just deployed websocket based echo-server on AWS EKS. I see it's running stable and okay but when I was searching for implementation details I was finding only articles that were saying something about nginx ingress controller or AWS application loadbalancer and a lot of troubles with them.
Do I miss anything in my current, vanilla config? Do I need the AWS ALB or nginx ingress controller?
Thank you for all the replies.
All the best.
Do I miss anything in my current, vanilla config?
You probably exposed your echo-server app using service type - ClusterIP or NodePort which is fine if you only need to access your app locally in the cluster (ClusterIP) or using your node IP address (NodePort).
Do I need the AWS ALB or nginx ingress controller?
They both are different things, but they have similar common goal - to make your websocket app available externally and distribute traffic based on defined L7 routing routes. It's good solution if you have multiple deployments. So you need to answer yourself if you need some kind of Ingress Controller. If you are planning to deploy your application into production you should consider using those solutions, but probably it may be fine with service type LoadBalancer.
EDIT:
If you are already using service type LoadBalancer your app is already available externally. Ingress controller provides additional configuration possibilities to configure L7 traffic route to your cluster (Ingress Controllers are often using LoadBalancer under the hood). Check this answer for more details about differences between LoadBalancer and Ingress.
Also check:
Choosing the Right Load Balancer on Amazon: AWS Application Load Balancer vs. NGINX Plus
Configuring Kubernetes Ingress on AWS? Don’t Make These Mistakes
WebSocket - Deploy to Kubernetes
LoadBalancer vs Ingress

what is an ingress controller and how do I create it?

Good morning guys, so I took down a staging environment for a product on GCP and ran the deployment scripts again, the backend and frontend service have been setup. I have an ingress resource and a load balancer up, however, the service is not running. A look at the production app revealed there was something like an nginx-ingress-controller. I really don't understand all these and how it was created. Can someone help me understand because I have not seen anything online that makes it clear for me. Am I missing something?
loadBalancer: https://gist.github.com/davidshare/5a571e56febe7dacd580282b373f3095
Ingress Resource: https://gist.github.com/davidshare/d0f53912bc7da8310ec3d64f1c8a44f1
Ingress allows access to your Kubernetes services from outside the Kubernetes cluster. There are different kubernetes aka K8 resources alternatively you can use like (Node Port / Loadbalancer) which you can use to expose.
Ingress is independent resource to your service , you can specify routing rules declaratively, so each url with some context can be mapped to different services.
This makes it decoupled and isolated from the services you want to expose.
So to work ingress it needs an Ingress Controller for your cluster.
Like deployment resource in K8, ingress can be created simply by
kubectl create -f ingress.yaml
First, you have to implement Ingress Controller in order to apply Ingress resource, as described in #Shubhu answer. Ingress controller, as an edge router, applies specific logical structure with aim to route external traffic to your Kubernetes cluster underlying services via basic pattern routing rules defined in Ingress resource.
If you select Nginx Ingress Controller then it might be useful to proceed with installation guide approaching some specific prerequisites based on cloud provider environment. In order to simplify Nginx Ingress controller installation procedure it is also possible to use Helm package manager and install appropriate stable/nginx-ingress Helm chart.

How to use multi domain by one ingress on baremetal

I know how can i use one ingress for one domain but if i have more than one domain like below what should ido?
how should i handle DNS for ingress?I do not want to write domain in ingress.yml
Ingress element on diagram is ingress-controller, but nobody forbids creating individual Ingress resources for each route.
As alternative solution, you can expose service as LoadBalancer and configure external DNS service to route traffic on Kubernetes LB Service. Check ExternalDNS project for more information.
MetalLB and kube-router also could be useful for Bare-Metal/On-Premise K8s setup.
On my opinion, Helm/Ksonnet/Kustomize will help you with Ingress resource management too.

Kubernetes - Have an ingress on a service - is it ok for its type to be ClusterIP

I have a Kubernetes services that I would like to be accessible from outside the cluster.
I've setup Traefik and have created an Ingress file for that service and am able to go to 'somemadeupdomain.com' and access the service fine. (Having locally added a line in my hosts file).
However my question is with the service type, I've currently set as ClusterIP. I can access the service fine, so is it fine to continue to use that or should I use NodePort.
Of course if I use NodePort I'm aware that when doing minikube service list I'll get a specific URL created by Kubernetes to access that service, but I feel I don't need to do that as I have that ingress file?
Any explanation would be appreciated.
Thanks
As you are using ingress already it does not make much sense to use NodePort. As you already have a way to access your application. Its totally fine to have a service type you need at service level that you need for the internal access(within Kubernets) purpose.
Ingress will redirect your external traffic to your service within the cluster, so ClusterIP is a good choice. No need to use NodePort.
From Documentation
Ingress, added in Kubernetes v1.1, exposes HTTP and HTTPS routes from
outside the cluster to services within the cluster

What's the exactly flow chart of an outside request comes into k8s pod via Ingress?

all
I knew well about k8s' nodePort and ClusterIP type in services.
But I am very confused about the Ingress way, because how will a request come into a pod in k8s by this Ingress way?
Suppose K8s master IP is 1.2.3.4, after Ingress setup, and can connect to backend service(e.g, myservice) with a port(e.g, 9000)
Now, How can I visit this myservice:9000 outside? i.e, through 1.2.3.4? As there's no entry port on the 1.2.3.4 machine.
And many docs always said visit this via 'foo.com' configed in the ingress YAML file. But that is really funny, because xxx.com definitely needs DNS, it's not a magic to let you new-invent any xxx.com you like be a real website and can map your xxx.com to your machine!
The key part of the picture is the Ingress Controller. It's an instance of a proxy (could be nginx or haproxy or another ingress type) and runs inside the cluster. It acts as an entrypoint and lets you add more sophisticated routing rules. It reads Ingress Resources that are deployed with apps and which define the routing rules. This allows each app to say what the Ingress Controller needs to do for routing to it.
Because the controller runs inside the cluster, it needs to be exposed to the outside world. You can do this by NodePort but if you're using a cloud provider then it's more common to use LoadBalancer. This gives you an external IP and port that reaches the Ingress controller and you can point DNS entries at that. If you do point DNS at it then you have the option to use routing rules base on DNS (such as using different subdomains for different apps).
The article 'Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?' has some good explanations and diagrams - here's the diagram for Ingress: