Kubernetes is an open-source platform for deploying, scaling and operating containerised applications across clusters of machines. For QA engineers, it matters because the environment being tested is no longer just “a server”: application instances can be recreated, moved, scaled, updated and exposed through several layers of networking and configuration. Understanding the core Kubernetes objects makes it much easier to diagnose environment failures, validate deployments and design reliable automated tests for cloud-native systems.
Why Kubernetes exists
Containers solve application packaging well, but once a system contains many containers across many machines, new operational questions appear:
- Where should each workload run?
- What happens when a container or machine fails?
- How should several replicas of the same application be reached?
- How can a new application version be rolled out without replacing everything at once?
- How should environment-specific configuration and secrets be injected?
- How do stateful workloads retain data when Pods are recreated?
- How can the same application topology run across local, on-premises or cloud infrastructure?
Kubernetes provides declarative APIs and controllers to solve these problems. Instead of scripting every infrastructure action directly, you normally describe the desired state and let the platform continually reconcile the actual state towards it.
Scheduling
Places Pods on suitable worker nodes based on available resources and scheduling rules.
Self-healing
Recreates failed Pods and can restart unhealthy containers according to workload configuration.
Scaling
Runs several interchangeable instances and can scale them manually or automatically.
Service discovery
Provides stable Service endpoints even while the Pods behind them are replaced.
Configuration
Separates runtime configuration and sensitive values from container images.
Rolling delivery
Deployments support controlled updates, rollout status and rollback to previous revisions.
From the original Kubernetes model to the modern platform
Older introductions to Kubernetes often use concepts and commands that still explain the platform historically but should not be copied directly into a current project.
| Older material | Current interpretation |
|---|---|
| Master node | Use control plane. The control plane manages cluster state and scheduling. |
| Worker node must run Docker | Nodes require a Kubernetes-compatible container runtime through the Container Runtime Interface (CRI); Docker Engine is not a required runtime. |
| ReplicationController | Legacy workload controller. For normal stateless applications, use a Deployment, which manages ReplicaSets. |
| Replication Set | The correct resource name is ReplicaSet. |
kubectl create -f for ongoing management | Declarative kubectl apply -f is usually preferable for version-controlled application configuration. |
| Direct Pod deployment | Useful for learning and debugging, but production application Pods are normally owned by a higher-level workload such as a Deployment, StatefulSet or Job. |
| Ingress as the future HTTP routing layer | Ingress remains stable and widely used, but its API is frozen; Kubernetes recommends Gateway API for newer routing capabilities. |
| Secret = base64 encoded | Base64 is encoding, not protection. Secrets require RBAC, encryption-at-rest configuration and careful access controls. |
Kubernetes cluster architecture
A Kubernetes cluster consists of a control plane and one or more worker nodes. The control plane exposes the Kubernetes API and decides how the desired state should be achieved. Worker nodes run the actual application Pods.
kubectl / CI / API clients
│
▼
┌───────────────────┐
│ Control Plane │
│ │
│ kube-apiserver │
│ etcd │
│ scheduler │
│ controllers │
└─────────┬─────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Worker Node│ │ Worker Node│ │ Worker Node│
│ kubelet │ │ kubelet │ │ kubelet │
│ runtime │ │ runtime │ │ runtime │
│ networking │ │ networking │ │ networking │
│ Pods │ │ Pods │ │ Pods │
└────────────┘ └────────────┘ └────────────┘
Control plane components
| Component | Responsibility |
|---|---|
kube-apiserver | Exposes the Kubernetes HTTP API. Almost every cluster operation goes through it. |
etcd | Highly available key-value store containing Kubernetes API data. |
kube-scheduler | Finds unscheduled Pods and selects appropriate nodes for them. |
kube-controller-manager | Runs controllers that continuously reconcile desired and actual resource state. |
cloud-controller-manager | Optional integration between Kubernetes and a cloud provider. |
Worker-node components
| Component | Responsibility |
|---|---|
kubelet | Node agent that ensures assigned Pods and their containers are running as declared. |
| Container runtime | Runs containers. Common Kubernetes environments use CRI-compatible runtimes such as containerd or CRI-O. |
kube-proxy | Optional networking component that implements Service traffic rules on nodes. |
Pods: the smallest deployable compute object
A Pod is the smallest deployable compute object in Kubernetes. A Pod usually contains one application container, but it can contain multiple tightly coupled containers that need to share networking and storage.
- Containers inside one Pod share the Pod network namespace.
- They can communicate with each other over
localhost. - The Pod receives its own cluster network identity.
- Pods are intentionally disposable and may be recreated with a new name or IP.
- The scheduler places Pods on nodes; it does not independently schedule each container inside the Pod.
Simple Pod manifest
apiVersion: v1
kind: Pod
metadata:
name: qa-demo
labels:
app: qa-demo
spec:
containers:
- name: web
image: nginx:1.29
ports:
- containerPort: 80
This is useful for learning, but for a real web application you would usually wrap the Pod template in a Deployment.
Labels and selectors
Labels are key-value metadata attached to Kubernetes resources. Selectors use those labels to identify related objects.
metadata:
labels:
app: checkout
environment: qa
tier: backend
A Service might select every Pod with app: checkout, while a Deployment uses matching labels to identify the Pods that belong to it.
Why labels matter to QA
- Filter Pods belonging to one service.
- Separate environments or components.
- Find all replicas of an application.
- Select the correct backend Pods for a Service.
- Target debugging and log commands more precisely.
kubectl get pods -l app=checkout
kubectl get pods -l environment=qa,tier=backend
Deployments and ReplicaSets
A Deployment is the standard higher-level workload for stateless applications. You declare how many replicas should exist and which Pod template they should use. Kubernetes then uses ReplicaSets to maintain those Pods.
apiVersion: apps/v1
kind: Deployment
metadata:
name: qa-demo
spec:
replicas: 3
selector:
matchLabels:
app: qa-demo
template:
metadata:
labels:
app: qa-demo
spec:
containers:
- name: web
image: nginx:1.29
ports:
- containerPort: 80
What a Deployment gives you
- Desired replica count.
- Replacement of failed or deleted Pods.
- Rolling updates when the Pod template changes.
- Rollout status and revision history.
- Rollback to a previous revision.
- Manual or automated horizontal scaling.
Useful rollout commands
# Watch rollout progress
kubectl rollout status deployment/qa-demo
# See rollout history
kubectl rollout history deployment/qa-demo
# Update the application image
kubectl set image deployment/qa-demo web=nginx:1.30
# Undo the latest rollout
kubectl rollout undo deployment/qa-demo
# Scale manually
kubectl scale deployment/qa-demo --replicas=5
Other workload types worth knowing
| Resource | Use | QA example |
|---|---|---|
| Deployment | Stateless, interchangeable application instances. | Web/API services. |
| StatefulSet | Pods requiring stable identity or persistent storage relationships. | Stateful database or clustered system tests. |
| DaemonSet | Runs a Pod on matching nodes. | Node-level logging, security or monitoring agents. |
| Job | Runs work to completion. | Database migration or one-off processing. |
| CronJob | Creates Jobs on a schedule. | Scheduled reports, cleanup or batch processing. |
Services: stable access to changing Pods
Pods are ephemeral, so clients should usually not connect to their IP addresses directly. A Kubernetes Service provides a stable network abstraction for a logical group of Pods.
apiVersion: v1
kind: Service
metadata:
name: qa-demo
spec:
selector:
app: qa-demo
ports:
- name: http
port: 80
targetPort: 80
type: ClusterIP
The Service selector discovers matching Pods and Kubernetes maintains the backend endpoints as Pods are created or removed.
Service types
| Type | Purpose | Typical use |
|---|---|---|
ClusterIP | Internal cluster IP. This is the default. | Service-to-service communication. |
NodePort | Exposes the Service through a static port on node IPs. | Simple labs or external integration where appropriate. |
LoadBalancer | Requests an external load balancer from the environment/provider. | Externally accessible applications. |
ExternalName | Returns a DNS CNAME for an external hostname. | Represent an external dependency through cluster DNS. |
port vs targetPort vs nodePort
ports:
- port: 80 # Port exposed by the Service
targetPort: 3000 # Port used by the application in the Pod
nodePort: 31080 # Only relevant when NodePort is used
Service discovery and DNS
Cluster DNS normally creates DNS records for Services. A Service called payments in namespace qa can be addressed within the same namespace simply as:
http://payments
From another namespace, qualify it:
http://payments.qa
http://payments.qa.svc.cluster.local
This is more reliable than discovering individual Pod names or IP addresses.
Ingress and Gateway API
Services provide network access to workloads, but web systems often need host-based or path-based HTTP routing, TLS termination and a common external entry point.
Ingress
Ingress defines HTTP/HTTPS routing rules and requires an Ingress controller to implement them. It remains stable and widely deployed, but the Kubernetes project has frozen the Ingress API.
Gateway API
Gateway API is the newer Kubernetes networking API family recommended for new capabilities. It separates infrastructure-facing gateway configuration from application routes more cleanly and supports richer routing models.
| Need | Possible resource |
|---|---|
| Internal service-to-service connection | ClusterIP Service |
| Temporary local debugging | kubectl port-forward |
| Simple external port exposure | NodePort or LoadBalancer Service |
| HTTP/HTTPS routing in an established cluster | Ingress + Ingress controller |
| Modern advanced traffic routing | Gateway API implementation |
ConfigMaps: non-sensitive runtime configuration
A ConfigMap stores non-confidential configuration separately from container images. Pods can consume values as environment variables, command arguments or mounted configuration files.
apiVersion: v1
kind: ConfigMap
metadata:
name: qa-demo-config
data:
API_URL: "https://api.qa.example.com"
LOG_LEVEL: "debug"
Consume a key as an environment variable
env:
- name: API_URL
valueFrom:
configMapKeyRef:
name: qa-demo-config
key: API_URL
This helps the same application image run across development, QA, staging and production while configuration changes independently.
Secrets: sensitive configuration
A Secret is intended for sensitive values such as passwords, tokens, certificates or registry credentials.
apiVersion: v1
kind: Secret
metadata:
name: qa-demo-secret
type: Opaque
stringData:
DB_PASSWORD: "replace-me"
Use the Secret in a container
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: qa-demo-secret
key: DB_PASSWORD
Secret data values are commonly base64 encoded, but that is not encryption. Kubernetes documentation warns that Secrets are stored unencrypted in etcd by default unless encryption at rest is enabled. A secure cluster should also apply least-privilege RBAC and restrict which workloads can access particular Secrets.
For test environments
- Use dedicated QA credentials rather than production credentials.
- Keep Secrets out of Git repositories.
- Avoid printing Secret values into CI logs or test reports.
- Rotate credentials used by shared test environments.
- Prefer secret-management integrations where organisational standards require them.
Volumes and persistent storage
Files written into a container's writable layer should not be treated as durable application storage. Kubernetes offers several volume mechanisms and a dedicated persistent-storage API.
PersistentVolume and PersistentVolumeClaim
- A PersistentVolume (PV) represents storage available to the cluster.
- A PersistentVolumeClaim (PVC) requests storage for a workload.
- A StorageClass describes storage classes and often enables dynamic provisioning.
Example claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: qa-db-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Mount the claim
spec:
containers:
- name: db
image: postgres:17
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: qa-db-data
Health checks: readiness, liveness and startup probes
Kubernetes health probes are extremely important for both operability and testing. They control whether a container receives traffic and whether Kubernetes should restart it.
| Probe | Question | If it fails |
|---|---|---|
| Readiness | Can this container serve traffic now? | The Pod becomes unready and should stop receiving Service traffic. |
| Liveness | Is this container still functioning? | The kubelet can restart the container after configured failures. |
| Startup | Has this slow-starting application finished starting? | Protects the application from premature liveness/readiness behaviour during startup. |
Example
containers:
- name: api
image: example/qa-api:1.4.0
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /health/startup
port: 8080
periodSeconds: 5
failureThreshold: 30
readinessProbe:
httpGet:
path: /health/ready
port: 8080
periodSeconds: 5
livenessProbe:
httpGet:
path: /health/live
port: 8080
periodSeconds: 10
Probe scenarios QA should test
- The application does not receive traffic before it is ready.
- Temporary dependency failure removes readiness without causing unnecessary restart loops.
- A genuine deadlock or unrecoverable state causes liveness failure and restart.
- A slow application start is protected by the startup probe.
- Health endpoints test meaningful application health rather than always returning 200.
Resources: requests and limits
Containers can declare CPU and memory requests and limits. These influence scheduling and runtime behaviour.
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
Why QA should care
- An application that passes with unlimited local resources may fail under realistic limits.
- Memory limits can expose leaks or oversized caches.
- CPU throttling can reveal timeout assumptions.
- Incorrect requests can prevent Pods from being scheduled.
- Scaling behaviour depends on how workloads consume resources.
kubectl: the main command-line interface
kubectl communicates with the Kubernetes API using the currently selected kubeconfig context. A QA engineer does not need cluster-admin privileges to benefit from it; read-only or namespace-scoped access can already make debugging far easier.
Discover resources
| Command | Use |
|---|---|
kubectl get pods | List Pods in the current namespace. |
kubectl get pods -o wide | Include node and IP details. |
kubectl get deploy,svc | List Deployments and Services. |
kubectl get all | Convenient view of several common workload resources; not literally every Kubernetes resource type. |
kubectl get events --sort-by=.lastTimestamp | Inspect recent cluster events. |
kubectl explain deployment.spec | Read API documentation directly from kubectl. |
Inspect and debug
# Detailed resource state and recent events
kubectl describe pod qa-demo-abc123
# Read logs
kubectl logs pod/qa-demo-abc123
# Follow logs
kubectl logs -f pod/qa-demo-abc123
# Logs from a particular container in a multi-container Pod
kubectl logs pod/qa-demo-abc123 -c api
# Previous container instance after a restart
kubectl logs pod/qa-demo-abc123 --previous
# Run a command
kubectl exec pod/qa-demo-abc123 -- printenv
# Open an interactive shell when available
kubectl exec -it pod/qa-demo-abc123 -- /bin/sh
# Create an ephemeral debugging session
kubectl debug pod/qa-demo-abc123 -it --image=busybox:1.36
Temporary access without exposing a Service publicly
kubectl port-forward service/qa-demo 8080:80
# Application is then available locally:
# http://localhost:8080
Port forwarding is excellent for manual QA and debugging because it can expose an internal Service to your workstation without creating a permanent external route.
Contexts and namespaces
A kubeconfig can contain several clusters, users and contexts. Always confirm which context and namespace you are using before changing resources.
kubectl config current-context
kubectl config get-contexts
kubectl config use-context qa-cluster
kubectl config set-context --current --namespace=qa
kubectl config view --minify
Declarative configuration files
Kubernetes objects are commonly stored as YAML manifests. The core structure usually contains:
apiVersion: apps/v1
kind: Deployment
metadata:
name: qa-demo
labels:
app: qa-demo
spec:
# desired object state
...
| Field | Meaning |
|---|---|
apiVersion | Which Kubernetes API group/version defines the object. |
kind | The resource type, such as Pod, Service or Deployment. |
metadata | Name, namespace, labels, annotations and other identity information. |
spec | The desired state for resources that define a spec. |
status | Observed state reported by Kubernetes; normally managed by the system rather than authored in manifests. |
Apply configuration
# Create or update declared resources
kubectl apply -f k8s/
# Preview client-side differences
kubectl diff -f k8s/
# Delete resources declared in a file
kubectl delete -f k8s/deployment.yaml
Validate what actually exists
kubectl get deployment qa-demo -o yaml
kubectl get service qa-demo -o yaml
For QA, version-controlled manifests are especially valuable because environment changes become reviewable and reproducible.
Complete application example
The following example combines a Deployment and Service using matching labels.
apiVersion: apps/v1
kind: Deployment
metadata:
name: qa-demo
spec:
replicas: 2
selector:
matchLabels:
app: qa-demo
template:
metadata:
labels:
app: qa-demo
spec:
containers:
- name: app
image: nginx:1.29
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 2
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: qa-demo
spec:
selector:
app: qa-demo
ports:
- name: http
port: 80
targetPort: http
type: ClusterIP
Deploy and access
kubectl apply -f qa-demo.yaml
kubectl rollout status deployment/qa-demo
kubectl get pods -l app=qa-demo
kubectl port-forward service/qa-demo 8080:80
Run Kubernetes locally
For learning and local development, Kubernetes currently documents several practical choices including kind and minikube. Minikube remains a convenient option for following the concepts in the original material.
Minikube basics
# Start a local cluster
minikube start
# Check cluster Pods
kubectl get pods -A
# Open the dashboard
minikube dashboard
# Get only the dashboard URL
minikube dashboard --url
# Stop without deleting
minikube stop
# Delete the cluster
minikube delete
Deploy a sample app
kubectl create deployment hello-minikube \
--image=kicbase/echo-server:1.0
kubectl expose deployment hello-minikube \
--type=NodePort \
--port=8080
minikube service hello-minikube
Alternatively, use kubectl port-forward to access the application locally without depending on NodePort behaviour.
A QA engineer’s Kubernetes workflow
You do not need to administer the cluster to use Kubernetes effectively in QA. A common test workflow looks like this:
- Confirm the target context and namespace. Make sure you are testing the intended environment.
- Check the rollout. Verify the new Deployment revision completed successfully.
- Confirm the expected image. Ensure the Pods use the build/version intended for testing.
- Check readiness. Wait until the required replicas are Ready before starting automated regression.
- Inspect Services and routes. Verify the application endpoint resolves to ready backends.
- Run smoke tests. Catch broken configuration quickly before expensive regression suites begin.
- Execute broader automation. Run API, UI, integration and non-functional coverage as appropriate.
- Collect evidence on failure. Capture Pod status, events, logs and rollout information.
- Separate environment failure from product failure. A Pending Pod or failed image pull is not the same defect as an API returning incorrect business data.
- Verify recovery. Where relevant, test restart, scaling, rollout and dependency-failure behaviour.
Useful Kubernetes checks before regression
# 1. Confirm environment
kubectl config current-context
kubectl config view --minify
# 2. Check rollout
kubectl rollout status deployment/my-app
# 3. Check desired/available replicas
kubectl get deployment my-app
# 4. Check Pods
kubectl get pods -l app=my-app
# 5. Inspect unhealthy Pods
kubectl describe pod <pod-name>
# 6. Check logs
kubectl logs deployment/my-app --tail=200
# 7. Check recent events
kubectl get events --sort-by=.lastTimestamp
These checks are easy to automate as a pre-test gate in CI.
Testing self-healing
Kubernetes is designed to recover from failures, but the application must still behave correctly while recovery happens. Useful resilience scenarios include:
- Delete one Pod while requests are being sent and verify the Service continues to operate if enough replicas remain.
- Cause a container process to fail and verify restart/replacement behaviour.
- Make readiness fail and verify traffic is removed from that Pod.
- Scale the Deployment up and confirm new replicas join successfully.
- Scale down and verify no unexpected state is lost.
- Roll out a new image while smoke traffic is running and check for unacceptable errors.
- Rollback the Deployment and verify the previous version becomes healthy again.
Controlled Pod deletion
kubectl delete pod <pod-name>
# A Deployment should create a replacement Pod automatically
kubectl get pods -w
Testing rolling deployments
A deployment can appear successful while still causing short service interruptions or incorrect compatibility between old and new instances. QA should consider the transition itself.
Questions to test
- Does the old version remain available until new replicas are Ready?
- Can old and new versions safely run at the same time during the rollout?
- Are database/schema changes backwards compatible with both revisions?
- Do readiness probes protect users from partially initialised instances?
- Does a failed rollout stop before all known-good replicas disappear?
- Does rollback restore functionality quickly?
Useful commands
kubectl rollout status deployment/my-app
kubectl rollout history deployment/my-app
kubectl describe deployment my-app
kubectl rollout undo deployment/my-app
Common Kubernetes failure states
| Symptom | Likely meaning | First checks |
|---|---|---|
Pending | Pod has not been scheduled or cannot satisfy requirements. | kubectl describe pod, node capacity, PVC binding, scheduling constraints. |
ImagePullBackOff | Container image cannot be downloaded. | Image name/tag, registry credentials, network access. |
CrashLoopBackOff | Container repeatedly starts and fails. | Current and previous logs, config, missing dependencies, liveness configuration. |
Running but not Ready | Process exists but readiness requirements are failing. | Readiness probe, application dependencies, logs. |
| Service has no working backends | Selector mismatch or matching Pods are not Ready. | Service selector, Pod labels, EndpointSlices, readiness. |
| Configuration appears unchanged | Pods may still be using an old environment/config state. | How the ConfigMap/Secret is consumed and whether a rollout/restart is required. |
| Pod restarts | Process exit, liveness failure, resource problem or node event. | Restart count, --previous logs, events, resource usage. |
Debugging from the outside in
A useful troubleshooting order prevents application debugging from starting before basic platform health is confirmed.
- Context: Am I in the correct cluster and namespace?
- Deployment: Did the rollout complete?
- Pods: Are enough replicas Running and Ready?
- Events: Did scheduling, image pulling or mounting fail?
- Logs: Does the application report a startup/runtime failure?
- Service: Does its selector match the correct ready Pods?
- DNS/network: Can dependencies resolve and connect?
- Configuration: Are the correct ConfigMap/Secret values mounted?
- Storage: Are PVCs bound and volumes mounted?
- Application: Only after platform basics pass, investigate business behaviour.
Kubernetes and test automation
Kubernetes can become part of the automation workflow rather than just the place where the application happens to run.
Ephemeral namespaces
Create isolated namespaces or preview environments for pull requests and delete them when testing ends.
Pre-test gates
Wait for Deployment readiness before starting Playwright or API regression.
Test Jobs
Run test containers as Kubernetes Jobs when that execution model fits the platform.
Artifact collection
Collect logs, events and test reports when CI fails.
Controlled versions
Deploy immutable image tags or digests so the tested build is unambiguous.
Parallel environments
Spin up multiple isolated instances when infrastructure capacity and architecture support it.
Simple CI readiness gate
kubectl apply -f k8s/
kubectl rollout status \
deployment/my-app \
--timeout=180s
# Only start functional regression after Kubernetes says
# the required Deployment rollout has completed.
npm run test:e2e
Namespaces for environment isolation
Namespaces provide a scope for many Kubernetes resources and are useful for separating teams, environments or temporary test deployments.
kubectl create namespace qa-pr-184
kubectl apply -n qa-pr-184 -f k8s/
kubectl get all -n qa-pr-184
# Clean up afterwards
kubectl delete namespace qa-pr-184
Namespaces are useful boundaries, but they are not automatically complete security or network-isolation boundaries. RBAC, quotas and NetworkPolicies may also be needed depending on the environment.
Configuration and Secret test cases
Cloud-native defects are often configuration defects rather than application-code defects. Include configuration in your test design.
| Area | Example scenario |
|---|---|
| ConfigMap | Application starts with the expected environment-specific API URL. |
| Missing ConfigMap | Deployment fails clearly rather than silently using unsafe defaults. |
| Secret | Correct QA credentials are supplied without appearing in logs. |
| Secret rotation | Application recovers when credentials are rotated using the supported rollout strategy. |
| Wrong Service DNS | Dependency failure produces meaningful health and application errors. |
| Feature flags | Flag configuration maps to expected application behaviour in each environment. |
Kubernetes security basics for QA
A QA engineer is not necessarily responsible for cluster security, but test activity should respect the same security principles as production engineering.
- Use the minimum RBAC permissions needed for testing.
- Do not request cluster-admin access simply for convenience.
- Keep kubeconfig files and tokens protected.
- Never commit Secrets into repositories.
- Do not expose internal Services publicly just to make tests easier when port-forwarding or a controlled route would work.
- Use non-production credentials in QA environments.
- Consider whether test containers run as root or request unnecessary Linux capabilities.
- Check that security controls do not disappear in test environments, otherwise deployment defects may reach production untested.
Kubernetes commands cheat sheet
| Goal | Command |
|---|---|
| Current cluster context | kubectl config current-context |
| List namespaces | kubectl get namespaces |
| List Pods | kubectl get pods |
| List Pods by label | kubectl get pods -l app=my-app |
| Watch Pods | kubectl get pods -w |
| Describe Pod | kubectl describe pod <name> |
| Logs | kubectl logs <pod> |
| Previous crashed logs | kubectl logs <pod> --previous |
| Follow logs | kubectl logs -f <pod> |
| Run command in Pod | kubectl exec <pod> -- <command> |
| Interactive shell | kubectl exec -it <pod> -- /bin/sh |
| Temporary debug container | kubectl debug <pod> -it --image=busybox:1.36 |
| Apply manifests | kubectl apply -f k8s/ |
| Preview manifest differences | kubectl diff -f k8s/ |
| Delete manifests | kubectl delete -f k8s/ |
| Deployment rollout | kubectl rollout status deployment/my-app |
| Rollout history | kubectl rollout history deployment/my-app |
| Rollback | kubectl rollout undo deployment/my-app |
| Scale Deployment | kubectl scale deployment/my-app --replicas=4 |
| Local Service access | kubectl port-forward service/my-app 8080:80 |
| Recent events | kubectl get events --sort-by=.lastTimestamp |
Common beginner mistakes
| Mistake | Why it causes problems | Better approach |
|---|---|---|
| Testing against Pod IPs | Pod IPs are ephemeral. | Use Services or approved routes. |
| Creating bare Pods for the application | No Deployment manages replicas or rollouts. | Use a Deployment for stateless services. |
| Assuming Running means healthy | A Running Pod can still be unready or functionally broken. | Check Ready state, probes and application smoke tests. |
Using latest everywhere | The tested image can change without the manifest changing. | Use immutable version tags or digests. |
| Putting secrets in YAML committed to Git | Base64 does not protect secrets. | Use your organisation's secret-management flow. |
| Restarting Pods without finding the cause | The problem may disappear temporarily and return later. | Capture logs, previous logs, describe output and events first. |
| Increasing all timeouts | Masks readiness, performance or dependency problems. | Understand rollout and probe state before changing test waits. |
| Testing only steady state | Deployments fail during transition and recovery too. | Test rollout, scaling, restart and dependency failure. |
| Using old ReplicationController examples | Teaches a legacy workload model. | Learn Deployments and ReplicaSets first. |
| Treating namespaces as full isolation | Security/network rules may still allow cross-namespace access. | Add RBAC, quotas and NetworkPolicies according to risk. |
A practical Kubernetes QA checklist
- The active kubeconfig context and namespace are correct.
- The expected Deployment revision completed successfully.
- The running image tag or digest matches the build under test.
- The desired number of replicas are available and Ready.
- Readiness, liveness and startup probes represent meaningful health conditions.
- Services select the intended Pods.
- Service DNS and application dependency names resolve correctly.
- Environment-specific configuration comes from the intended ConfigMaps.
- Secrets use QA-specific values and are not visible in logs or source control.
- PersistentVolumeClaims required by the application are Bound.
- Resource requests and limits are realistic enough to expose resource-related defects.
- Smoke tests run before expensive regression suites.
- CI captures Pod status, describe output, events and logs when environment setup fails.
- Rolling deployment behaviour has been verified for important services.
- Rollback has been exercised for critical release paths.
- At least one controlled failure/recovery scenario exists for highly available services.
- Temporary test namespaces and resources are cleaned up.
- QA automation does not rely on specific Pod names or IP addresses.
- External access is created only through approved Service/Gateway/Ingress mechanisms.
- Application defects are distinguished from cluster/configuration defects in reporting.
Key takeaways
- Kubernetes manages desired application state across a cluster rather than simply running individual containers.
- The control plane manages scheduling and reconciliation; worker nodes run Pods.
- Pods are ephemeral and should normally be managed by higher-level workload resources.
- Deployments and ReplicaSets are the modern replacement for ReplicationController-centric application management.
- Services provide stable access to changing Pod replicas.
- ConfigMaps store non-secret configuration; Secrets require real security controls beyond base64 encoding.
- PVCs provide an abstraction for persistent storage consumption.
- Readiness, liveness and startup probes are central to safe traffic routing and recovery.
kubectlis one of the most valuable debugging tools a QA engineer can learn.- Cloud-native quality includes testing rollouts, configuration, resource limits and failure recovery, not only functional application behaviour.
Useful links
- Kubernetes Overview ↗ — current introduction to Kubernetes and its orchestration model.
- Kubernetes Components ↗ — control-plane and worker-node architecture.
- Workloads ↗ — Pods, Deployments, StatefulSets, DaemonSets and Jobs.
- Services ↗ — ClusterIP, NodePort, LoadBalancer, ExternalName and service discovery.
- Ingress ↗ — HTTP and HTTPS routing to cluster Services.
- Gateway API ↗ — newer Kubernetes networking APIs.
- ConfigMaps ↗ — non-confidential application configuration.
- Secrets ↗ — sensitive data and Kubernetes security guidance.
- Persistent Volumes ↗ — PVs, PVCs and storage abstraction.
- Liveness, Readiness and Startup Probes ↗ — configuring health checks.
- kubectl Quick Reference ↗ — common command-line operations.
- Minikube Get Started ↗ — run Kubernetes locally for learning and development.