dev-ops-challenges

Deploy Pods in a Kubernetes Cluster

Technical Overview

Deploying applications in Kubernetes (K8s) requires interacting with the cluster’s API server. While production environments rely on declarative YAML configuration files to maintain state, developers and system administrators frequently use imperative commands for rapid prototyping, ad-hoc administration, and debugging.

Core Kubernetes Concepts

  1. kubectl: The command-line interface (CLI) tool used to execute commands against Kubernetes API clusters. It reads configurations from the local kubeconfig file (typically located at ~/.kube/config) to authenticate and target the active cluster context.

  2. Pods: The smallest, most basic deployable computing unit in Kubernetes. A Pod hosts one or more containers (e.g., helper sidecars next to a main application container). Containers inside a single Pod share:

    • Network namespace: They share a single IP address and port space, allowing them to communicate via localhost.
    • Storage volumes: Local storage mounts can be shared directly across containers within the Pod.

Imperative Commands vs. Declarative Configurations


Key Command Parameters for Prototyping

1. Dry Run (--dry-run=client)

Executes the command locally to validate syntax, requirements, and permissions against the client-side API without sending any modifications to the live cluster. This prevents incomplete or erroneous resources from being created.

2. Output Formatting (-o)

Specifies the format in which the resource details are returned:

flowchart TD
    A[Identify deployment requirements] --> B[Run imperative command with --dry-run=client -o yaml]
    B --> C[Save output to a manifest.yaml file]
    C --> D[Modify and customize the manifest.yaml]
    D --> E[Apply the manifest: kubectl apply -f manifest.yaml]
    E --> F[Resource successfully deployed in cluster]

Infrastructure & Configuration Requirements


Step-by-Step Implementation

Step 1: Log in to the Cluster Controller/Jump Host

Establish terminal access to the command host configured with cluster access:

ssh thor@jump_host_ip

Step 2: Validate Cluster Connection

Ensure that your kubectl client is communicating successfully with the target cluster:

kubectl cluster-info
kubectl get nodes

Step 3: Generate a Declarative Manifest (Dry Run)

Before creating the Pod, generate the YAML manifest template to confirm the configuration and save it for record-keeping:

kubectl run nginx-pod \
  --image=nginx:alpine \
  --port=80 \
  --dry-run=client \
  -o yaml > pod.yaml

Inspect the generated file to ensure it aligns with expectations:

cat pod.yaml

Expected Output:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx-pod
  name: nginx-pod
spec:
  containers:
  - image: nginx:alpine
    name: nginx-pod
    ports:
    - containerPort: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

Step 4: Deploy the Pod

Create the Pod by applying the generated configuration:

kubectl apply -f pod.yaml

Alternatively, you can run it directly using the imperative command without a dry-run:

kubectl run nginx-pod --image=nginx:alpine --port=80

Post-Deployment Verification

1. Check Pod Listing and Details

List the running pods to confirm that nginx-pod is in the Running state:

kubectl get pods

Expected Output:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          10s

2. View Extended Listing

Show the Pod’s internal IP address and the host Node it has been scheduled to run on:

kubectl get pods -o wide

Expected Output:

NAME        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
nginx-pod   1/1     Running   0          25s   10.244.1.5   node01     <none>           <none>

3. Retrieve Resource Details in YAML

Inspect the live state of the Pod directly from the cluster in YAML format:

kubectl get pod nginx-pod -o yaml

4. Fetch Pod Web Response

Query the Nginx web root directly from inside the cluster using a temporary debug Pod:

kubectl run busybox --image=busybox -it --rm --restart=Never -- wget -qO- 10.244.1.5:80

Expected Output:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...