This lab is designed to help students experiment with Kubernetes Pods, understand their behavior, and learn how to manage them.
By the end of this lab, students will:
- Create and manage Kubernetes Pods.
- Understand Pod specifications.
- Experiment with multi-container Pods.
- Observe and debug Pod behavior using Kubernetes commands.
- A Kubernetes cluster (e.g., Minikube, Kind, or a cloud-based cluster).
kubectl
command-line tool installed and configured.- Basic YAML knowledge.
Download Latest Kubeconfig
URL = https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/
Setup your environment variable
Linux/MacOS
export KUBECONFIG=<PATH TO KUBECONFIG FILE>
In Powershell
$env:KUBECONFIG="<Path to your folder>\quick-labs-0-kubeconfig.yaml"
Ensure it is working
kubectl.exe get no
NAME STATUS ROLES AGE VERSION
quick-labs-0-aa0mx Ready <none> 21m v1.32.1
quick-labs-0-aaalz Ready <none> 11h v1.32.1
quick-labs-0-aaapc Ready <none> 11h v1.32.1
Create a file named simple-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: my-first-pod
labels:
app: demo
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-first-service
spec:
selector:
app: demo
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
This YAML file defines two Kubernetes resources:
- Pod (
my-first-pod
): - Service (
my-first-service
):
The first part of the YAML defines a Pod, which is the smallest deployable unit in Kubernetes.
apiVersion: v1
kind: Pod
metadata:
name: my-first-pod
labels:
app: demo
apiVersion: v1
– Specifies the API version used.kind: Pod
– Defines this resource as a Kubernetes Pod.metadata
:name: my-first-pod
– Assigns a name to the Pod.labels
:app: demo
– Labels help with organizing and selecting resources.
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
spec
– Describes the desired behavior of the Pod.containers
– Defines the list of containers within the Pod.name: nginx
– Container is namednginx
.image: nginx:latest
– Uses the latest Nginx container image from Docker Hub.ports
:containerPort: 80
– Exposes port 80 inside the container.
The second part of the YAML defines a Service, which provides networking and load balancing.
apiVersion: v1
kind: Service
metadata:
name: my-first-service
apiVersion: v1
– Specifies the API version used.kind: Service
– Defines this resource as a Service.metadata
:name: my-first-service
– Assigns a name to the Service.
spec:
selector:
app: demo
spec
– Describes the desired behavior of the Service.selector
:app: demo
– Matches any Pod with the labelapp: demo
, which in this case selectsmy-first-pod
.
ports:
- protocol: TCP
port: 80
targetPort: 80
ports
:protocol: TCP
– Uses TCP for communication.port: 80
– Exposes port 80 on the Service.targetPort: 80
– Forwards traffic to port 80 inside the matching Pods.
type: LoadBalancer
type: LoadBalancer
– Exposes the Service externally with a cloud provider-managed load balancer.
kubectl apply -f simple-pod.yaml
Output running from Windows Terminal
kubectl.exe apply -f .\simple-pod.yaml
pod/my-first-pod created
service/my-first-service created
kubectl get pods
Example
kubectl.exe get pods
NAME READY STATUS RESTARTS AGE
my-first-pod 1/1 Running 0 60s
kubectl logs my-first-pod
Output
kubectl.exe logs my-first-pod
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/02/13 17:28:13 [notice] 1#1: using the "epoll" event method
2025/02/13 17:28:13 [notice] 1#1: nginx/1.27.4
2025/02/13 17:28:13 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025/02/13 17:28:13 [notice] 1#1: OS: Linux 6.1.0-29-amd64
2025/02/13 17:28:13 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2025/02/13 17:28:13 [notice] 1#1: start worker processes
2025/02/13 17:28:13 [notice] 1#1: start worker process 29
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.109.0.1 <none> 443/TCP 143m
my-first-service LoadBalancer 10.109.2.95 <External IP> 80:30507/TCP 3m11s
Visit http://<External IP>
in your browser.
Create a file named multi-container-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
labels:
app: demo
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
- name: sidecar
image: busybox:latest
command: ["sh", "-c", "while true; do echo Hello from Sidecar; sleep 5; done"]
kubectl apply -f multi-container-pod.yaml
kubectl logs multi-container-pod -c nginx
kubectl logs multi-container-pod -c sidecar
Write a manifest networking-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: network-pod
labels:
app: demo
spec:
containers:
- name: busybox
image: busybox:latest
command: ["sh", "-c", "sleep 3600"]
kubectl apply -f networking-pod.yaml
kubectl exec -it network-pod -- sh
Inside the Pod:
nslookup quick-labs.io
exit
Write a manifest failing-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: failing-pod
spec:
containers:
- name: failing-container
image: busybox:latest
command: ["sh", "-c", "exit 1"]
kubectl apply -f failing-pod.yaml
kubectl get pods
kubectl describe pod failing-pod
kubectl delete pod failing-pod
Delete all resources created during the lab:
kubectl delete pod my-first-pod multi-container-pod network-pod
- How to create and manage Pods using YAML manifests.
- How to inspect and debug Pods.
- How Pods handle networking and multiple containers.
- How to troubleshoot common Pod issues.