Sunday, June 6, 2021

Kubernetes for Developers #15: Kubernetes Service YAML manifest in-detail

In general, we use application IP address and Port to give access to the external world. However, In Kubernetes world, we are deploying our applications as K8 Pods and it has following limitations.
  • Pods are designed to be ephemeral in nature which means they can be destroyed and re-created with new IP address at any time. Hence, relaying on Pod IP address will not help us.
  • Kubernetes assigns an IP address to a Pod after the pod has been scheduled to a node and before getting started. Hence, we cannot know the Pod IP address prior. 
  • As we run multiple Pods of same application, all Pods should be accessible through a single IP address to the external world.
Kubernetes Service comes into the picture to solve the above problems.

Kubernetes Service provides a single entry or network access to a group of Pods. Each service has an IP address and port that never change while the service exists. All the Pods can communicate with other Pods within the cluster or outside cluster using K8 Service.

  1. Kubernetes Service find the Pods based on their labels which is similar to K8 Deployment matchLabels.
  2. Once service is created, All the Pods in the cluster can communicate with each other using K8 Service IP address or Service name
  3. K8 Service can be created using YAML file or ‘kubectl expose’ command
  4. Internally K8 Endpoints keep track of all selected Pod IPs and these endpoints will be attached to the Service
  5. Kube-proxy module is used to assign virtual IP address for all K8 services.
  6. K8 Service is responsible for enabling network access to set of Pods where as K8 Deployment is responsible for keeping set of Pods running
  7. K8 Service can be created with or without a Pod selector
  8. Once service is created, Kubernetes controller will create a resource called “Endpoints” with the same service name automatically. This “Endpoints” resource will keep track all the selected Pod IPs.
  9. K8 Service supports exposing more than one port from the application/container
  10. K8 Service port can be any number used to map targetPort. Try to use same number for both port and targetPort to avoid confusion.
Create Kubernetes Deployment
Before creating service, first create K8 Deployment and make nginx Pods are up and running with label app:nginx

Read complete article on k8 deployment Kubernetes for Developers #14: Kubernetes Deployment YAML manifest in-detail

apiVersionapps/v1
kindDeployment
metadata:
  namenginx-deployment
spec:
  replicas3
  selector:
    matchLabels:
      appnginx
  template:
    metadata:
      labels:
        appnginx
    spec:
      containers:
        - namenginx
          imagenginx:1.14.2
          ports:
            - containerPort80


// Create a Deployment based on YAML file
$ kubectl apply -f ./nginx-deployment.yaml
deployment.apps/nginx-deployment created

// Display information about all deployments 
$ kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/3     2            2           64s

// Display information about Pods with labels
$ kubectl get pods --show-labels                                                                             
NAME                                READY   STATUS    RESTARTS   AGE   LABELS                                
nginx-deployment-6b474476c4-8mx72   1/1     Running   0          30h   app=nginx
nginx-deployment-6b474476c4-cdhvb   1/1     Running   0          30h   app=nginx
nginx-deployment-6b474476c4-gw975   1/1     Running   0          30h   app=nginx

Create Kubernetes Service
K8 Service will be created in following two ways

1. Create  Service using YAML manifest

apiVersionv1
kindService
metadata:
  namenginx-service
spec:
  selector:
    appnginx
  ports:
    - protocolTCP
      port8081
      targetPort80


// Create a Service using YAML file
$ kubectl apply -f ./nginx-service.yaml
service/nginx-service created  

// Display information about Services
$ kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   10.105.224.36   <none>        8081/TCP    112s

K8 Endpoint object will be created automatically when the Service is created with same service name. It will track all the Pod IPs where label as app:nginx
// Display information about the Endpoints 
$ kubectl get endpoints
NAME            ENDPOINTS                                AGE
nginx-service   10.1.1.68:80,10.1.1.69:80,10.1.1.70:80   19m

NAME: Name of the Endpoint which is same as Service name
ENDPOINTS: list all the Pod IPs where label as app:nginx

By default, Kubernetes Service IP address (i.e. Cluster-IP) and Port will be accessed within the cluster only. So, enter into one of the nginx Pod and make curl using service IP address/name and Port to view nginx webpage
// Enter into nginx Pod shell
$ kubectl exec -it nginx-deployment-6b474476c4-8mx72 -- bin/bash

// update packages
# apt-get update

// install curl
# apt-get install curl

// make curl using service name(or IP ) and port to access nginx webpage
# curl http://nginx-service:8081
(or)
# curl http://10.105.224.36:8081

There is another way to test service by port-forwarding from service port to local computer port
// use kubectl port-forward to test the service in local computer
$ kubectl port-forward service/nginx-service 8081:8081
Forwarding from 127.0.0.1:8081 -> 80
Forwarding from [::1]:8081 -> 80

// Go to browser and hit http://localhost:8081 to view nginx webpage


2. Create  Service using kubectl expose command

$ kubectl expose deployment nginx-deployment --name=nginx-service --port=8081 --target-port=80
service/nginx-service exposed

Kubernetes for Developers Journey.

Happy Coding :)

No comments:

Post a Comment