Pod, Service, and Deployment

Big Picture

Delete existing pods and services
  • Assuming that you have been completed launching K8S via FABRIC, you will have one nginx pod and one nginx service running as part of the validation scheme.
  • First, SSH into node1 using the generated ssh command.
  • Use the following commands to check the existence of the pod and service, then to delete the pod and service.
  • After deletion, check again to confirm that the pod and service are gone.
1
2
3
4
5
kubectl get deployment -o wide
kubectl get pods -o wide
kubectl get svc -o wide
kubectl delete deployment nginx-demo
kubectl delete svc nginx-demo
CAREERDeployments connect development to release engineering

In industry, creating a Deployment is part of a larger release process: building an immutable image, identifying its version, validating the manifest, rolling it out gradually, observing health, and rolling back when necessary. Google’s SRE chapter on release engineering emphasizes reproducible and automated releases rather than one-off “snowflake” procedures.

Practice describing a release with operational evidence:

  • the exact image tag or digest deployed;
  • rollout status and revision history;
  • readiness behavior during replacement;
  • the command and criteria used to roll back;
  • proof that the Service continued selecting healthy Pods.

These are common responsibilities for cloud, DevOps, platform, and SRE roles.

Pods: Containers and Node Abstraction

What is a Pod?
  • A pod includes one or more containers plus additional share resources.
    • Shared resources include, but are not limited to, shared IP (internal/external) and storage volumes.
    • Example pod: one nginx webserver container plus one log-shipper sidecar container plus shared volume for log data.
  • Pods are scheduled onto nodes by the kube-scheduler.
Pod and physical (virtual) node
  • Each node runs a kubelet agent.
  • Kubelet talks to the container runtime (containerd in Rancher Desktop).
  • When a pod is deployed, kubelet pulls the associated container image(s) and runs it(them).
graph TD
    subgraph Node1["Node (VM)"]
        Kubelet1["kubelet + runtime"]
        subgraph Pod1["Pod"]
            Nginx["Container: Nginx"]
        end
    end

    subgraph Node2["Node (VM)"]
        Kubelet2["kubelet + runtime"]
        subgraph Pod2["Pod"]
            Redis["Container: Redis"]
        end
    end

    Kubelet1 --> Pod1
    Kubelet2 --> Pod2
Hands-on with FABRIC
  • Verify that your FABRIC experiment is up and running, then get into the server node and run the followings
1
kubectl get nodes -o wide
  • Create a file called nginx-pod.yaml with the following content
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Pod
metadata:
    name: nginx
    labels:
        app: nginx
spec:
    containers:
    - name: nginx
      image: nginx:latest   # pulls Docker/OCI image
      ports:
      - containerPort: 80
  • Run kubectl and provide path to your nginx-pod.yaml. In the example below, I am in the same directory as my file.
1
2
3
4
kubectl apply -f nginx-pod.yaml
kubectl get pods -o wide
curl 127.0.0.1:80
kubectl exec -it nginx -- curl 127.0.0.1:80

Services: Stable Access to Pods

At this point, if we try to access the above pod using the containerPort 80, it will fail.

Problem
  • Pods are ephemeral
    • Pods can restart and be rescheduled onto different nodes.
    • Each pod gets a random IP inside the cluster.
    • How does a client reliably connect to nginx if its internal IP changes?
  • Docker: -P and -p is not adequate for this.
SOLUTION
  • Kubernetes Service
  • A Service provides Pods with a stable virtual IP and DNS name.
  • Service load-balances traffic to all matching Pods via label.
Connection to Physical Node
  • A ClusterIP service gives access only inside the cluster.
  • A NodePort service opens a port on every node’s IP.
  • A LoadBalancer (on cloud) provisions an external IP (if available).
1
kubectl get nodes
Hands-on: Adding service to pod
  • Create a file called nginx-svc.yaml with the following content
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
    name: nginx
spec:
    type: NodePort
    selector:
        app: nginx
    ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080

Run the following

1
2
3
4
kubectl apply -f nginx-svc.yaml
kubectl get svc -o wide
curl 127.0.0.1:80
curl 127.0.0.1:30080
CHALLENGECleaning up
  • Use kubectl delete to clean up the previously launched nginx pod and nginx service.
  • Use kubectl get to confirm that everything is gone.

Deployment

Hands-on: Create deployment
  • In Kubernetes, Deployment and Service are distinct objects, usually defined in separate YAML files.
    • Deployment: workload management (replicas, rolling updates, Pod templates).
    • Service: network exposure (ClusterIP, NodePort, LoadBalancer).
  • However, it is common practice for examples and small apps to combine them into a single YAML file, using --- as a separator.
  • Create a file called nginx-deployment.yaml with the following content
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
          - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
  • Deployment
    • Ensures 2 replics of nginx Pods always run
    • Each Pod get a random IP inside the cluster.
  • Service
    • Select all Pods with app: nginx.
    • Provide a stable virual IP and DNS name (nginx-service)
    • Expose port 30007 on every node.
1
2
3
4
kubectl apply -f nginx-deployment.yaml
kubectl get deployments
kubectl get pods -o wide
kubectl get svc
Test recovery
  • From the outcomes of kubectl get pods -o wide, delete one pod.
1
2
3
4
kubectl get deployments
kubectl get pods
kubectl delete pods POD_NAME
kubectl get pods
  • Check again and observe how nginx-deployment immediately create a replacement pod.
CHALLENGENavigation inside the containers
  • Explore the usage of kubectl exec -it and attempt to open a shell terminal into your running pods/containers from part 1.
  • Who are you inside the container?
  • Can you ping other pods/containers?
  • Can you download/install software (apt-get/yum/wget …) inside the pods/containers?