Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty ADDRESS kubernetes ingress

I tried configuring ingress on my kubernetes cluster. I followed the documentation to install ingress controller and ran the following commands

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml

After that default-http-backend and nginx-ingress-controller were running:

ingress-nginx   default-http-backend-846b65fb5f-6kwvp      1/1       Running   0          23h       192.168.2.28   node1
ingress-nginx   nginx-ingress-controller-d658896cd-6m76j   1/1       Running   0          6m        192.168.2.31   node1

I tried testing ingress and I deployed the following service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
        - name: my-echo
          image: gcr.io/google_containers/echoserver:1.8
---
apiVersion: v1
kind: Service
metadata:
  name: echoserver-svc
spec:
  selector:
    app: echo
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

And the following ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: happy-ingress
  annotations:
    INGRESS.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: happy.k8s.io
      http:
        paths:
          - path: /echoserver
            backend:
              serviceName: echoserver-svc
              servicePort: 8080

When I ran the command 'kubectl get ing' I received:

NAME            HOSTS          ADDRESS   PORTS     AGE
happy-ingress   happy.k8s.io             80        14m

I didn't have ADDRESS resolved and I can’t figure out what the problem is because all the pods are running. Can you give me a hint as to what the issue can be?

Thanks

like image 938
Dorin Avatar asked Jul 25 '18 05:07

Dorin


People also ask

What is ingress URL in Kubernetes?

Kubernetes Ingress is an API object that provides routing rules to manage external users' access to the services in a Kubernetes cluster, typically via HTTPS/HTTP. With Ingress, you can easily set up rules for routing traffic without creating a bunch of Load Balancers or exposing each service on the node.


3 Answers

You have to enable ingress addons by following command before creating ingress rules. You can also enable it before executing any other command

$ minikube addons enable ingress
ingress was successfully enabled

Wait until the pods are up and running. You can check by executing following command and wait for the similar output

kubectl get pods -n kube-system | grep nginx-ingress-controller

nginx-ingress-controller-5984b97644-jjng2   1/1       Running   2          1h

enter image description here For Deployment you have to specify the containerPort and for Service you have to specify http protocol.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: echoserver-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-echo
  template:
    metadata:
      labels:
        app: my-echo
    spec:
      containers:
        - name: my-echo
          image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
          ports:
          - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: echoserver-svc
spec:
  selector:
    app: my-echo
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
    name: http

For ingress rule change the port servicePort from 8080 to 80 the default http port.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: happy-ingress
  annotations:
    INGRESS.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: happy.k8s.io
    http:
      paths:
      - path: /echoserver
        backend:
          serviceName: echoserver-svc
          servicePort: 80

Now apply those files and create your pods, service and ingress rule. Wait few moment, it will take few moments to get ADDRESS for your ingress rule. enter image description here Now you can visit your service using minikube ip address but not by host name yet. For that you have to add the host and respective IP address in /etc/hosts file. So open /etc/hosts file in your favorite editor and add below line where is the actual IP of you minikube

<minikube_ip> happy.k8s.io

Now you access you service using host name. Verify be following command

curl http://happy.k8s.io/echoserver
like image 173
Shalauddin Ahamad Shuza Avatar answered Oct 19 '22 00:10

Shalauddin Ahamad Shuza


As official document say:

Because NodePort Services do not get a LoadBalancerIP assigned by definition, the NGINX Ingress controller does not update the status of Ingress objects it manages

You have deployed the NGINX Ingress controller as described in the installation guide, so it is normal for your ADDRESS was empty!

Instead, the external client must append the NodePort allocated to the ingress-nginx Service to HTTP requests.

ps. This question is not about minikube

like image 43
Dylan Lai Avatar answered Oct 18 '22 23:10

Dylan Lai


Ingress problems are specific to your implementation, so let me just speak to a bare-metal, LAN implementation with no load-balancer.

The key validation point of an ingress resource is that it gets an address (after all, what am I supposed to hit, if the ingress doesn't have an address associated with it?) So if you do

kubectl get ingress some-ingress

Over and over (give it 30 seconds or so) and it never shows an address - what now?

On bare-metal LAN there are a few trouble spots. First, ensure that your Ingress resource can find your Ingress controller - so (setting aside the controller spec for now) your resource needs to be able to find your controller with something like:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-api-ingress
  annotations:
    kubernetes.io/ingress.class: nginx

Where your controller has entries like:

Labels:                   app.kubernetes.io/component=controller
                          app.kubernetes.io/instance=ingress-nginx
                          app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=ingress-nginx
                          app.kubernetes.io/version=1.0.4
                          helm.sh/chart=ingress-nginx-4.0.6

But now let's go back a step - your controller - is it setup appropriately for your (in my case) bare-metal LAN implementation? (this is all made super-easy by the cloud providers, so I'm providing this answer for my friends in the private cloud community)

There the issue is that you need this essential hostNetwork setting to be true, in your Ingress controller deployment. So for that, instead of using the basic yamil (https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.4/deploy/static/provider/baremetal/deploy.yaml) - wget it, and modify it to set the spec of the template of the spec of the Deployment, so that hostNetwork: true - something like (scroll down to the end):

# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.6
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.0.4
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/component: controller
  revisionHistoryLimit: 10
  minReadySeconds: 0
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      dnsPolicy: ClusterFirst
      containers:
        - name: controller
          image: k8s.gcr.io/ingress-nginx/controller:v1.0.4@sha256:545cff00370f28363dad31e3b59a94ba377854d3a11f18988f5f9e56841ef9ef
          imagePullPolicy: IfNotPresent
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown
          args:
            - /nginx-ingress-controller
            - --election-id=ingress-controller-leader
            - --controller-class=k8s.io/ingress-nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            - --validating-webhook=:8443
            - --validating-webhook-certificate=/usr/local/certificates/cert
            - --validating-webhook-key=/usr/local/certificates/key
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            runAsUser: 101
            allowPrivilegeEscalation: true
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: LD_PRELOAD
              value: /usr/local/lib/libmimalloc.so
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
            - name: webhook
              containerPort: 8443
              protocol: TCP
          volumeMounts:
            - name: webhook-cert
              mountPath: /usr/local/certificates/
              readOnly: true
          resources:
            requests:
              cpu: 100m
              memory: 90Mi
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      hostNetwork: true
      volumes:
        - name: webhook-cert
          secret:
            secretName: ingress-nginx-admission

Deploy that, then setup your ingress resource, as indicated above.

Your key tests are:

  • Does my ingress have a dedicated node in my bare-metal implementation?
  • if I hit port 80 on the ingress node, do I get the same thing as hitting the NodePort? (let's say NodePort is 31207 - do I get the same thing hitting port 80 on the ingress node as hitting port 31207 on any node?)

Final note: Ingress has changed a lot over the past few years, and tutorials are often providing examples that don't pass validation - please feel free to comment on this answer if it has become out of date

like image 9
James_SO Avatar answered Oct 18 '22 22:10

James_SO