It is ok for test or development environment to use Service component for exposing our application to external requests. However, we need Ingress for the same logic. It is the actual entry point to external requests in the K8S cluster. Ingress controller plugins are manually installed on the cluster. We are going to use Nginx Ingress. If your setup had an external load balancer/proxy server, it would sit in front of the Ingress controller but we will ignore it this time. This is to avoid exposing K8S components to outside completely. We are using Minikube in this example.


Install


$ minikube addons enable ingress
Verifying ingress addon...
The 'ingress' addon is enabled

$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-f9fd979d6-jwz84 1/1 Running 7 19d
etcd-minikube 1/1 Running 7 19d
ingress-nginx-admission-create-tpbrr 0/1 Completed 0 10m
ingress-nginx-admission-patch-vbwvm 0/1 Completed 2 10m
ingress-nginx-controller-799c9469f7-tkz48 1/1 Running 0 10m
kube-apiserver-minikube 1/1 Running 9 19d
kube-controller-manager-minikube 1/1 Running 7 19d
kube-proxy-fjxvf 1/1 Running 7 19d
kube-scheduler-minikube 1/1 Running 7 19d
storage-provisioner 1/1 Running 30 19d

Run kubectl describe pod -n kube-system ingress-nginx-controller-799c9469f7-tkz48 command to see its details. For more details about Nginx controller annotations check here.


Configuration


apiVersion: networking.k8s.io/v1beta1
kind: Ingress

metadata:
name: address-finder-ingress

spec:
tls:
- hosts:
- my-address-finder.com
secretName: address-finder-tls-secret
rules:
- host: my-address-finder.com
http:
paths:
- path: /
backend:
serviceName: address-finder-service # You can add this, I am skipping.
servicePort: 80

This exposes a single service address-finder-service to external traffic in our Kubernetes cluster. If you wanted to expose other services as well with different domains/hosts or paths, you would need to use path based spec definition above.


SSL


We want only HTTPS access from outside. As soon as the HTTPS request arrives, Nginx SSL termination takes place at Ingress Controller level. Our Ingress setup will instruct the controller to terminate traffic using the provided TLS cert and forward un-encrypted HTTP traffic to internal services (as in plain text). For more information visit here.



Certificates


$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ~/Desktop/k8s.key -out ~/Desktop/k8s.crt \
-subj "/CN=my-address-finder.com/O=my-address-finder.com"

$ kubectl create secret tls address-finder-tls-secret \
--cert=~/Desktop/k8s.crt \
--key=~/Desktop/k8s.key

$ kubectl describe secret address-finder-tls-secret
Name: address-finder-tls-secret
Namespace: default
Labels:
Annotations:

Type: kubernetes.io/tls

Data
====
tls.crt: 1233 bytes
tls.key: 1708 bytes

Hosts


After deploying the ingress, you need to update hosts as shown below. You can get the IP from address-finder-ingress details.


$ nano /etc/hosts
192.168.99.100 my-address-finder.com

Now you can use https://my-address-finder.com in your browser. HTTP won't work.