Search code examples
kubernetes-ingressminikube

How to use nginx ingress to route traffic based on port


I'm currently working on deploying ELK stack on kubernetes cluster, i was successfully able to use ClusterIP service and nginx-ingress on minikube to route inbound http traffic to kibana (5601 port), need inputs on how i can route traffic based on inbound port rather than path?

Using below Ingress object declaration, i was successfully able to connect to my kibana deployment, but how can i access other tools stack exposed on different ports (9200, 5044, 9600)?

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: ingress-service
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: kibana-service
          servicePort: 5601

CUrl'ing minikube ip on default 80 port returns valid response

# curl http://<minikube-ip>/api/status
{"name":"kibana",....}

Note: i would not want to use NodePort, but would like to know if nodeport is the only way we can achieve the above?


Solution

  • As you already have minikube and minikube ingress addon enabled:

    $ minikube addons list | grep ingress
    | ingress                     | minikube | enabled ✅   |
    | ingress-dns                 | minikube | enabled ✅   |
    

    Just as reminder:

    targetPort: is the port the container accepts traffic on (port where application runs inside the pod).

    port: is the abstracted Service port, which can be any port other pods use to access the Service.

    Please keep in mind that if your container will not be listening port specified in targetPort you will not be able to connect to the pod. Also remember about firewall configuration to allow traffic.

    As for example I've used this yamls:

    apiVersion: v1
    kind: Service
    metadata:
      name: service-one
    spec:
      selector:
        key: application-1
      ports:
        - port: 81
          targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deployment-1
    spec:
      replicas: 1
      selector:
        matchLabels:
          key: application-1
      template:
        metadata:
          labels:
            key: application-1
        spec:
          containers:
          - name: hello1
            image: gcr.io/google-samples/hello-app:1.0
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: service-two
    spec:
      selector:
        key: application-2
      ports:
        - port: 82
          targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deployment-2
    spec:
      replicas: 1
      selector:
        matchLabels:
          key: application-2
      template:
        metadata:
          labels:
            key: application-2
        spec:
          containers:
          - name: hello2
            image: gcr.io/google-samples/hello-app:2.0
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 8080
    ---
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ingress
      annotations:
        kubernetes.io/ingress.class: nginx
    spec:
      rules:
      - http:
          paths:
          - path: /hello
            backend:
              serviceName: service-one
              servicePort: 81
          - path: /hello2
            backend:
              serviceName: service-two
              servicePort: 82
    
    service/service-one created
    deployment.apps/deployment-1 created
    service/service-two created
    deployment.apps/deployment-2 created
    Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
    ingress.networking.k8s.io/ingress created
    

    Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress

    Please keep in mind that soon Minikube will change apiVersion as per warning above.

    Below output of this configuration:

    $ curl http://172.17.0.3/hello
    Hello, world!
    Version: 1.0.0
    Hostname: deployment-1-77ddb77d56-2l4cp
    minikube-ubuntu18:~$ curl http://172.17.0.3/hello2
    Hello, world!
    Version: 2.0.0
    Hostname: deployment-2-fb984955c-5dvbx
    

    You could use:

          paths:
          - path: /elasticsearch
            backend:
              serviceName: elasticsearch-service
              servicePort: 100
          - path: /anotherservice
            backend:
              serviceName: another-service
              servicePort: 101
    

    Where service would looks like:

      name: elasticsearch-service
      ...
      ports:
        - port: 100
          targetPort: 9200
      ---
      name: another-service
      ...
      ports:
        - port: 101
          targetPort: 5044
    

    However, if you would need more advanced path configuration you can also use rewrite. Also you can use default backend to redirect to specific service.

    More information about accessing Minikube you can find in Minikube documentation.

    Is it what you were looking for or something different?