kubectl and k9s essentials¶
Duration: 65 minutes (35 minutes theory + 30 minutes lab)
Learning Objectives¶
- Master essential kubectl commands
- Learn kubectl productivity tips and shortcuts
- Understand kubectl context and configuration
- Use k9s for visual cluster management
- Debug and troubleshoot common issues
- Efficiently navigate and inspect cluster resources
kubectl Basics¶
kubectl is the primary CLI tool for interacting with Kubernetes clusters.
Command Structure¶
Examples:
Essential Commands¶
| Command | Purpose | Example |
|---|---|---|
get |
List resources | kubectl get pods |
describe |
Show detailed info | kubectl describe pod nginx |
create |
Create resource | kubectl create deployment nginx --image=nginx |
apply |
Apply configuration | kubectl apply -f app.yaml |
delete |
Delete resources | kubectl delete pod nginx |
logs |
View logs | kubectl logs nginx -f |
exec |
Execute command | kubectl exec -it nginx -- bash |
port-forward |
Forward ports | kubectl port-forward pod/nginx 8080:80 |
edit |
Edit resource | kubectl edit deployment nginx |
scale |
Scale replicas | kubectl scale deployment nginx --replicas=3 |
kubectl get - List Resources¶
# List pods
kubectl get pods
kubectl get pods -o wide # More details (node, IP)
kubectl get pods -o yaml # Full YAML output
kubectl get pods -o json # JSON output
kubectl get pods -o name # Just names
# List all resource types
kubectl get all
# List across all namespaces
kubectl get pods --all-namespaces
kubectl get pods -A # Short form
# Filter by labels
kubectl get pods -l app=nginx
kubectl get pods -l 'app=nginx,env=prod'
kubectl get pods -l 'env!=dev'
# Watch for changes
kubectl get pods -w
kubectl get pods --watch
# Sort by field
kubectl get pods --sort-by=.metadata.creationTimestamp
kubectl get pods --sort-by=.status.startTime
# Custom columns
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName
kubectl describe - Detailed Information¶
# Describe pod (shows events!)
kubectl describe pod nginx
# Describe multiple resources
kubectl describe pods -l app=nginx
# Describe node
kubectl describe node kind-worker
# Describe service
kubectl describe service nginx
Key information shown:
- Configuration details
- Status and conditions
- Events (creations, errors, scheduling)
- Resource usage
- Volume mounts
kubectl logs - View Logs¶
# View pod logs
kubectl logs nginx
# Follow logs (like tail -f)
kubectl logs -f nginx
# Logs from previous container instance
kubectl logs nginx --previous
# Logs from specific container in multi-container pod
kubectl logs nginx -c sidecar
# Last N lines
kubectl logs nginx --tail=50
# Logs since timestamp
kubectl logs nginx --since=1h
kubectl logs nginx --since-time=2024-01-01T00:00:00Z
# All pods matching label
kubectl logs -l app=nginx --all-containers=true
# Combine with grep
kubectl logs nginx | grep ERROR
kubectl exec - Execute Commands¶
# Interactive shell
kubectl exec -it nginx -- /bin/sh
kubectl exec -it nginx -- /bin/bash
# Run single command
kubectl exec nginx -- ls /etc
kubectl exec nginx -- cat /etc/nginx/nginx.conf
# Specific container in multi-container pod
kubectl exec -it nginx -c sidecar -- sh
# Run command in all pods
kubectl get pods -l app=nginx -o name | \
xargs -I {} kubectl exec {} -- date
kubectl apply vs create¶
# create: Create new resource (fails if exists)
kubectl create -f app.yaml
# apply: Create or update resource (idempotent)
kubectl apply -f app.yaml
# apply is declarative and tracks changes
kubectl apply -f app.yaml --dry-run=client # Preview
kubectl apply -f app.yaml --dry-run=server # Validate with server
# Apply directory of manifests
kubectl apply -f ./manifests/
# Apply with kustomize
kubectl apply -k ./overlays/production/
kubectl port-forward - Access Services Locally¶
# Forward pod port to localhost
kubectl port-forward pod/nginx 8080:80
# Forward service port
kubectl port-forward service/nginx 8080:80
# Forward deployment port
kubectl port-forward deployment/nginx 8080:80
# Bind to specific address
kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80
# Multiple ports
kubectl port-forward pod/nginx 8080:80 8443:443
Access at: http://localhost:8080
kubectl Context and Configuration¶
# View current context
kubectl config current-context
# List all contexts
kubectl config get-contexts
# Switch context
kubectl config use-context kind-kind
# View full config
kubectl config view
# Set default namespace for context
kubectl config set-context --current --namespace=development
# Create new context
kubectl config set-context dev --cluster=kind-kind --user=kind-kind --namespace=development
kubectl Shortcuts and Aliases¶
# Enable kubectl autocompletion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
# Alias k=kubectl
alias k=kubectl
complete -F __start_kubectl k
# Common aliases
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kgd='kubectl get deployments'
alias kd='kubectl describe'
alias kl='kubectl logs'
alias ke='kubectl exec -it'
alias kaf='kubectl apply -f'
alias kdel='kubectl delete'
kubectl Productivity Tips¶
1. Resource Type Shortcuts¶
# Full name Short name
pods -> po
services -> svc
deployments -> deploy
replicasets -> rs
namespaces -> ns
nodes -> no
persistentvolumeclaims -> pvc
configmaps -> cm
secrets -> secret
Example:
2. Watch Mode¶
# Watch resources update in real-time
kubectl get pods -w
# Watch with timestamp
watch kubectl get pods
3. JSONPath Queries¶
# Extract specific fields
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
# Get pod IPs
kubectl get pods -o jsonpath='{.items[*].status.podIP}'
# Complex queries
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
# Get resource limits
kubectl get pod nginx -o jsonpath='{.spec.containers[*].resources}'
4. Dry Run¶
# Generate YAML without creating
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml
# Validate manifest
kubectl apply -f app.yaml --dry-run=server
# Generate manifest and apply
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml | kubectl apply -f -
5. Explain Resources¶
# View resource documentation
kubectl explain pod
kubectl explain pod.spec
kubectl explain pod.spec.containers
kubectl explain deployment.spec.strategy
# Show all fields
kubectl explain deployment --recursive
k9s - Terminal UI for Kubernetes¶
k9s provides a terminal-based UI for managing and monitoring Kubernetes clusters.
Launch k9s¶
k9s
# Specific namespace
k9s -n development
# Read-only mode
k9s --readonly
# Different context
k9s --context kind-kind
k9s Navigation¶
| Key | Action |
|---|---|
:pods or :po |
View pods |
:svc |
View services |
:deploy |
View deployments |
:ns |
View namespaces |
0 |
Show all namespaces |
1-9 |
Switch namespace |
/ |
Filter resources |
esc |
Clear filter/back |
? |
Help |
:q or Ctrl+C |
Quit |
k9s Pod Operations¶
When viewing pods:
| Key | Action |
|---|---|
enter |
View pod details |
l |
View pod logs |
s |
Shell into pod |
d |
Describe pod |
e |
Edit pod |
y |
View YAML |
ctrl+k |
Delete pod |
p |
Previous logs |
f |
Port forward |
k9s Log Viewing¶
While viewing logs:
| Key | Action |
|---|---|
f |
Toggle follow mode |
t |
Toggle timestamp |
w |
Toggle wrap |
s |
Save logs to file |
/ |
Search in logs |
n/N |
Next/previous match |
c |
Clear logs |
k9s Pulses (Live View)¶
k9s shows live metrics:
- CPU and memory usage (if metrics-server installed)
- Pod status changes
- Events in real-time
k9s Skins and Themes¶
k9s Configuration¶
Config file: ~/.k9s/config.yml
k9s:
refreshRate: 2
maxConnRetry: 5
readOnly: false
noExitOnCtrlC: false
ui:
enableMouse: false
headless: false
logoless: false
crumbsless: false
skin: dracula
skipLatestRevCheck: false
logger:
sinceSeconds: 300
Troubleshooting Common Issues¶
Pod Not Starting¶
# Check pod status
kubectl get pods
# Describe for events
kubectl describe pod <pod-name>
# Check logs
kubectl logs <pod-name>
kubectl logs <pod-name> --previous # Previous container
# Common issues:
# - ImagePullBackOff: Wrong image name, no credentials
# - CrashLoopBackOff: Application crashes on startup
# - Pending: Insufficient resources, PVC not bound
# - CreateContainerConfigError: ConfigMap/Secret missing
Service Not Accessible¶
# Verify service exists
kubectl get svc
# Check endpoints (pod IPs)
kubectl get endpoints <service-name>
# Verify labels match
kubectl get pods --show-labels
kubectl describe service <service-name> # Check selector
# Test from another pod
kubectl run test --image=busybox --rm -it -- wget -O- http://<service>
# Check service type
kubectl get svc <service-name> -o jsonpath='{.spec.type}'
Debugging Network Issues¶
# DNS resolution
kubectl run test --image=busybox --rm -it -- nslookup kubernetes.default
# Connectivity test
kubectl run test --image=nicolaka/netshoot --rm -it -- bash
# Then: ping, curl, dig, traceroute, etc.
# Check CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
Resource Constraints¶
# Check node resources
kubectl top nodes
kubectl describe node <node-name>
# Check pod resources
kubectl top pods
kubectl top pods --containers
# Check resource quotas
kubectl describe resourcequota -n <namespace>
# Check limit ranges
kubectl describe limitrange -n <namespace>
Deployment Rollout Issues¶
# Check rollout status
kubectl rollout status deployment/<name>
# View rollout history
kubectl rollout history deployment/<name>
# View specific revision
kubectl rollout history deployment/<name> --revision=2
# Rollback
kubectl rollout undo deployment/<name>
kubectl rollout undo deployment/<name> --to-revision=2
# Pause/resume rollout
kubectl rollout pause deployment/<name>
kubectl rollout resume deployment/<name>
kubectl Debug Commands¶
# Debug pod (creates ephemeral container)
kubectl debug pod/nginx -it --image=busybox
# Debug node (creates privileged pod on node)
kubectl debug node/kind-worker -it --image=ubuntu
# Copy pod for debugging
kubectl debug pod/nginx --copy-to=nginx-debug --container=nginx -- sh
# Attach to running container
kubectl attach nginx -it
Best Practices¶
- Use namespaces: Organize resources logically
- Label everything: Makes filtering and selection easier
- Use
describe: First stop for troubleshooting - Check events: Often reveals the root cause
- Use
--dry-run: Preview changes before applying - Use contexts: Switch between clusters easily
- Enable completion: Save typing and prevent errors
- Learn JSONPath: Extract exactly what you need
- Use k9s: Faster for exploration and monitoring
- Keep cheatsheets handy: Reference common commands
Quick Reference¶
See the kubectl Cheatsheet and k9s Shortcuts for complete references.
Key takeaways¶
- kubectl is your primary interface to Kubernetes
describeandlogsare essential for troubleshooting- k9s provides a faster, more visual way to manage clusters
- Labels and selectors make resource management easier
- Contexts let you work with multiple clusters
- Dry-run and explain help understand and validate configurations
Check your understanding¶
- What's the difference between
kubectl createandkubectl apply? - How do you view logs from a previous container instance?
- What's the purpose of
kubectl describevskubectl get? - How do you access a ClusterIP service from your local machine?
- What are the advantages of using k9s over kubectl?
Solution
createfails if the resource already exists;applycreates or updates and is idempotentkubectl logs <pod> --previousgetgives a brief overview;describegives full details, conditions, and crucially the Events section for debugging- Use
kubectl port-forward service/<name> <local-port>:<service-port> - k9s is faster for browsing resources, real-time log tailing, and navigating multiple resource types without typing commands
Hands-on¶
Apply the concepts from this section in the lab exercises.
Next section¶
Once you've reviewed the content and completed the lab, proceed to the next section