Categories
General Kubernetes

Kubernetes: NGINX Ingress Controller on GKE

What is an ingress?

An Ingress gives you a way to route requests to services based on the request host or path, centralizing a number of services into a single entrypoint. With an Ingress, there is no need to create a bunch of Load Balancers or exposing each service on the Node. You can simply consolidate your routing rules into a single resource.

Ingress Options

There are many Ingress options, but I am going to focus on the community NGINX version.

What Network Layer is an Ingress configured?

Ingress configures a Layer 7 (Application Layer) HTTP load balancer for Services and provides the following:

  • TLS (Transport Layer Security)
  • Name-based virtual hosting 
  • Path-based routing
  • Custom rules

Install via Helm

I installed the Ingress controller in the itsmetommy namespace and set controller.scope.enabled=true & controller.scope.namespace=itsmetommy so that the controller only watches my namespace instead of the default all namespaces.

  • controller.scope.enabled — limit the scope of the ingress controller
  • controller.scope.namespace — namespace to watch for ingress
helm install stable/nginx-ingress \
  --namespace itsmetommy \
  --name nginx-ingress \
  --set rbac.create=true \
  --set controller.publishService.enabled=true \
  --set controller.scope.enabled=true \
  --set controller.scope.namespace=itsmetommy

Verify.

kubectl get service nginx-ingress-controller -w
NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
nginx-ingress-controller   LoadBalancer   10.7.246.102   35.233.230.93   80:31082/TCP,443:32255/TCP   115s

Git

Clone my kubernetes-ingress-nginx repo that has Ingress examples.

git clone https://github.com/itsmetommy/kubernetes-ingress-nginx.git

Deployments

Create deployments.

{
  kubectl create deploy service1 --image=itsmetommy/helloworld
  kubectl create deploy service2 --image=itsmetommy/helloworld
  kubectl create deploy service3 --image=itsmetommy/helloworld
  kubectl create deploy circle --image=itsmetommy/shape-circle
  kubectl create deploy heart --image=itsmetommy/shape-heart
  kubectl create deploy infinity --image=itsmetommy/shape-infinity
  kubectl create deploy lock --image=itsmetommy/shape-lock
  kubectl create deploy moon --image=itsmetommy/shape-moon
  kubectl create deploy pac-man --image=itsmetommy/shape-pac-man
  kubectl create deploy space-invader --image=itsmetommy/shape-space-invader
  kubectl create deploy square --image=itsmetommy/shape-square
  kubectl create deploy star --image=itsmetommy/shape-star
  kubectl create deploy triangle --image=itsmetommy/shape-triangle
  kubectl create deploy yin-yang --image=itsmetommy/shape-yin-yang
}

Services

Create services.

{
  kubectl expose deploy service1 --port=80 --type=NodePort
  kubectl expose deploy service2 --port=80 --type=NodePort
  kubectl expose deploy service3 --port=80 --type=NodePort
  kubectl expose deploy circle --port=80 --type=NodePort
  kubectl expose deploy heart --port=80 --type=NodePort
  kubectl expose deploy infinity --port=80 --type=NodePort
  kubectl expose deploy lock --port=80 --type=NodePort
  kubectl expose deploy moon --port=80 --type=NodePort
  kubectl expose deploy pac-man --port=80 --type=NodePort
  kubectl expose deploy space-invader --port=80 --type=NodePort
  kubectl expose deploy square --port=80 --type=NodePort
  kubectl expose deploy star --port=80 --type=NodePort
  kubectl expose deploy triangle --port=80 --type=NodePort
  kubectl expose deploy yin-yang --port=80 --type=NodePort
}

Ingress Examples

I’m not going to go over every example, but I will go over a few.

Example 1

kubectl apply -f ingress-example-01.yaml

Get.

kubectl get ing -w
NAME                 HOSTS   ADDRESS         PORTS   AGE
ingress-example-01   *       35.233.230.93   80      5m22s

Describe.

kubectl describe ing ingress-example-01
Name:             ingress-example-01
Namespace:        itsmetommy
Address:          35.233.230.93
Default backend:  circle:80 (10.4.9.19:80)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     *     circle:80 (10.4.9.19:80)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-example-01","namespace":"itsmetommy"},"spec":{"backend":{"serviceName":"circle","servicePort":80}}}

  kubernetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age                  From                      Message
  ----    ------  ----                 ----                      -------
  Normal  CREATE  5m53s                nginx-ingress-controller  Ingress itsmetommy/ingress-example-01
  Normal  UPDATE  5m20s                nginx-ingress-controller  Ingress itsmetommy/ingress-example-01
  Normal  CREATE  2m54s                nginx-ingress-controller  Ingress itsmetommy/ingress-example-01
  Normal  UPDATE  80s (x2 over 2m20s)  nginx-ingress-controller  Ingress itsmetommy/ingress-example-01

Test (use your IP).

https://35.233.230.93/

You should see a red circle.

Clean up.

kubectl delete -f ingress-example-01.yaml

Example 2

kubectl apply -f ingress-example-03.yaml

Get.

kubectl get ing -w
NAME                 HOSTS   ADDRESS         PORTS   AGE
ingress-example-03   *       35.233.230.93   80      69s

Describe.

kubectl describe ing ingress-example-03
Name:             ingress-example-03
Namespace:        itsmetommy
Address:          35.233.230.93
Default backend:  default-http-backend:80 (10.4.8.32:8080)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *
        /foo   service1:80 (<none>)
        /bar   service2:80 (<none>)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-example-03","namespace":"itsmetommy"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"service1","servicePort":80},"path":"/foo"},{"backend":{"serviceName":"service2","servicePort":80},"path":"/bar"}]}}]}}

  kubernetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  96s   nginx-ingress-controller  Ingress itsmetommy/ingress-example-03
  Normal  UPDATE  46s   nginx-ingress-controller  Ingress itsmetommy/ingress-example-03

Test (use your IP).

curl -kL 35.233.230.93/foo
foo%

curl -kL 35.233.230.93/bar
bar%

curl -kL 35.233.230.93
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>

Clean up.

kubectl delete -f ingress-example-03.yaml

Example 3

If you’ve followed my External DNS and Cert Manager blogs, this Ingress example should create DNS entries, along with having a valid SSL Certificate if you are using an existing Certificate. If not, add the annotation certmanager.k8s.io/cluster-issuer: letsencrypt to each Ingress to auto generate the SSL Certificate.

kubectl apply -f ingress-example-08.yaml

Get.

kubkubectl get ing -w
NAME                 HOSTS   ADDRESS         PORTS   AGE
ingress-example-08   itsmetommy.io,www.itsmetommy.io,circle.itsmetommy.io + 10 more...   35.233.230.93   80, 443   36s

Describe.

kubectl describe ing ingress-example-08
Name:             ingress-example-08
Namespace:        itsmetommy
Address:          35.233.230.93
Default backend:  default-http-backend:80 (10.4.8.32:8080)
TLS:
  itsmetommy-io-tls terminates itsmetommy.io,www.itsmetommy.io,circle.itsmetommy.io,heart.itsmetommy.io,infinity.itsmetommy.io,lock.itsmetommy.io,moon.itsmetommy.io,pac-man.itsmetommy.io,space-invader.itsmetommy.io,square.itsmetommy.io,star.itsmetommy.io,triangle.itsmetommy.io,yin-yang.itsmetommy.io
Rules:
  Host                         Path  Backends
  ----                         ----  --------
  itsmetommy.io
                                  service1:80 (<none>)
  www.itsmetommy.io
                                  service1:80 (<none>)
  circle.itsmetommy.io
                                  circle:80 (<none>)
  heart.itsmetommy.io
                                  heart:80 (<none>)
  infinity.itsmetommy.io
                                  infinity:80 (<none>)
  lock.itsmetommy.io
                                  lock:80 (<none>)
  moon.itsmetommy.io
                                  moon:80 (<none>)
  pac-man.itsmetommy.io
                                  pac-man:80 (<none>)
  space-invader.itsmetommy.io
                                  space-invader:80 (<none>)
  square.itsmetommy.io
                                  square:80 (<none>)
  star.itsmetommy.io
                                  star:80 (<none>)
  triangle.itsmetommy.io
                                  triangle:80 (<none>)
  yin-yang.itsmetommy.io
                                  yin-yang:80 (<none>)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-example-08","namespace":"itsmetommy"},"spec":{"rules":[{"host":"itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"service1","servicePort":80}}]}},{"host":"www.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"service1","servicePort":80}}]}},{"host":"circle.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"circle","servicePort":80}}]}},{"host":"heart.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"heart","servicePort":80}}]}},{"host":"infinity.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"infinity","servicePort":80}}]}},{"host":"lock.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"lock","servicePort":80}}]}},{"host":"moon.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"moon","servicePort":80}}]}},{"host":"pac-man.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"pac-man","servicePort":80}}]}},{"host":"space-invader.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"space-invader","servicePort":80}}]}},{"host":"square.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"square","servicePort":80}}]}},{"host":"star.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"star","servicePort":80}}]}},{"host":"triangle.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"triangle","servicePort":80}}]}},{"host":"yin-yang.itsmetommy.io","http":{"paths":[{"backend":{"serviceName":"yin-yang","servicePort":80}}]}}],"tls":[{"hosts":["itsmetommy.io","www.itsmetommy.io","circle.itsmetommy.io","heart.itsmetommy.io","infinity.itsmetommy.io","lock.itsmetommy.io","moon.itsmetommy.io","pac-man.itsmetommy.io","space-invader.itsmetommy.io","square.itsmetommy.io","star.itsmetommy.io","triangle.itsmetommy.io","yin-yang.itsmetommy.io"],"secretName":"itsmetommy-io-tls"}]}}

  kubernetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  59s   nginx-ingress-controller  Ingress itsmetommy/ingress-example-08
  Normal  UPDATE  48s   nginx-ingress-controller  Ingress itsmetommy/ingress-example-08

Test (use your domain) — version may vary.

curl https://itsmetommy.io
Hello World! 3.0.0

curl https://www.itsmetommy.io
Hello World! 3.0.0

Circle

Heart

Infinity

Lock

Moon

Pac-man

Space Invader

Square

Star

Triangle

Yin Yang

Clean up

{
  kubectl delete deploy service1
  kubectl delete deploy service2
  kubectl delete deploy service3
  kubectl delete deploy circle
  kubectl delete deploy heart
  kubectl delete deploy infinity
  kubectl delete deploy lock
  kubectl delete deploy moon
  kubectl delete deploy pac-man
  kubectl delete deploy space-invader
  kubectl delete deploy square
  kubectl delete deploy star
  kubectl delete deploy triangle
  kubectl delete deploy yin-yang
  kubectl delete svc service1
  kubectl delete svc service2
  kubectl delete svc service3
  kubectl delete svc circle
  kubectl delete svc heart
  kubectl delete svc infinity
  kubectl delete svc lock
  kubectl delete svc moon
  kubectl delete svc pac-man
  kubectl delete svc space-invader
  kubectl delete svc square
  kubectl delete svc star
  kubectl delete svc triangle
  kubectl delete svc yin-yang
  kubectl delete ing ingress-example-08
}

Delete Helm chart.

helm delete --purge nginx-ingress