Getting Started with Kubernetes Ingress-Nginx on Minikube
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.
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.

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 .kubeDeploying an Application
Now that our cluster is running we can go ahead and start deploying stuff.
- 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-v4l4fPod Information: -no pod information available-Server values: server_version=nginx: 1.12.2 - lua: 10010Request 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/meowRequest 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=httpsRequest 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 - 404Basic 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!!!
