0

I am trying to implement nginx-ingress controller for kubernetes 1.26.3. I am testing on my local machine using rancher desktop 1.8.1. As of this post everything is the latest version. If it matters im using containerd. Im new to k8s and finding it hard to figure out what is wrong when things dont work based on examples.

I have a service game-core-service running inside my cluster on port 8080 and I can test that is working by sshing into a pod or using a browser and setting the service as a nodeport.

Now im trying to setup nginx ingress to replace nodeport since nodeport is not a good option for exposing services. I want to call my kubernetes service externally from postman by calling localhost:80/myservice. I installed the controller with these commands:

I am not sure that it installed cleanly even though I got no error messages. I see a pod named nginx-ingress-v1-controller added in my default namespace is running. I also see a pod / deployment called svclb-nginx-ingress-v1-controller was added to kube-system but it is in pending state. I assume the setup is not correct but not clear how to debug it or find what is wrong. Or maybe its supposed to be pending till I set up some other configuration .. Im lost.

I then applied this ingress.yaml via kubectl:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: game-core-service
            port:
              number: 80

Few things that are totally unclear about this yaml:

  • do we really need the ingressClassName or is that only needed if you have multiple ingress controllers. Examples of defining a default ingress class dont seem to reference nginx so no idea if they are correct for what im doing (an example would be great)
  • does the backend.service.port refer to the incoming port number or the port the service is running on? I would ideally forward anything on port 80 or 443 to the service which is on port 8080

Answers to any of these questions would be so hugely appreciated. Thanks!

1 Answer 1

0

looks like you've fallen into the manually configure kubernetes rabbits hole. One of the biggest issues with Kubernetes is there are millions of ways to get to the same outcome.

You're on the right track however it might be quicker for you to just get helm to drive everything for you.

TLDR answer

do we really need the ingressClassName or is that only needed if you have multiple ingress controllers. Examples of defining a default ingress class dont seem to reference nginx so no idea if they are correct for what im doing (an example would be great)

I'm sure there are other ways to configure it where you don't but the method I would use would define the ingressClassName as nginx.

does the backend.service.port refer to the incoming port number or the port the service is running on? I would ideally forward anything on port 80 or 443 to the service which is on port 8080

The backend service is the port that the docker container runs on. You don't really need to worry about this as kubernetes can deal with all that for you.

Longer winded answer

If you install using helm, you'll have an option to use a values.yaml file during install. This file is where all the knobs you're after live. The values.yaml file will vary based on which helm repo you choose to install. It looks like you're using the NGINX official repo, you can find the official values.yaml here.

First thing to do is download a local copy of that file and edit it to suit your purposes. I suggest trying to use it with as few edits as possible first - I have just pulled that version and applied it to my dev cluster and applications like podinfo worked immediately.

Now for the non-obvious bit - there are a couple of ways to publish a service:

  1. URL route ie. test.com/myapp
  2. DNS named application ie. myapp.test.com

My personal preference is to use DNS names but it depends on your use case.

Lets use podinfo to demonstrate how to configure an application to use ingress-nginx as its ingress.

URL Route

  • Download podinfo's values.yaml and save it locally.
  • Edit the values.yaml file and find the ingress: section. This is going to be a common section amongst most/all helm charts you install.
  • Add a host to your ingress as follows, making sure to add the path you wish to have ingress-nginx serve the application from.
    ingress:
      enabled: true
      className: "nginx"
      annotations:
        kubernetes.io/ingress.class: nginx
      hosts:
        - host: test.com
          paths:
            - path: /podinfo
              pathType: ImplementationSpecific
  • Once you've added this to your podinfo values.yaml you need to install the podinfo helm chart as follows: helm upgrade --install --wait podinfo --namespace podinfo --values values.yaml oci://ghcr.io/stefanprodan/charts/podinfo
  • After a short while you should see an ingress appear in the podinfo namespace:
root@dev:~# kubectl get ingress -n podinfo -o yaml
apiVersion: v1
kind: List
items:
- apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
      meta.helm.sh/release-name: podinfo
      meta.helm.sh/release-namespace: podinfo
    labels:
      app.kubernetes.io/managed-by: Helm
      app.kubernetes.io/name: podinfo
      app.kubernetes.io/version: 6.3.5
      helm.sh/chart: podinfo-6.3.5
    name: podinfo
    namespace: podinfo
  spec:
    ingressClassName: nginx
    rules:
    - host: test.com
      http:
        paths:
        - backend:
            service:
              name: podinfo
              port:
                number: 9898
          path: /podinfo
          pathType: ImplementationSpecific
  status:
    loadBalancer:
      ingress:
      - ip: 10.20.20.100

Note that the output shows the path and host value correctly and that up in the annotations the ingress.class is set to nginx which is what tells nginx to serve up this content.

DNS Route

This method is almost exactly the same as the method above except that in the values.yaml file you leave the path as a / and the host is the dns name you wish to use for the application like this:

    ingress:
      enabled: true
      className: "nginx"
      annotations:
        kubernetes.io/ingress.class: nginx
      hosts:
        - host: podinfo.test.com
          paths:
            - path: /
              pathType: ImplementationSpecific

Once you've applied this values.yaml you should see the following:

root@dev:~# kubectl get ingress -n podinfo -o yaml
apiVersion: v1
kind: List
items:
- apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
      meta.helm.sh/release-name: podinfo
      meta.helm.sh/release-namespace: podinfo
    labels:
      app.kubernetes.io/managed-by: Helm
      app.kubernetes.io/name: podinfo
      app.kubernetes.io/version: 6.3.5
      helm.sh/chart: podinfo-6.3.5
    name: podinfo
    namespace: podinfo
  spec:
    ingressClassName: nginx
    rules:
    - host: podinfo.test.com
      http:
        paths:
        - backend:
            service:
              name: podinfo
              port:
                number: 9898
          path: /
          pathType: ImplementationSpecific
  status:
    loadBalancer:
      ingress:
      - ip: 10.20.20.100

I hope this helps. One of my favourite how to websites for Kubernetes is The Geek Cookbook by David Young. His site has some very well documented examples showing useful applications to have on your K8S stack and most importantly how to configure them.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for all the thought you put into the answer. If you look at my original post I am using helm to install it. I actually found there are 2 versions of nginx ingress - one maintained by nginx and one by kubernetes. I switched to the kubernetes one and installed via helm - was much smoother. I do find that it doesnt come up cleanly when I restart rancher but otherwise works fine for testing. For me the hardest think of k8s is there are pushbutton solutions like helm but if the helm install doesnt work I have no idea how to debug the issue.
Helm provides the application owner with a streamlined way to deploy their application, while also making it easy for the application consumer to configure it. When an application is installed using Helm, the underlying Kubernetes resources (such as deployment, service, etc.) are still visible, allowing for easy debugging in case issues arise. By modifying the values in the values.yaml file, one can easily make necessary changes and adjustments to the application. Application could be nginx-ingress or any

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.