Installing Ingress Controller - Kubernetes

Installing the Ingress Controller

Prerequisites

Make sure you have access to the Ingress controller image:
  • For NGINX Ingress controller, use the image nginxdemos/nginx-ingress from DockerHub.
  • For NGINX Plus Ingress controller, build your own image and push it to your private Docker registry by following the instructions from here.
The installation manifests are located in the install folder. In the steps below we assume that you will be running the commands from that folder.

1. Create a Namespace, a SA and the Default Secret.

  1. Create a namespace and a service account for the Ingress controller:
    kubectl apply -f common/ns-and-sa.yaml
    
    
  2. Create a secret with a TLS certificate and a key for the default server in NGINX:
    $ kubectl apply -f common/default-server-secret.yaml
    
    Note: The default server returns the Not Found page with the 404 status code for all requests for domains for which there are no Ingress rules defined. For testing purposes we include a self-signed certificate and key that we generated. However, we recommend that you use your own certificate and key.
  3. Optional. Create a config map for customizing NGINX configuration (read more about customization here):
    $ kubectl apply -f common/nginx-config.yaml
    

2. Configure RBAC

If RBAC is enabled in your cluster, create a cluster role and bind it to the service account, created in Step 1:
$ kubectl apply -f rbac/rbac.yaml
Note: To perform this step you must be a cluster admin.

3. Deploy the Ingress Controller

We include two options for deploying the Ingress controller:
  • Deployment. Use a Deployment if you plan to dynamically change the number of Ingress controller replicas.
  • DaemonSet. Use a DaemonSet for deploying the Ingress controller on every node or a subset of nodes.

3.1 Create a Deployment

For NGINX, run:
$ kubectl apply -f deployment/nginx-ingress.yaml
For NGINX Plus, run:
$ kubectl apply -f deployment/nginx-plus-ingress.yaml
Note: Update the nginx-plus-ingress.yaml with the container image that you have built.
Kubernetes will create one Ingress controller pod.

3.2 Create a DaemonSet

For NGINX, run:
$ kubectl apply -f daemon-set/nginx-ingress.yaml
For NGINX Plus, run:
$ kubectl apply -f daemon-set/nginx-plus-ingress.yaml
Note: Update the nginx-plus-ingress.yaml with the container image that you have built.
Kubernetes will create an Ingress controller pod on every node of the cluster. Read this doc to learn how to run the Ingress controller on a subset of nodes, instead of every node of the cluster.

3.3 Check that the Ingress Controller is Running

Run the following command to make sure that the Ingress controller pods are running:
$ kubectl get pods --namespace=nginx-ingress

4. Get Access to the Ingress Controller

If you created a daemonset, ports 80 and 443 of the Ingress controller container are mapped to the same ports of the node where the container is running. To access the Ingress controller, use those ports and an IP address of any node of the cluster where the Ingress controller is running.
If you created a deployment, below are two options for accessing the Ingress controller pods.

4.1 Service with the Type NodePort

Create a service with the type NodePort:
$ kubectl create -f service/nodeport.yaml
Kubernetes will allocate two ports on every node of the cluster. To access the Ingress controller, use an IP address of any node of the cluster along with two allocated ports. Read more about the type NodePort here.

4.2 Service with the Type LoadBalancer

Create a service with the type LoadBalancer. Kubernetes will allocate and configure a cloud load balancer for load balancing the Ingress controller pods.
Create a service using a manifest for your cloud provider:
  • For GCP or Azure, run:
    $ kubectl apply -f service/loadbalancer.yaml
    
  • For AWS, run:
    $ kubectl apply -f service/loadbalancer-aws-elb.yaml
    
    Kubernetes will allocate a Classic Load Balancer (ELB) in TCP mode with the PROXY protocol enabled to pass the client's information (the IP address and the port). NGINX must be configured to use the PROXY protocol:
    • Add the following keys to the config map file nginx-config.yaml from the Step 1 :
      proxy-protocol: "True"
      real-ip-header: "proxy_protocol"
      set-real-ip-from: "0.0.0.0/0"
      
    • Update the config map:
      kubectl apply -f common/nginx-config.yaml
      
    Note: For AWS, additional options regarding an allocated load balancer are available, such as the type of a load balancer and SSL termination. Read this doc to learn more.
Use the public IP of the load balancer to access the Ingress controller. To get the public IP:
  • For GCP or Azure, run:
    $ kubectl get svc nginx-ingress --namespace=nginx-ingress
    
  • In case of AWS ELB, the public IP is not reported by kubectl, as the IP addresses of the ELB are not static and you should not rely on them, but rely on the ELB DNS name instead. However, you can use them for testing purposes. To get the DNS name of the ELB, run:
    $ kubectl describe svc nginx-ingress --namespace=nginx-ingress
    
    You can resolve the DNS name into an IP address using nslookup:
    $ nslookup 
    
Read more about the type LoadBalancer here.

5. Access the Live Activity Monitoring Dashboard

For NGINX Plus, you can access the live activity monitoring dashboard:
  1. Use kubectl port-forward command to forward connections to port 8080 on your local machine to port 8080 of an NGINX Plus Ingress controller pod (replace with the actual name of a pod):
    $ kubectl port-forward  8080:8080 --namespace=nginx-ingress 
    
  2. Open your browser at http://127.0.0.1:8080/dashboard.html to access the dashboard.

Support For Prometheus Monitoring

If you are using Prometheus, you can deploy the NGINX Plus Ingress controller with the prometheus exporter for NGINX Plus. The exporter will export NGINX Plus metrics into your Prometheus. To deploy the Ingress controller with the exporter, use the modified manifests:
  • For a deployment, run:
    $ kubectl apply -f deployment/nginx-plus-ingress-with-prometheus.yaml
    
  • For a daemon set, run:
    $ kubectl apply -f daemon-set/nginx-plus-ingress-with-prometheus.yaml
    
Note: this is a preview version of the prometheus exporter for NGINX Plus. It is not suitable for using in production environments.

Uninstall the Ingress Controller

Delete the nginx-ingress namespace to uninstall the Ingress controller along with all the auxiliary resources that were created:
$ kubectl delete namespace nginx-ingress

kubernetes Deployment with Ingress and Ingress Controller


Ingress Controller is a pre-requisite for this exercise. There is only one Ingress-controller for KOPS available on Github. https://github.com/kubernetes/ingress-nginx
I will create another post once I create the Ingress-Controller


$ kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello.yaml
deployment "hello" created

$ kubectl get deploy
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello     7         7         7            6           9s
$


$ kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
host01    Ready         2m        v1.9.0
$ kubectl get pods
NAME                    READY     STATUS    RESTARTS   AGE
hello-f95d44d75-4d6g5   1/1       Running   0          1m
hello-f95d44d75-522kj   1/1       Running   0          1m
hello-f95d44d75-5w4jt   1/1       Running   0          1m
hello-f95d44d75-8tzr7   1/1       Running   0          1m
hello-f95d44d75-m6znh   1/1       Running   0          1m
hello-f95d44d75-s4br5   1/1       Running   0          1m
hello-f95d44d75-tzccb   1/1       Running   0          1m

$ w
 19:22:59 up 6 min,  1 user,  load average: 0.16, 0.15, 0.06
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    172.17.0.52      19:18    0.00s  0.08s  0.00s w

$ netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:10248         0.0.0.0:*               LISTEN      1886/localkube
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      1886/localkube
tcp        0      0 127.0.0.1:2380          0.0.0.0:*               LISTEN      1886/localkube
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      674/sshd
tcp6       0      0 :::8443                 :::*                    LISTEN      1886/localkube
tcp6       0      0 :::4194                 :::*                    LISTEN      1886/localkube
tcp6       0      0 :::10250                :::*                    LISTEN      1886/localkube
tcp6       0      0 :::10251                :::*                    LISTEN      1886/localkube
tcp6       0      0 :::10252                :::*                    LISTEN      1886/localkube
tcp6       0      0 :::10255                :::*                    LISTEN      1886/localkube
tcp6       0      0 :::30000                :::*                    LISTEN      1886/localkube
tcp6       0      0 :::22                   :::*                    LISTEN      674/sshd
$



$ kubectl describe deploy hello
Name:                   hello
Namespace:              default
CreationTimestamp:      Fri, 13 Apr 2018 19:20:16 +0000
Labels:                 app=hello
                        tier=backend
                        track=stable
Annotations:            deployment.kubernetes.io/revision=1
Selector:               app=hello,tier=backend,track=stable
Replicas:               7 desired | 7 updated | 7 total | 7 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=hello
           tier=backend
           track=stable
  Containers:
   hello:
    Image:        gcr.io/google-samples/hello-go-gke:1.0
    Port:         80/TCP
    Environment: 
    Mounts:       
  Volumes:       
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets: 
NewReplicaSet:   hello-f95d44d75 (7/7 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  4m    deployment-controller  Scaled up replica set hello-f95d44d75 to 7




$ kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1            443/TCP   5m
$ kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello-service.yaml
service "hello" created



$ kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello-service.yaml
service "hello" created
$
$
$ kubectl get service
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
hello        ClusterIP   10.111.253.211           80/TCP    2m
kubernetes   ClusterIP   10.96.0.1                443/TCP   8m
$


$ kubectl describe service hello
Name:              hello
Namespace:         default
Labels:           
Annotations:       
Selector:          app=hello,tier=backend
Type:              ClusterIP
IP:                10.111.253.211
Port:                80/TCP
TargetPort:        http/TCP
Endpoints:         172.18.0.10:80,172.18.0.4:80,172.18.0.5:80 + 4 more...
Session Affinity:  None
Events:           
$

$ vi ingress.yaml
$
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  backend:
    serviceName: hello
    servicePort: 80

$ kubectl create -f ingress.yaml
ingress "test-ingress" created
$


$ kubectl get ingress
NAME           HOSTS     ADDRESS   PORTS     AGE
test-ingress   *                   80        26s
$ kubectl get ingress
NAME           HOSTS     ADDRESS   PORTS     AGE
test-ingress   *                   80        28s
$ kubectl describe ingress test-ingress
Name:             test-ingress
Namespace:        default
Address:
Default backend:  hello:80 (172.18.0.10:80,172.18.0.4:80,172.18.0.5:80 + 4 more...)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     *     hello:80 (172.18.0.10:80,172.18.0.4:80,172.18.0.5:80 + 4 more...)
Annotations:
Events: 
$ kubectl get ingress
NAME           HOSTS     ADDRESS   PORTS     AGE
test-ingress   *                   80        2m
$ kubectl get ingress
NAME           HOSTS     ADDRESS   PORTS     AGE
test-ingress   *                   80        2m
$
$

Installing Ingress Controller - Kubernetes

Installing the Ingress Controller Prerequisites Make sure you have access to the Ingress controller image: For NGINX Ingress controll...