Ingress

Pods and services in Kubernetes have their own IPs. However, this is normally not the interface you'd provide to the external internet. Though there is a service with a node IP configured, the port in the node IP can't be duplicated among the services. It is cumbersome to decide which port to manage with which service. Furthermore, the node comes and goes; it wouldn't be clever to provide a static node IP to an external service.

Ingress defines a set of rules that allows the inbound connection to access Kubernetes cluster services. This brings the traffic into the cluster at L7, and allocates and forwards a port on each VM to the service port. This is shown in the following diagram. We define a set of rules and post them as source type ingress to the API server. When the traffic comes in, the ingress controller will then fulfill and route the ingress according to the ingress rules. As shown in the following diagram, ingress is used to route external traffic to the kubernetes endpoints by different URLs:

Now, we will go through an example and see how this works. In this example, we'll create two services named nginx and echoserver, with the ingress paths /welcome and /echoserver configured. We can run this in minikube. The old version of minikube doesn't enable ingress by default; we'll have to enable it first:

// start over our minikube local
# minikube delete && minikube start // enable ingress in minikube
# minikube addons enable ingress ingress was successfully enabled // check current setting for addons in minikube # minikube addons list - registry: disabled - registry-creds: disabled - addon-manager: enabled - dashboard: enabled - default-storageclass: enabled - kube-dns: enabled - heapster: disabled - ingress: enabled

Enabling ingress in minikube will create an nginx ingress controller (https://github.com/kubernetes/ingress-nginx) and a ConfigMap to store nginx configuration, as well as a Deployment and service as default HTTP backends for handling unmapped requests. We can observe these by adding --namespace=kube-system in the kubectl command. Next, let's create our backend resources. Here is our nginx Deployment and Service:

# cat chapter6/6-2-1_nginx.yaml
apiVersion: apps/v1

kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
template:
metadata:
labels:
project: chapter6
service: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx
spec:
type: NodePort
selector:
project: chapter6
service: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
// create nginx RS and service
# kubectl create -f chapter6/6-2-1_nginx.yaml
deployment.apps/nginx created
service/nginx created

Then, we'll create another service with Deployment:

// another backend named echoserver
# cat chapter6/6-2-1_echoserver.yaml apiVersion: apps/v1 kind: Deployment metadata: name: echoserver spec: replicas: 1 template: metadata: name: echoserver labels: project: chapter6 service: echoserver spec: containers: - name: echoserver image: gcr.io/google_containers/echoserver:1.4 ports: - containerPort: 8080 --- kind: Service apiVersion: v1 metadata: name: echoserver spec: type: NodePort selector: project: chapter6 service: echoserver ports: - protocol: TCP port: 8080 targetPort: 8080 // create RS and SVC by above configuration file # kubectl create -f chapter6/6-2-1_echoserver.yaml deployment.apps/echoserver created
service/echoserver created

Next, we'll create the ingress resource. There is an annotation named nginx.ingress.kubernetes.io/rewrite-target. This is required if the service requests are coming from the root URL. Without a rewrite annotation, we'll get 404 as a response. Refer to https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite for more annotation that's supported in the nginx ingress controller:

# cat chapter6/6-2-1_ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: devops.k8s
http:
paths:
- path: /welcome
backend:
serviceName: nginx
servicePort: 80
- path: /echoserver
backend:
serviceName: echoserver
servicePort: 8080 // create ingress # kubectl create -f chapter6/6-2-1_ingress.yaml ingress.extensions/ingress-example created
In some cloud providers, the service LoadBalancer controller is supported. This can be integrated with ingress via the status.loadBalancer.ingress syntax in the configuration file. For more information, refer to https://github.com/kubernetes/contrib/tree/master/service-loadbalancer.

Since our host is set to devops.k8s, it will only return if we access it from that hostname. You could either configure the DNS record in the DNS server, or modify the host's file in local. For simplicity, we'll just add a line with the ip hostname format in the host file:

// normally host file located in /etc/hosts in linux
# sudo sh -c "echo `minikube ip` devops.k8s >> /etc/hosts"  

Then, we should be able to access our service by the URL directly:

# curl http://devops.k8s/welcome
...
<title>Welcome to nginx!</title>
...
// check echoserver 
# curl http://devops.k8s/echoserver
CLIENT VALUES:
client_address=172.17.0.4
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://devops.k8s:8080/  

The pod ingress controller dispatches the traffic based on the URL's path. The routing path is similar to external-to-service communication. The packet hops between nodes and pods. Kubernetes is pluggable; lots of third-party implementation is going on. We have only scratched the surface here, even though iptables is just a default and common implementation. Networking evolves a lot with every single release. At the time of writing, Kubernetes had just released version 1.13.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset