How do I expose ingress to my local machine? (minikube on windows)

1/30/2020

I have two deployments

deployment 1

apiVersion: v1
kind: Service
metadata:
  name: first-service
spec:
  selector:
    key: app1
  ports:
    - port: 81
      targetPort: 5050

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      run: app1
  template:
    metadata:
      labels:
        run: app1
    spec:
      containers:
      - name: ocr
        image: ocr_app
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5050

deployment 2

apiVersion: v1
kind: Service
metadata:
  name: second-service
spec:
  selector:
    key: app2
  ports:
    - port: 82
      targetPort: 5000

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: second-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      run: app2
  template:
    metadata:
      labels:
        run: app2
    spec:
      containers:
      - name: ner
        image: ner_app
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5000

After enabling ingress on minikube I applied ingess

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  rules:
  - host: demo.local
    http:
      paths:
      - path: /ocr
        backend:
          serviceName: first-service
          servicePort: 81
      - path: /ner
        backend:
          serviceName: second-service
          servicePort: 82

In my hosts file I have

192.168.177.71  demo.local

Where 192.168.177.71 is my current minikube ip

I then ran this command

kubectl port-forward nginx-ingress-controller-6fc5bcc8c9-p6mvj 3000:80 --namespace kube-system

And in the console is outputs

Forwarding from 127.0.0.1:3000 -> 80
Forwarding from [::1]:3000 -> 80

But when I make a request to demo.local:3000/ocr using postman there is no response

Could not get any response There was an error connecting to demo.local:3000.

EDIT: using minikube service first-service gives this output

PS D:\docker> minikube service first-service
|-----------|---------------|-------------|--------------|
| NAMESPACE |     NAME      | TARGET PORT |     URL      |
|-----------|---------------|-------------|--------------|
| default   | first-service |             | No node port |
|-----------|---------------|-------------|--------------|
* service default/first-service has no node port
-- erotavlas
kubernetes
minikube

2 Answers

2/4/2020

@erotavlas as Mafor provided answer which help you resolve your issue please accept his answer.

I am posting extended answer which might help someone else.

Root cause of this Issue was with selector/labels.

In first-service, spec.selector was set to key: app1, however in deployment spec.selector.matchLabels was set to run: app1.

To proper work you need to have the same selectors. So you would need to change in service, spec.selector to run: app1 or change deployment spec.selector.matchLabels to key: app1. Same situation with second-service and second-deployment. More details can be found here.

I've tried to use Ingress on Minikube based on official docs and your YAMLs.

As addition, to use Ingress on Minikube, Ingress addon must be enabled.

$ minikube addons list | grep ingress
- ingress: disabled

If it's disabled, you have to enable it.

$ minikube addons enable ingress
✅  ingress was successfully enabled

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.

OP used own images where application was running on ports 5050 and 5000, for this example I will use GCP hello world on port 8080. Labels/matchLabels were changed to have the sam value in deployment and service.

First service

apiVersion: v1
kind: Service
metadata:
  name: first-service
spec:
  selector:
    key: app1
  ports:
    - port: 81
      targetPort: 8080

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      key: app1
  template:
    metadata:
      labels:
        key: app1
    spec:
      containers:
      - name: hello1
        image: gcr.io/google-samples/hello-app:1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

service/first-service created
deployment.apps/first-deployment created

Second Service

apiVersion: v1
kind: Service
metadata:
  name: second-service
spec:
  selector:
    key: app2
  ports:
    - port: 82
      targetPort: 8080

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: second-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      key: app2
  template:
    metadata:
      labels:
        key: app2
    spec:
      containers:
      - name: hello2
        image: gcr.io/google-samples/hello-app:2.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

service/second-service created
deployment.apps/second-deployment created

It crated services as ClusterIP type. If need you can use NodePort but it's not neccessary.

Apply Ingress

Ingress provided in question is enough to tests.

As mentioned in official docs. You should add minikube ip to host file.

Note: If you are running Minikube locally, use minikube ip to get the external IP. The IP address displayed within the ingress list will be the internal IP.

In Ubuntu OS it's /etc/hosts (need to use sudo to edit). In Windows OS please check this article

For my cluster (Using GCE):

$ minikube ip
10.132.15.208

Added to hosts file value:

10.132.15.208 demo.local

Below responses.

$ curl demo.local/ocr
Hello, world!
Version: 1.0.0
Hostname: first-deployment-85b75bf4f9-qlzrp
$ curl demo.local/ner
Hello, world!
Version: 2.0.0
Hostname: second-deployment-5b5bbb7f4-9sbqr

However, version with rewrite provided by Mafor is more versatile.

In addition, You could also consider use LoadBalancer on Minikube. More information can be found in Minikube docs.

-- PjoterS
Source: StackOverflow

1/30/2020

First thing, you don't need kubectl port-forward. Ingress is exposed on your minikube ip, port 80.

Second, probably you need some rewrite rules in the ingress configuration. By default, ingress forwards requests "as they are", i.e demo.local:3000/ocr is forwarded to first-service:81/ocr. Probably it is not what you want, unless first-service is deployed to /ocr context.

I guess, you need something like this:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: demo.local
    http:
      paths:
      - path: /ocr(/|$)(.*)
        backend:
          serviceName: first-service
          servicePort: 81
      - path: /ner(/|$)(.*)
        backend:
          serviceName: second-service
          servicePort: 82

See https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rewrite

-- Mafor
Source: StackOverflow