Getting Started with Kubernetes Ingress-Nginx on Minikube

Fernando Diaz
Sep 1, 2018 · 6 min read

I have been working on Kubernetes Ingress-Nginx for some time now, and I’ve noticed that there aren’t many tutorials that go over the very basics. I hope that this post will help out those which are new to Kubernetes and getting started deploying their applications.

What is an Ingress? It is a door, a way into your application.

“yellow 8-panel door beside window” by Jünior Rodríguez on Unsplash

How does Ingress work in Kubernetes? In Kubernetes, Ingress works by configuring rules for accessing your applications.

There are 4 items which we will be looking at, Pods, Services, Ingress Resources, and the Ingress Controller. WARNING: I’m going to use alot of door metaphors.

  • A Pod is a group of one or more containers, with shared storage/network, and a specification for how to run the containers. That definition is straight from Kubernetes. It’s the actual application, sitting behind the door.
  • A Service identifies a set of pods that are running your application, and routes traffic to those pods. It does this using label selectors. It’s what’s behind the door, pointing at the application.
  • The Ingress Resource is a collection of rules that allows incoming connections to reach your Services. It is the door.
  • The Ingress Controller uses Ingress Resources to configure application access. In Ingress-Nginx, an Nginx configuration is built from the ingress resources, setting up the routing rules. It is the door person, which opens and closes the door to users.
S=Service, P=Pod, N=Node. From my presentation in KubeCon 2018 Europe.

Tutorial

Now, lets get started with putting all the above into action!

Prerequisites

  • Kubectl
  • VirtualBox
  • VT-x/AMD-v virtualization must be enabled in BIOS
  • Internet connection on first run

Minikube

Minikube makes it easy to get started with Kubernetes. It runs a single-node Kubernetes cluster inside a VM on your laptop. It’s really easy to install and use.

NOTE: I’m using OSX, but the install should be simple for other platforms as well. If using another Operating System, see the installation instructions here. All commands, besides the brew commands, should be the same.

$ brew cask install minikube
🍺 minikube was successfully installed!
$ minikube version
minikube version: v0.28.2
$ minikube start
Starting local Kubernetes v1.10.0 cluster...
Starting VM...
Downloading Minikube ISO
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Downloading kubeadm v1.10.0
Downloading kubelet v1.10.0
Finished Downloading kubelet v1.10.0
Finished Downloading kubeadm v1.10.0
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.
$ minikube status
minikube: Running
cluster: Running
kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.100
$ minikube addons enable ingress
ingress was successfully enabled
# wait a min for the pod to be up and running
$ kubectl get pods -n kube-system | grep nginx-ingress-controller
NAME READY STATUS
nginx-ingress-controller-5984b97644-9kv2t 1/1 Running

If you had any issues, most times its because there was a previous minikube installation, if thats the case for you, try again after uninstalling minikube.

$ minikube delete
Deleting local Kubernetes cluster...
$ brew cask uninstall minikube
==> Uninstalling Cask minikube
==> Unlinking Binary '/usr/local/bin/minikube'.
==> Purging files for version 0.28.2 of Cask minikube
$ rm -rf /usr/local/bin/minikube
$ rm -rf ~/.minikube .kube

Deploying an Application

Now that our cluster is running we can go ahead and start deploying stuff.

  1. Deploy our pods(containers), using deployments. A deployment, pretty much just manages the state of our pods, It’s out of the scope of this tutorial, but you can learn more here.
$ echo "
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: meow
spec:
replicas: 2
selector:
matchLabels:
app: meow
template:
metadata:
labels:
app: meow
spec:
containers:
- name: meow
image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
ports:
- containerPort: 8080
" | kubectl apply -f -
# wait a min for the deployment to be created
$ kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE
meow 2 2 2 2
# you should have 2 pods running
$ kubectl get pods
NAME READY STATUS
meow-5557bc7c54-cw2ck 1/1 Running
meow-5557bc7c54-kfzm5 1/1 Running

The image is the location of the container. When deploying your own application, you would select your image. gcr.io/kubernetes-e2e-test-images/echoserver:2.1 just responds with information about the request.

Also note that containerPort: 8080 is the port that the application is running on.

2. Expose our pods using Services. More info about exposure here.

$ echo "
apiVersion: v1
kind: Service
metadata:
name: meow-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: meow
" | kubectl apply -f -
# wait a min for the service to be created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
meow-svc ClusterIP 10.107.78.24 <none> 80/TCP

Note the targetPort: 8080 is the port we target when we access the service. port: 80 is the port used to access the service.

3. Setup the Ingress Rules.

$ echo "
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: meow-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: \"false\"
spec:
rules:
- http:
paths:
- path: /meow
backend:
serviceName: meow-svc
servicePort: 80
" | kubectl apply -f -
# wait a min for the ingress resource to be created
$ kubectl get ing
NAME HOSTS ADDRESS PORTS
meow-ingress * 10.0.2.15 80

This allows us to access the service meow-svc via the /meow path. Since we didn’t specify a host, then we can access it using the clusterIP.

Note the nginx.ingress.kubernetes.io/ssl-redirect annotation. It is used since we are not specifying a host. When no host is specified, then the default-server is hit, which is configured with a self-signed certificate, and redirects http to https. This issue explains more.

Accessing your application

Now the Ingress rules are configured, we can test everything out. Now let’s send some requests.

$ minikube ip
192.168.99.100
$ curl 192.168.99.100/meow
Hostname: meow-799b895f78-v4l4f
Pod Information:
-no pod information available-
Server values:
server_version=nginx: 1.12.2 - lua: 10010
Request Information:
client_address=172.17.0.5
method=GET
real path=/meow
query=
request_version=1.1
request_scheme=http
request_uri=http://192.168.99.100:8080/meow
Request Headers:
accept=*/*
connection=close
host=192.168.99.100
user-agent=curl/7.54.0
x-forwarded-for=192.168.99.1
x-forwarded-host=192.168.99.100
x-forwarded-port=443
x-forwarded-proto=https
x-original-uri=/meow
x-real-ip=192.168.99.1
x-request-id=a1c65aa5ae7a574e47aaff49548160c5
x-scheme=https
Request Body:
-no body in request-

Note: If we curl other, none-existing endpoint, we get a 404.

$ curl 192.168.99.100/arepa
default backend - 404

Basic Debugging

In this section, we will explore a few basics of debugging. The following show how to gather basic information, which can be useful to determine what’s going on.

Describe the Pods:

Prints a detailed description of the selected pods, which includes events.

$ kubectl get pods -n kube-system | grep nginx-ingress-controller
nginx-ingress-controller-5984b97644-qbwtv 1/1 Running
$ kubectl describe pods -n kube-system nginx-ingress-controller-5984b97644-qbwtv
Name: nginx-ingress-controller-5984b97644-qbwtv
Namespace: kube-system
Node: minikube/10.0.2.15
Start Time: Fri, 31 Aug 2018 16:44:50 -0500
....

View the Logs:

Prints the logs for the nginx-ingress-controller.

$ kubectl get pods -n kube-system | grep nginx-ingress-controller
nginx-ingress-controller-5984b97644-qbwtv 1/1 Running
$ kubectl logs -n kube-system nginx-ingress-controller-5984b97644-qbwtv
....
I0831 21:45:34.090212 5 nginx.go:271] Starting NGINX process
....

View the Nginx Conf:

Displays how nginx configures the application routing rules.

$ kubectl get pods -n kube-system | grep nginx-ingress-controller
nginx-ingress-controller-5984b97644-qbwtv 1/1 Running
$ kubectl exec -it -n kube-system nginx-ingress-controller-5984b97644-qbwtv cat /etc/nginx/nginx.conf
# Configuration checksum: 1983714050352580293
....

Conclusion

Hope you enjoyed this post! For learning more about Ingress-Nginx on Kubernetes, checkout their twitter page!!!

Fernando Diaz

Written by

Living Life and Developing Software, Kubernaut⛵, Keeping life a little weird🗿, Everything I post is my own opinion!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade