Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes Ingress running behind nginx reverse proxy

I have installed minikube on a server which I can access from the internet.

I have created a kubernetes service which is available:

>kubectl get service myservice
NAME        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
myservice   10.0.0.246   <nodes>       80:31988/TCP   14h

The IP address of minikube is:

>minikube ip
192.168.42.135

I would like the URL http://myservice.myhost.com (i.e. port 80) to map to the service in minikube.

I have nginx running on the host (totally unrelated to kubernetes). I can set up a virtual host, mapping the URL to 192.168.42.135:31988 (the node port) and it works fine.

I would like to use an ingress. I've added and enabled ingress. But I am unsure of:

a) what the yaml file should contain

b) how incoming traffic on port 80, from the browser, gets redirected to the ingress and minikube.

c) do I still need to use nginx as a reverse proxy?

d) if so, what address is the ingress-nginx running on (so that I can map traffic to it)?

like image 419
Ant Kutschera Avatar asked Sep 30 '17 22:09

Ant Kutschera


2 Answers

Setup

First of all, you need a nginx ingress controller.

The nginx instance(s) will listen on host 80 and 443 port, and redirect every HTTP request to services which ingress configuration defined, like this.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-service-ingress
annotations:
  # by default the controller redirects (301) HTTP to HTTPS,
  # the following would make it disabled.
  # ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80

Use https://{host-ip}/ to visit myservice, The host should be the one where nginx controller is running at.

Outside

Normally you don't need another nginx outside kubernetes cluster.

While Minikube is a little different, It is running kubernetes in a virtual machine instead of host.

We need do some port-forwards like host:80 => minikube:80, Running a reverse proxy (like nginx) in the host is an elegant way.

It can also be done by setting virtual networking port forward in Virtualbox.

like image 189
silverfox Avatar answered Oct 11 '22 00:10

silverfox


As stated by @silverfox, you need an ingress controller. You can enable the ingress controller in minikube like this:

minikube addons enable ingress

Minikube runs on IP 192.168.42.135, according to minikube ip. And after enabling the ingress addon it listens to port 80 too. But that means a reverse proxy like nginx is required on the host, to proxy calls to port 80 through to minikube.

After enabling ingress on minikube, I created an ingress file (myservice-ingress.yaml):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myservice-ingress
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myservice.myhost.com
      http:
        paths:
        - path: /
          backend:
            serviceName: myservice
            servicePort: 80

Note that this is different to the answer given by @silverfox because it must contain the "host" which should match.

Using this file, I created the ingress:

kubectl create -f myservice-ingress.yaml

Finally, I added a virtual host to nginx (running outside of minikube) to proxy traffic from outside into minikube:

server {
  listen 80;
  server_name myservice.myhost.com;
  location / {
    proxy_set_header Host            $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_pass http://192.168.42.135;
  }
}

The Host header must be passed through because the ingress uses it to match the service. If it is not passed through, minikube cannot match the request to the service.

Remember to restart nginx after adding the virtual host above.

like image 21
Ant Kutschera Avatar answered Oct 11 '22 00:10

Ant Kutschera