part 5: deployment and service

A deployment is an object in Kubernetes that lets you manage a set of identical pods usually that doesn't maintain state.

Below is sample deployment for nginx webserver

vim deploymentngnix.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-sbx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80

kubectl apply -f deploymentngnix.yaml

$ kubectl get deployment
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
nginx-sbx-deployment   1/2     2            1           22m

$ kubectl get pod -o wide
NAME                                   READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginx-sbx-deployment-5d8888c5ff-jc87f   1/1     Running   0          26s   10.244.1.193   nodea   <none>           <none>
nginx-sbx-deployment-5d8888c5ff-zzkp2   1/1     Running   0          27s   10.244.1.128   nodeb   <none>           <none>

ubuntu@masterNode:~$ kubectl edit deployment nginx-sbx-deployment

kubectl delete deployment nginx-sbx-deployment to delete deployment, it took ~3-4 minutes for pods to be terminated on local env.

pods can get created/destroyed to match desired state, pods get their own ip maintained by CNI. this can create problem for eg. frontend and backend application communication can get disrupted due to change in ip. Now comes the service for rescue.

Service:

Service exposes a network application that is running as one or more Pods in your cluster. It makes pods accessible on permanent IP using the service name + also load balances traffic among multiple replicas of the pods.

Kubeproxy(running on all nodes) does the mapping of services to pods. It forwards the request to service endpoint. whenever you define a service(new object) it finds it out in etcd and It uses iptables/ipvs/ebpf and configures mapping service-> pod.

nginxservice.yml
kubectl apply -f nginxservice.yml
#service file
apiVersion: v1
kind: Service
metadata:
  name: nginx-service

spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 8080       # port used by service(host),
      targetPort: 80   # the port container is listening

ubuntu@masterNode:~$ kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP    41h
nginx-service   ClusterIP   10.103.60.169   <none>        8080/TCP   7m32s

ubuntu@masterNode:~$ kubectl describe service nginx-service
Name:              nginx-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.103.60.169
IPs:               10.103.60.169
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.128:80,10.244.1.193:80
Session Affinity:  None
Events:            <none>

Endpoints are the ip address of pods(nginx deployment:running on port 80)
# kubectl get pod -o wide
NAME                                    READY   STATUS      RESTARTS      AGE     IP             NODE    NOMINATED NODE   READINESS GATES
nginx-sbx-deployment-5d8888c5ff-7z7x6   1/1     Running     1 (76s ago)   3m38s   10.244.1.193   nodea   <none>           <none>
nginx-sbx-deployment-5d8888c5ff-xzpkq   0/1     Completed   0             3m38s   10.244.1.128   nodeb   <none>           <none>
the "selector -> app: nginx" must match the label used in nginx deployment yaml file
check the deploymentngnix.yaml above

Labels (key/val pairs) are used to map the pods to its related service. multiple labels (its a list) can be applied to component. Label "selector" is used to identify the component.

To check the endpoints available

ubuntu@masterNode:~$ kubectl get ep
NAME            ENDPOINTS           AGE
kubernetes      192.168.1.50:6443   43h
nginx-service   10.244.1.193:80     72m

service is not process running in node but a Virtual ip accessible throughout cluster, request is sent to service which send to kubeproxy, the kube proxy picks one of available pods to serve request

kubectl get pod --show-labels
kubectl get pod -l app=nginx  #list pod with app=nginx label
kubectl logs -l app=nginx   #show logs of pod with app=nginx label

To run curl command within the pod (you can create new pod named test-nginx)

kubectl run test-nginx --image=nginx

kubectl exec -it nginx-sbx-deployment-5d8888c5ff-fj2jq -- bash
root@nginx-sbx-deployment-5d8888c5ff-fj2jq:/# 
curl http://nginx-service:8080
...