Introduction
A Kubernetes Pod is the smallest deployable unit in Kubernetes. It provides the execution environment for one or more containers, along with shared networking and storage resources.
In this mission, I deployed a standalone NGINX Pod to my Azure Kubernetes Service (AKS) cluster, defined its resource requirements, inspected its runtime state, reviewed its logs, accessed the application locally, and examined what happens when a standalone Pod is deleted.
The focus was on the Pod lifecycle and the operational details that matter when running containerized workloads on Kubernetes.
What This Part Covers
- Defining a Pod using a Kubernetes YAML manifest.
- Deploying the Pod to the
k8s-labnamespace. - Verifying its status, IP address, and assigned node.
- Inspecting container configuration and resource constraints.
- Reviewing NGINX logs and verifying its version.
- Accessing the application through port forwarding.
- Observing the behavior of a standalone Pod after deletion.
1. Define the Pod Manifest
I created the manifest at manifests/01-pod.yaml in the project repository.
cat << 'EOF' > manifests/01-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-pod
labels:
app: web-pod
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
EOF
The manifest defines a Pod named web-pod containing one NGINX container.
Key configuration details
-
apiVersion: v1specifies the Kubernetes API version for the Pod resource. -
kind: Podidentifies the resource being created. -
metadata.nameassigns the nameweb-pod. -
metadata.labelsattaches theapp: web-podlabel, which can be used to identify and select the Pod. -
image: nginx:1.27specifies the NGINX container image. -
containerPort: 80documents the port on which the container is expected to receive HTTP traffic. -
CPU request:
50mdeclares 50 millicores of CPU as the container's requested compute capacity. -
Memory request:
64Mideclares 64 mebibytes of requested memory. -
CPU limit:
200msets the container's CPU usage limit. -
Memory limit:
128Misets the container's memory limit.
Resource requests and limits serve different purposes. Requests influence scheduling decisions, while limits constrain the resources a container can consume. CPU limits can result in throttling, whereas exceeding a container's memory limit can lead to termination.
Defining these values makes the workload's resource expectations explicit rather than leaving them entirely unspecified.
2. Deploy the Pod
With the manifest in place, I applied it to the cluster:
kubectl apply -f manifests/01-pod.yaml
Kubernetes confirmed that the resource had been created:
pod/web-pod created
I then checked the Pod's status and placement:
kubectl get pods -o wide
The output showed:
NAME READY STATUS RESTARTS AGE IP NODE
web-pod 1/1 Running 0 25s 10.244.0.139 aks-nodepool1-33590657-vmss000000
The important observations were:
-
Ready:
1/1— the Pod's single container was ready. -
Status:
Running— the Pod had started successfully. -
Restarts:
0— no container restarts had occurred at the time of inspection. -
Pod IP:
10.244.0.139— Kubernetes assigned the Pod an internal IP address. -
Node:
aks-nodepool1-33590657-vmss000000— the scheduler placed the Pod on this AKS worker node.
The -o wide option exposes additional placement and networking information beyond the default Pod listing.
This verified that the manifest had been accepted and the NGINX workload was running in the k8s-lab namespace.
3. Inspect the Pod Configuration and Runtime State
To examine the Pod in more detail, I ran:
kubectl describe pod web-pod
The output confirmed that web-pod was running in the k8s-lab namespace, with the nginx container using the nginx:1.27 image.
The inspection also exposed the container's runtime information, resource configuration, readiness conditions, assigned node, and recent events.
Container readiness
The Pod reported the following conditions as true:
InitializedReadyContainersReadyPodScheduled
These conditions provide useful operational information. A Pod's existence alone does not guarantee that its application is ready to serve traffic. Checking readiness and container state helps distinguish a successfully scheduled workload from one that is actually running and ready.
Resource configuration
The container's reported resource settings matched the manifest:
| Resource | Request | Limit |
|---|---|---|
| CPU | 50m |
200m |
| Memory | 64Mi |
128Mi |
The events also recorded the scheduling, image-pulling, container-creation, and container-start operations.
The image was pulled successfully, and Kubernetes started the container without reporting a restart.
This inspection connected the desired configuration in the YAML manifest with the state Kubernetes was reporting for the running workload.
4. Review the NGINX Logs
I retrieved the container logs with:
kubectl logs web-pod
The output showed the NGINX container entrypoint initializing its configuration and launching the NGINX process.
The logs included messages indicating that configuration was complete and that NGINX was ready to start up. They also showed the NGINX worker processes starting.
Reviewing logs is an important part of troubleshooting containerized applications. They can reveal startup failures, configuration problems, and application-level errors that may not be obvious from the Pod status alone.
In this case, the startup output was consistent with a successfully initialized NGINX container.
5. Verify the NGINX Version
To inspect the NGINX version from inside the running container, I executed:
kubectl exec web-pod -- nginx -v
The command returned:
nginx version: nginx/1.27.5
This verified the version of NGINX running inside the container.
The manifest specified the nginx:1.27 image tag, while the running binary reported version 1.27.5. This illustrates why inspecting the runtime can provide useful information beyond the image tag declared in a manifest.
6. Access the Application with Port Forwarding
The Pod was running NGINX on container port 80. To access it from my local machine without creating a Kubernetes Service or exposing the application publicly, I used port forwarding:
kubectl port-forward pod/web-pod 8080:80
The terminal reported:
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
This forwarded local port 8080 to port 80 on the Pod.
With the port-forwarding process running, I opened the following address in my browser:
http://localhost:8080
The browser displayed the default Welcome to nginx! page, confirming that the NGINX web server was accessible through the local port-forwarding connection.
Port forwarding provided a convenient way to test the application without creating a public endpoint. The connection remained dependent on the kubectl port-forward process, so it was useful for this verification rather than as a production traffic-routing solution.
Important: The port-forwarding command occupies the terminal while it is running. I kept that process active while accessing the page in the browser.
7. Delete the Standalone Pod
After verifying the application, I deleted the Pod:
kubectl delete pod web-pod
Kubernetes confirmed:
pod "web-pod" deleted from k8s-lab namespace
I then checked the namespace for remaining Pods:
kubectl get pods
The result was:
No resources found in k8s-lab namespace.
This confirmed that the standalone Pod had been removed and that no Pods remained in the namespace at the time of the check.
Why the Pod was not recreated
A standalone Pod does not have a higher-level workload controller responsible for maintaining a desired number of replicas.
Deleting it therefore removed the workload without automatically creating a replacement.
This behavior is an important distinction between running a Pod directly and managing workloads through resources such as Deployments or StatefulSets. Controllers can reconcile the actual state with the declared desired state, including replacing Pods when necessary.
For this mission, deleting the standalone Pod demonstrated its lifecycle and the absence of automatic replacement.
8. Operational Takeaways
This mission established a complete workflow for deploying and inspecting a basic Kubernetes workload.
The key operational points were:
- Declarative configuration: A YAML manifest defines the desired Pod configuration and can be stored alongside the rest of the project.
- Resource management: CPU and memory requests and limits establish explicit resource expectations for the container.
-
Runtime inspection:
kubectl get pods -o wideandkubectl describe podexpose different levels of information about scheduling, readiness, networking, and container state. -
Log inspection:
kubectl logshelps reveal what happens during application startup. -
Container-level verification:
kubectl execcan be used to inspect the running container, including its software version. - Local application access: Port forwarding provides a practical way to test a Pod without creating a public endpoint.
- Pod lifecycle: A standalone Pod is not automatically recreated after deletion because no higher-level controller manages its desired state.
Conclusion
The web-pod workload was successfully deployed to AKS, inspected at both the Kubernetes and container levels, accessed through local port forwarding, and subsequently deleted.
The exercise demonstrated how Kubernetes manifests translate into running workloads and how the Kubernetes CLI supports verification throughout the Pod lifecycle.
A standalone Pod is useful for understanding the fundamentals and performing targeted tests. For workloads that require resilience, scaling, and automatic replacement, higher-level controllers provide the management capabilities needed to maintain the desired state.
In the next part of this series, I will continue building on the AKS environment and explore the next workload-management concept in the lab.
This article is Part 3 of the nine-part series, “Kubernetes on AKS: From Zero to Production Workloads.”









Top comments (1)
A Pod may be Kubernetes’ smallest deployable unit, but understanding its lifecycle is fundamental to operating workloads reliably. This mission covered the full workflow - from declarative configuration and resource constraints to runtime inspection, logs, port forwarding, and deletion. It also reinforced an important operational distinction: a standalone Pod does not provide the self-healing behavior of a controller-managed workload.