Kubernetes NGINX-INGRESS Do I need an NGINX Service running?

4/13/2020

I am attempting to create an NGINX-INGRESS (locally at first, then to be deployed to AWS behind a load-balancer). However I am new to Kubernetes, and I understand the Ingress model for NGINX- the configurations are confusing me as to weather I should be deploying an NGINX-INGRESS Service, Ingress or Both

I am working with multiple Flask-Apps I would like to have routed by path (/users, /content, etc.) My services are named user-service on port: 8000 (their container port is 8000 as well)

In this example an Ingress is defined. However, when I apply an ingress (in the same Namespace as my Flask there is no response from http://localhost

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  namespace: my-namespace
spec:
  rules:
  - http:
      paths:
      - path: /users
        backend:
          serviceName: users-service 
          servicePort: 8000
      - path: /content
        backend:
          serviceName: content-service 
          servicePort: 8000

Furthermore, looking at the nginx-ingress "Deployment" docs, under Docker for Mac (which I assume I can use as I am using Docker on a MacOS) they define a Service like so:

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https

---

This seems to function for me (When I open "localhost" I get Nginx "not found", but it is a service in a different namespace then my apps- and there is no association between the port 80/443 and my service-ports.

For reference here is one of my deployment/service definitions:

---
apiVersion: apps/v1
kind: Deployment
metadata:
    name: users-service
    labels:
        app: users-service
    namespace: example
spec:
    replicas: 1
    selector:
        matchLabels:
            app: users-service
    template:
        metadata:
            labels:
                app: users-service
        spec:
            containers:
                - name: users-service
                  image: users-service:latest
                  imagePullPolicy: Never
                  ports:
                  - containerPort: 8000
---
kind: Service
apiVersion: v1
metadata:
  name: users-service
spec:
  selector:
    app: users-service
  ports:
  - protocol: TCP
port: 8000

Update

I followed a video for setting up an NGINX-Controller+Ingress, here the results, entering "localhost/users" does not work,

describe-ingress:

(base) MacBook-Pro-2018-i9:microservices jordanbaucke$ kubectl describe ingress users-ingress
Name:             users-ingress
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host        Path  Backends
  ----        ----  --------
  *           
              /users   users-service:8000 (10.1.0.75:8000)
Annotations:  Events:  <none>

users-service:

(base) MacBook-Pro-2018-i9:microservices jordanbaucke$ kubectl describe svc users-service
Name:              users-service
Namespace:         default
Labels:            <none>
Annotations:       Selector:  app=users-service
Type:              ClusterIP
IP:                10.100.213.229
Port:              <unset>  8000/TCP
TargetPort:        8000/TCP
Endpoints:         10.1.0.75:8000
Session Affinity:  None
Events:            <none>

nginx-ingress

(base) MacBook-Pro-2018-i9:microservices jordanbaucke$ kubectl describe svc nginx-ingress
Name:                     nginx-ingress
Namespace:                default
Labels:                   <none>
Annotations:              Selector:  name=nginx-ingress
Type:                     NodePort
IP:                       10.106.167.181
LoadBalancer Ingress:     localhost
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  32710/TCP
Endpoints:                10.1.0.74:80
Port:                     https  443/TCP
TargetPort:               443/TCP
NodePort:                 https  32240/TCP
Endpoints:                10.1.0.74:443
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Now when I try to enter the combination of NodeIP:NodePort/users, it does not connect?

From inside my nginx-ingress pod, calling:

curl 10.1.0.75:8000 or curl 10.100.213.229:8000 returns results.

-- jordan.baucke
kubernetes
nginx
nginx-ingress

1 Answer

4/13/2020

For nginx or any other ingress to work properly:

  1. Nginx ingress controller need to deployed on the cluster
  2. A LoadBalancer or NodePort type service need to be created to expose nginx ingress controller via port 80 and 443 in the same namespace where nginx ingress controller is deployed.LoadBalancer works in supported public cloud(AWS etc). NodePort works if running locally.
  3. ClusterIP type service need to be created for workload pods in the namespace where workload pods are deployed.
  4. Workload Pods will be exposed via nginx ingress and you need to create ingress resource in the same namespace as of the clusterIP service of your workload Pods.
  5. You will use either the LoadBalancer(in case nginx ingress controller was exposed via LoadBalancer) or NodeIP:NodePort(in case Nginx ingress controller was exposed via NodePort) to access your workload Pods.

So in this case since docker desktop is being used Loadbalancer type service(ingress-nginx) to expose nginx ingress controller will not work. This needs to be of NodePort type. Once done workload pods can be accessed via NodeIP:NodePort/users and NodeIP:NodePort/content. NodeIP:NodePort should give nginx homepage as well.

-- Arghya Sadhu
Source: StackOverflow