Kubernetes – Deploy Nginx Ingress Controller as layer between your applications and external Load Balancers

Everyone knows what Kubernetes is, most of us know how to expose a service in NodePort, ClusterIP or LoadBalancer mode but not everyone knows how to use Ingress.

What is an Ingress Controller? In short it is a Load Balancer.

Why do we need it? For more control of you exposed services and not last, cost related; I’ll give an example here: If you are using 100 services exposed via ELBs on Amazon it will cost you around 2,000$/month but if you use one replicated Ingress Controller and expose the 100 services via it it will cost you only 20$/month.

Bellow the order to deploy an Ingress Controller:

Note! This has been tested on Kubernetes 1.6.4

# default-backend.yaml
# kubectl create -f default-backend.yaml
#
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    k8s-app: default-http-backend
  namespace: K8S_NAMESPACE
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        image: gcr.io/google_containers/defaultbackend:1.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
# default-backend-service.yaml
# kubectl create -f default-backend-service.yaml
#
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: K8S_NAMESPACE
  labels:
    k8s-app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    k8s-app: default-http-backend

# nginx-ingress-controller-conf.yaml
# kubectl create -f nginx-ingress-controller-conf.yaml
#
apiVersion: v1
data:
  enable-sticky-sessions: "true"
  body-size: "5m"
kind: ConfigMap
metadata:
  name: nginx-ingress-controller-conf

# nginx-ingress-controller.yaml
# kubectl create -f nginx-ingress-controller.yaml
#
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  labels:
    k8s-app: nginx-ingress-controller
  namespace: K8S_NAMESPACE
spec:
  replicas: 2
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-controller
      annotations:
        prometheus.io/port: '10254'
        prometheus.io/scrape: 'true'
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - image: gcr.io/google_containers/nginx-ingress-controller:0.8.3
        name: nginx-ingress-controller
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          timeoutSeconds: 1
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 443
          hostPort: 443
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        args:
        - /nginx-ingress-controller
        - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
        - --nginx-configmap=default/nginx-ingress-controller-conf

 

Make sure you have the below DNS records pointing as ALIAS to your ELB on Amazon.


# ingress.yaml
# kubectl create -f ingress.yaml
#
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: customer-ingress
  namespace: K8S_NAMESPACE
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - host: "default.test-cloud.eu"
    http:
      paths:
      - path: /
        backend:
          serviceName: default-http-backend
          servicePort: 80
  - host: "tomcat.test-cloud.eu"
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-service
          servicePort: 8080
# ingress-service.yaml
# kubectl create -f ingress-service.yaml
#
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-service
  namespace: K8S_NAMESPACE
spec:
  type: LoadBalancer
  ports:
    - port: 80
      name: http
    - port: 443
      name: https
  selector:
    k8s-app: nginx-ingress-controller

Give it a try! Enhance your services and reduce your cost overhead.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s