| | |

LFCA 80 🐧 Basic kubectl Commands

The previous chapter covered the Kubernetes architecture. This chapter covers the tool you use to interact with that architecture: kubectl. It is the command-line interface for Kubernetes, and every action on the cluster goes through it . You use it to deploy applications, inspect resources, view logs, debug problems, and manage the cluster itself.

The LFCA exam places containers and deployment environments under DevOps Fundamentals, which carries 16% of the total weight . While LFCA focuses on foundational concepts, kubectl is the practical interface for the container orchestration topics the exam covers. The Kubernetes and Cloud Native Associate (KCNA) certification, often paired with LFCA, explicitly requires the ability to deploy an application using basic kubectl commands .

Key point: Every kubectl command follows the same structure: kubectl [command] [TYPE] [NAME] [flags] . The command is the action, the TYPE is the resource type (pod, deployment, service), the NAME is the resource name, and the flags are additional options. This consistent syntax is what makes kubectl learnable once you understand the pattern.


Why kubectl matters

Kubernetes is a distributed system with an API server at its center. Every component — the scheduler, the controller manager, the kubelet on each node — communicates with the API server. kubectl is the tool that lets you do the same. It translates your commands into REST API calls to the cluster .

The declarative problem. Kubernetes is a declarative system. You describe the desired state, and Kubernetes makes it happen. kubectl provides two ways to do this. The imperative approach creates resources directly from the command line. The declarative approach applies YAML manifests that describe the desired state. The declarative approach is preferred in production because it allows versioning, review, and rollback .

The inspection problem. A Pod is not starting. The reason could be a scheduling failure, an image pull error, a missing ConfigMap, or a crashed container. kubectl describe shows the events and conditions that explain what happened. kubectl logs shows the application’s output. kubectl exec lets you run commands inside the container. Each command answers a different question .

The lifecycle problem. A Deployment needs to be updated, scaled, or rolled back. kubectl set image updates the container image. kubectl scale changes the replica count. kubectl rollout undo reverts to a previous version. These commands manage the application through its lifecycle .

The trade-off. kubectl is a command-line tool. It has no graphical interface. The learning curve is real: the resource types, the flag combinations, and the output formats take time to internalize. But the payoff is automation. Every kubectl command can be scripted, integrated into CI/CD pipelines, and combined with other Unix tools. This is why it remains the standard interface despite the availability of dashboards and GUIs.


a. Viewing Resources: get, describe, and logs

The get command retrieves information about resources. It is the most frequently used kubectl command . The basic form is kubectl get [TYPE]. It returns a tabular summary of the requested resources.

# List all Pods in the current namespace
kubectl get pods

# List all Pods across all namespaces
kubectl get pods --all-namespaces

# List Pods with additional details (including node name)
kubectl get pods -o wide

# Get a specific Pod as YAML
kubectl get pod my-pod -o yaml

The -o wide flag adds the node name and IP address to the output. The -o yaml and -o json flags change the output format entirely, which is useful for extracting specific fields or piping to other tools .

The describe command provides detailed information about a resource. Unlike get, which shows a summary, describe makes multiple API calls to build a comprehensive view. For a Pod, it shows the node, the container statuses, the conditions, the volumes, and the events .

# Detailed information about a Pod
kubectl describe pod my-pod

# Detailed information about a node
kubectl describe node worker-01

The events section at the bottom of the describe output is often the most valuable part for debugging. It shows what the scheduler, the kubelet, and the controllers have done with the resource, including any errors.

The logs command retrieves the output from a container. It is equivalent to running docker logs on a container, but it works for any Pod in the cluster .

# View logs from a Pod
kubectl logs my-pod

# Follow the logs in real time
kubectl logs -f my-pod

# View logs from a specific container in a multi-container Pod
kubectl logs my-pod -c sidecar

# View logs from the previous instance (if the container restarted)
kubectl logs my-pod --previous

The --previous flag is particularly useful when a container is in CrashLoopBackOff. The current container may not have produced any logs yet, but the previous instance’s logs explain why it crashed.


b. Creating and Managing Resources: run, create, apply, and delete

The run command creates a Pod imperatively. It is the fastest way to start a single container, and it is useful for testing and debugging .

# Create a Pod running nginx
kubectl run nginx --image=nginx:1.25

# Create an interactive shell Pod
kubectl run -it --rm busybox --image=busybox:1.28 -- sh

# Generate YAML without creating the resource
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml

The --dry-run=client flag combined with -o yaml is a common pattern for generating manifest files. It produces the YAML that would create the resource without actually creating it .

The create command creates specific resource types from the command line. It is more structured than run and covers resources like namespaces, secrets, and configmaps .

# Create a namespace
kubectl create namespace production

# Create a secret from literal values
kubectl create secret generic db-credentials --from-literal=password=secret

# Create a configmap from a file
kubectl create configmap app-config --from-file=config.properties

The apply command is the declarative approach. It reads a YAML manifest and creates or updates the described resources. The apply command is idempotent: running it multiple times produces the same result .

# Apply a manifest file
kubectl apply -f deployment.yaml

# Apply all manifests in a directory
kubectl apply -f ./manifests/

# Apply from a URL
kubectl apply -f https://example.com/manifest.yaml

The apply command is preferred in production because the manifest file is the source of truth. The file can be version-controlled, reviewed, and reused. The imperative commands are faster for quick tasks but leave no record of what was done .

The delete command removes resources. It can delete by name, by label, or from a file.

# Delete a Pod by name
kubectl delete pod my-pod

# Delete all Pods with a specific label
kubectl delete pods -l app=my-app

# Delete all Pods and Services in a namespace
kubectl delete pods,services --all -n my-namespace

# Delete from a manifest file
kubectl delete -f deployment.yaml

The delete command is immediate for most resources. Pods are terminated gracefully, but Deployments and other controllers may recreate Pods if the desired replica count is not changed .


c. Debugging and Interacting: exec, port-forward, and cp

The exec command runs a command inside a running container. It is the primary tool for interactive debugging .

# Run a single command in a Pod
kubectl exec my-pod -- ls /app

# Open an interactive shell
kubectl exec -it my-pod -- /bin/bash

# Run in a specific container of a multi-container Pod
kubectl exec -it my-pod -c sidecar -- /bin/sh

The -- separates the kubectl arguments from the command to run in the container. The -it flags allocate an interactive terminal, which is required for a shell session .

The port-forward command creates a tunnel from your local machine to a Pod or Service. It is used to access a service that is not exposed externally, such as a database or an admin interface .

# Forward local port 8080 to port 80 on a Pod
kubectl port-forward my-pod 8080:80

# Forward to a Service
kubectl port-forward service/my-service 5432:5432

The tunnel is active as long as the port-forward command is running. It is useful for development and debugging but is not intended for production traffic.

The cp command copies files and directories between your local machine and a container. It works like the Unix cp command but with the Pod name and path as the remote endpoint .

# Copy a local file to a Pod
kubectl cp ./config.yaml my-pod:/app/config.yaml

# Copy a file from a Pod to the local machine
kubectl cp my-pod:/app/logs/error.log ./error.log

The cp command requires that the container has the tar binary available, because it uses tar to stream the files .


Complete Example Session

This session walks through deploying an application, inspecting it, debugging it, and cleaning up.

# ============================================
# PART 1: DEPLOY AN APPLICATION
# ============================================

# Create a deployment imperatively
kubectl create deployment web --image=nginx:1.25 --replicas=3

# Verify the deployment
kubectl get deployments

# Output:
# NAME   READY   UP-TO-DATE   AVAILABLE   AGE
# web    3/3     3            3           10s

# ============================================
# PART 2: VIEW THE PODS
# ============================================

kubectl get pods

# Output:
# NAME                   READY   STATUS    RESTARTS   AGE
# web-7d9f8b6c5-2x4kz    1/1     Running   0          15s
# web-7d9f8b6c5-8m3np    1/1     Running   0          15s
# web-7d9f8b6c5-q7r5t    1/1     Running   0          15s

# View with node information
kubectl get pods -o wide

# ============================================
# PART 3: DESCRIBE A POD
# ============================================

kubectl describe pod web-7d9f8b6c5-2x4kz

# The output shows:
# - Node assignment
# - Container status
# - Conditions
# - Events (most useful for debugging)

# ============================================
# PART 4: VIEW LOGS
# ============================================

kubectl logs web-7d9f8b6c5-2x4kz

# Output: the nginx access log entries

# ============================================
# PART 5: EXECUTE A COMMAND
# ============================================

kubectl exec -it web-7d9f8b6c5-2x4kz -- /bin/bash

# Inside the container:
ls /usr/share/nginx/html/
# index.html
exit

# ============================================
# PART 6: EXPOSE THE DEPLOYMENT
# ============================================

kubectl expose deployment web --port=80 --type=ClusterIP

# Verify the service
kubectl get services

# Output:
# NAME         TYPE        CLUSTER-IP      PORT(S)
# web          ClusterIP   10.96.123.45    80/TCP

# ============================================
# PART 7: PORT FORWARD
# ============================================

kubectl port-forward service/web 8080:80

# In another terminal:
curl http://localhost:8080
# The nginx welcome page HTML

# ============================================
# PART 8: SCALE THE DEPLOYMENT
# ============================================

kubectl scale deployment web --replicas=5

kubectl get pods

# Output shows five Pods running.

# ============================================
# PART 9: UPDATE THE IMAGE
# ============================================

kubectl set image deployment/web web=nginx:1.26

# Watch the rollout
kubectl rollout status deployment/web

# Output:
# Waiting for deployment "web" rollout to finish...
# deployment "web" successfully rolled out

# ============================================
# PART 10: CLEAN UP
# ============================================

kubectl delete deployment web
kubectl delete service web

# Or delete both at once
kubectl delete deployment/web service/web

The ten parts cover deploying an application, viewing Pods, describing a Pod, viewing logs, executing commands, exposing the deployment, port forwarding, scaling, updating the image, and cleaning up.


Quick Reference

The Essential Commands

CommandPurposeExample
getList resourceskubectl get pods
describeDetailed informationkubectl describe pod my-pod
logsContainer outputkubectl logs my-pod
execRun command in containerkubectl exec -it my-pod -- sh
applyApply manifestkubectl apply -f file.yaml
deleteRemove resourceskubectl delete pod my-pod
scaleChange replicaskubectl scale deploy web --replicas=5
exposeCreate a Servicekubectl expose deploy web --port=80
port-forwardTunnel to a Podkubectl port-forward pod/my-pod 8080:80
cpCopy fileskubectl cp my-pod:/path ./local

The Resource Shortcuts

ShortcutFull Resource
popods
deploydeployments
svcservices
nsnamespaces
cmconfigmaps
nonodes
rsreplicasets

The Output Formats

FlagFormat
-o wideExtended plain text
-o yamlYAML
-o jsonJSON
-o nameResource names only
-o jsonpathCustom field extraction

The Useful Flags

FlagPurpose
-nNamespace
-A / --all-namespacesAll namespaces
-lLabel selector
-fFile or directory
--dry-run=clientPreview without creating
-itInteractive terminal

Best Practices

✅ Do This:

# Use declarative apply for production
kubectl apply -f deployment.yaml                              # ✅
# Use describe to debug scheduling and startup issues
kubectl describe pod my-pod                                   # ✅
# Use logs --previous for crashed containers
kubectl logs my-pod --previous                                # ✅
# Generate YAML with dry-run for reference
kubectl run nginx --image=nginx --dry-run=client -o yaml      # ✅
# Use resource shortcuts for speed
kubectl get po                                                # ✅

❌ Don’t Do This:

# Don't use imperative commands in production pipelines
kubectl run nginx --image=nginx                               # ❌ no record
# Don't forget -- to separate kubectl args from container command
kubectl exec my-pod ls /app  # may fail                       # ❌ use --
# Don't use port-forward for production traffic
kubectl port-forward my-pod 8080:80                           # ❌ not for prod
# Don't delete resources without checking dependencies
kubectl delete namespace production                           # ❌ deletes everything

Common Pitfalls

PitfallWhy It HappensFix
“Connection refused”No cluster configuredCheck kubectl config current-context
Pod not foundWrong namespaceUse -n or -A
Exec fails-- missingUse kubectl exec pod -- command
Logs emptyContainer just started or crashedUse --previous
Apply failsInvalid YAMLCheck kubectl apply --dry-run=client
Delete hangsFinalizersCheck kubectl describe

Real-World Examples

1. List All Resources

kubectl get all

2. Watch Pods

kubectl get pods -w

3. Describe a Node

kubectl describe node worker-01

4. Create from Manifest

kubectl apply -f ./manifests/

5. Delete by Label

kubectl delete pods -l app=web

6. Scale a Deployment

kubectl scale deploy web --replicas=5

7. Rollback a Deployment

kubectl rollout undo deploy/web

8. Copy a File

kubectl cp my-pod:/app/config.yaml ./config.yaml

9. Port Forward to a Database

kubectl port-forward svc/postgres 5432:5432

10. Interactive Shell

kubectl exec -it my-pod -- /bin/bash

Visual

The kubectl Command Structure

┌──────────────────────────────────────────────┐
│  kubectl [command] [TYPE] [NAME] [flags]     │
│                                              │
│  command: get, describe, apply, delete, etc. │
│  TYPE:    pods, deployments, services, etc.  │
│  NAME:    my-pod, web, etc.                  │
│  flags:   -n, -o, -l, -f, etc.               │
│                                              │
│  Example:                                    │
│  kubectl get pods my-pod -n production -o wide│
│         │     │     │         │          │   │
│         │     │     │         │          └─ extended output│
│         │     │     │         └─ namespace                   │
│         │     │     └─ resource name                         │
│         │     └─ resource type                               │
│         └─ action                                            │
│                                              │
└──────────────────────────────────────────────┘

The Debugging Flow

┌──────────────────────────────────────────────┐
│  POD NOT RUNNING                             │
│       │                                      │
│       ▼                                      │
│  kubectl get pods                            │
│    └─ Check STATUS column                    │
│       │                                      │
│       ├─ Pending → kubectl describe pod      │
│       │              └─ Check Events         │
│       │                                      │
│       ├─ CrashLoopBackOff → kubectl logs     │
│       │                      --previous      │
│       │                                      │
│       ├─ ImagePullBackOff → kubectl describe │
│       │                      └─ Check image  │
│       │                                      │
│       └─ Running but not working →           │
│            kubectl logs                      │
│            kubectl exec                      │
│                                              │
└──────────────────────────────────────────────┘

The Resource Lifecycle Commands

┌──────────────────────────────────────────────┐
│  CREATE                                      │
│    kubectl run (imperative)                  │
│    kubectl create (structured)               │
│    kubectl apply (declarative)               │
│       │                                      │
│       ▼                                      │
│  INSPECT                                     │
│    kubectl get                               │
│    kubectl describe                          │
│    kubectl logs                              │
│       │                                      │
│       ▼                                      │
│  MODIFY                                      │
│    kubectl scale                             │
│    kubectl set image                         │
│    kubectl edit                              │
│       │                                      │
│       ▼                                      │
│  DELETE                                      │
│    kubectl delete                            │
│                                              │
└──────────────────────────────────────────────┘

The Output Format Options

┌──────────────────────────────────────────────┐
│  kubectl get pods                            │
│    └─ Default: human-readable table          │
│                                              │
│  kubectl get pods -o wide                    │
│    └─ Adds node name, IP                     │
│                                              │
│  kubectl get pod my-pod -o yaml              │
│    └─ Full YAML manifest                     │
│                                              │
│  kubectl get pods -o jsonpath='{.items[*].metadata.name}'│
│    └─ Custom field extraction                │
│                                              │
│  kubectl get pods --show-labels              │
│    └─ Adds labels column                     │
│                                              │
└──────────────────────────────────────────────┘

Summary

ItemValue
kubectl definitionCommand-line interface for Kubernetes
Command structurekubectl [command] [TYPE] [NAME] [flags]
GetList resources
DescribeDetailed resource information
LogsContainer output
ExecRun command in container
ApplyDeclarative resource management
DeleteRemove resources
ScaleChange replica count
Port-forwardTunnel to a Pod
Resource shortcutspo, deploy, svc, ns
LFCA weightDevOps Fundamentals, 16%

Key takeaways:

  • kubectl is the single entry point to the Kubernetes API. Every action on the cluster goes through it. The command structure is consistent: kubectl [command] [TYPE] [NAME] [flags] .
  • get, describe, and logs are the inspection commands. get shows a summary. describe shows detailed information including events. logs shows the container’s output. Together they answer most debugging questions .
  • apply is the declarative command; run and create are imperative. The declarative approach uses YAML manifests that can be version-controlled and reviewed. The imperative approach is faster for quick tasks but leaves no record .
  • exec runs commands inside a running container. The -- separates kubectl arguments from the container command. The -it flags allocate an interactive terminal for shell sessions .
  • port-forward creates a tunnel to a Pod or Service. It is useful for development and debugging but is not intended for production traffic .
  • Resource shortcuts save typing. po for pods, deploy for deployments, svc for services, ns for namespaces. These are the most common shortcuts and are worth memorizing .
  • The --dry-run=client -o yaml pattern generates manifests. It produces the YAML that would create the resource without actually creating it. This is useful for learning the manifest format and for generating templates .

Remember: kubectl is the tool that makes Kubernetes accessible. The architecture is abstract until you run kubectl get pods and see the Pods your Deployment created. The lifecycle is abstract until you run kubectl logs and see the application’s output. The reconciliation loop is abstract until you run kubectl delete pod and watch a new one appear. Every command is a window into the cluster. The syntax is consistent. The resource types are finite. The debugging flow is a sequence: get, describe, logs, exec. Learn the pattern, and the cluster becomes manageable.


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!