I'm trying to set up a cluster like this:

+--------------+  +---------------+
|              |  |               |
| Express API  |  | Front End     |
|              |  | Static Assets |
|              |  |               |
+------+-------+  +--------+------+
       ^                   ^
       |                   |
       |                   |
+------+-------------------+------+
|  /api/..                 /      |
|            Ingress              |
+--------------+------------------+
               ^
               +
            Internet

For now I'm doing this on Minikube.

I've looked at these two guides:

https://kubernetes.io/docs/concepts/services-networking/ingress/

https://medium.com/@Oskarr3/setting-up-ingress-on-minikube-6ae825e98f82

In the second guide - he exposes his deployments with NodePort services, and then configures his ingress to use those services.

This also means - that those services can be just accessed directly via IP address.

However, my understanding is that that's not necessary - you can just declare an unexposed service, and let ingress expose them. (similar to how they've done it in this official documentation).

ie:

kind: Service
apiVersion: v1
metadata:
  name: template-frontend-service
  labels:
    app: template
spec:
  selector:
    app: template
    type: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

kind: Service
apiVersion: v1
metadata:
  name: template-api-service
  labels:
    app: template
spec:
  selector:
    app: template
    type: api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3001

But this is where I'm running in to an issue:

Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: template-ingress
  labels:
    app: template
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: template.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: template-frontend-service
              servicePort: 80
          - path: /api
            backend:
              serviceName: template-api-service
              servicePort: 80

I get:

503 Service Temporarily Unavailable nginx/1.13.12

On the other hand, if I just expose my deployments directly with:

kubectl expose deploy template-api --type=NodePort
kubectl expose deploy template-frontend --type=NodePort

(this will give me two services template-api and template-frontend)

then this configuration will work:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: template-ingress
  labels:
    app: template
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: template.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: template-frontend
              servicePort: 80
          - path: /api
            backend:
              serviceName: template-api
              servicePort: 80

What am I missing here?

  • Could you share your ingress-controller configuration related to backends "/" and "/api" using command <kubectl exec -it nginx-ingress-controller-RANDOMHASH -n kube-system cat /etc/nginx/nginx.conf > (set the correct namespace and replace controller name with actual name of the ingress controller in your cluster)? – VAS Sep 24 at 17:30

503 Service Temporarily Unavailable

I'm getting this error in two cases:

  • service mentioned in ingress does not exist
  • service does exist, but there is no pod matched by service selector.

Nginx Ingress controller is able to access service without necessity to specifying type=NodePort for a service. I've tested a configuration that is quite close to yours and it works fine with the service type=ClusterIP.
Miniube version is v0.30.0 (ingress addon enabled)

Ingress service is configured as NodePort because we have to access it from host machine:

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

Here is the log of experiment:
I've created two deployments for frontend and api and checked if it's running:

$ kubectl run template-frontend --image=hashicorp/http-echo --labels=app=template,type=frontend -- -listen=:80 -text="Frontend"
$ kubectl run template-api --image=hashicorp/http-echo --labels=app=template,type=api -- -listen=:80 -text="API"
$ kubectl get pods -o wide

I've exposed them via ClusterIP service and checked their addresses:

$ kubectl expose deployment template-frontend --port=80
$ kubectl expose deployment template-api --port=80
$ kubectl get svc -o wide

I've checked accessibility of pods via services using their ClusterIPs:

$ kubectl run ubuntu --rm -it --image ubuntu --restart=Never --command -- bash -c 'apt-get update && apt-get -y install curl less net-tools && bash'

root@ubuntu:/# curl http://10.96.101.51
API
root@ubuntu:/# curl http://10.107.165.156
Frontend

I've applied ingress.yaml file to the cluster:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: template-ingress
  labels:
    app: template
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: template.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: template-frontend
              servicePort: 80
          - path: /api
            backend:
              serviceName: template-api
              servicePort: 80

Now I need to check the IP address of minikube node:

$ minikube ip
192.168.99.100

and the service node port:

$ kubectl get svc --all-namespaces | grep ingress

Usualy the port number in the range of 30000 and 33000

kube-system   nginx-ingress          NodePort    10.99.220.242    <none>        80:32462/TCP,443:32318/TCP   1h        app.kubernetes.io/name=nginx-ingress-controller,app.kubernetes.io/part-of=kube-system

Finally I check if the pods are able to serve requests via ingress:

$ curl -H "Host:template.example.com" http://192.168.99.100:32462/api/
API
$ curl -H "Host:template.example.com" http://192.168.99.100:32462/
Frontend

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.