Basic Kubernetes Usage
Learn the fundamentals of Kubernetes and how to deploy and manage containerized applications effectively.
Overview
Kubernetes (K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. This guide covers the essential concepts and commands to get you started with Kubernetes.
What is Kubernetes?
Kubernetes provides:
🚀 Container Orchestration
- Automatic deployment and scaling of containerized applications
- Load balancing and service discovery
- Self-healing and automated rollouts/rollbacks
📦 Resource Management
- Efficient resource allocation and utilization
- Declarative configuration management
- Storage orchestration
🔧 Production-Ready Features
- Secret and configuration management
- Horizontal scaling
- Rolling updates with zero downtime
- Health checks and monitoring
Prerequisites
Before you begin, ensure you have:
- kubectl - Kubernetes command-line tool
- A Kubernetes cluster (local or cloud-based)
- Basic understanding of containers and Docker
- Terminal/command line access
Installation
Install kubectl
macOS:
brew install kubectl
Linux:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
Windows:
choco install kubernetes-cli
Verify installation:
kubectl version --client
Set Up a Local Cluster
For learning and development, you can use:
Minikube (Recommended for beginners):
# Install minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Start cluster
minikube start
Kind (Kubernetes in Docker):
# Install kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# Create cluster
kind create cluster
Docker Desktop (Windows/macOS):
- Enable Kubernetes in Docker Desktop settings
Verify cluster is running:
kubectl cluster-info
kubectl get nodes
Core Concepts
Pods
A Pod is the smallest deployable unit in Kubernetes, representing one or more containers.
Deployments
Deployments manage the desired state of your application, handling scaling and updates.
Services
Services provide stable networking endpoints to access your Pods.
Namespaces
Namespaces provide logical isolation for resources within a cluster.
Basic kubectl Commands
Cluster Information
# Get cluster info
kubectl cluster-info
# View nodes in the cluster
kubectl get nodes
# Get detailed node information
kubectl describe nodes
Working with Namespaces
# List all namespaces
kubectl get namespaces
# Create a namespace
kubectl create namespace my-app
# Set default namespace
kubectl config set-context --current --namespace=my-app
# Delete a namespace
kubectl delete namespace my-app
Managing Resources
# Get all resources in current namespace
kubectl get all
# Get specific resources
kubectl get pods
kubectl get deployments
kubectl get services
# Get resources from all namespaces
kubectl get pods --all-namespaces
# Get resources with more details
kubectl get pods -o wide
# Watch resources in real-time
kubectl get pods --watch
Creating Your First Pod
Simple Pod Definition
Create a file called nginx-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Deploy the Pod:
# Create the Pod
kubectl apply -f nginx-pod.yaml
# Check Pod status
kubectl get pods
# View Pod details
kubectl describe pod nginx-pod
# View Pod logs
kubectl logs nginx-pod
# Execute command in Pod
kubectl exec -it nginx-pod -- /bin/bash
Multi-Container Pod
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80
- name: sidecar
image: busybox:latest
command: ['sh', '-c', 'while true; do echo "Sidecar running"; sleep 10; done']
Working with Deployments
Deployments provide declarative updates for Pods and ReplicaSets.
Creating a Deployment
Create nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Deploy and manage:
# Create deployment
kubectl apply -f nginx-deployment.yaml
# Get deployments
kubectl get deployments
# Scale deployment
kubectl scale deployment nginx-deployment --replicas=5
# Update image
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
# Check rollout status
kubectl rollout status deployment/nginx-deployment
# View rollout history
kubectl rollout history deployment/nginx-deployment
# Rollback to previous version
kubectl rollout undo deployment/nginx-deployment
Deployment Strategies
Rolling Update (default):
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
Recreate:
spec:
strategy:
type: Recreate
Exposing Applications with Services
ClusterIP Service (Internal)
Create service-clusterip.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
NodePort Service (External Access)
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
LoadBalancer Service (Cloud)
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
Manage services:
# Create service
kubectl apply -f service-clusterip.yaml
# Get services
kubectl get services
# Describe service
kubectl describe service nginx-service
# Get service endpoints
kubectl get endpoints nginx-service
# Delete service
kubectl delete service nginx-service
ConfigMaps and Secrets
ConfigMaps
Store configuration data as key-value pairs:
# Create ConfigMap from literal values
kubectl create configmap app-config \
--from-literal=database_url=postgres://localhost:5432/mydb \
--from-literal=log_level=info
# Create from file
kubectl create configmap app-config --from-file=config.properties
Use in Pod:
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database_url
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
Secrets
Store sensitive data:
# Create secret from literal
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=secretpass
# Create from file
kubectl create secret generic tls-cert --from-file=tls.crt --from-file=tls.key
Use in Pod:
apiVersion: v1
kind: Pod
metadata:
name: app-with-secret
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Resource Management
Resource Requests and Limits
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Namespace Resource Quotas
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: my-app
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "10"
Health Checks
Liveness Probe
Checks if container is running:
apiVersion: v1
kind: Pod
metadata:
name: liveness-demo
spec:
containers:
- name: app
image: myapp:latest
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
Readiness Probe
Checks if container is ready to serve traffic:
apiVersion: v1
kind: Pod
metadata:
name: readiness-demo
spec:
containers:
- name: app
image: myapp:latest
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Labels and Selectors
Using Labels
apiVersion: v1
kind: Pod
metadata:
name: labeled-pod
labels:
environment: production
tier: frontend
version: v1.0.0
spec:
containers:
- name: nginx
image: nginx:latest
Selecting Resources
# Get pods with specific label
kubectl get pods -l environment=production
# Multiple labels
kubectl get pods -l environment=production,tier=frontend
# Label-based operations
kubectl delete pods -l version=v1.0.0
Debugging and Troubleshooting
Pod Troubleshooting
# Get pod status
kubectl get pods
# Describe pod for events
kubectl describe pod <pod-name>
# View logs
kubectl logs <pod-name>
# Previous container logs
kubectl logs <pod-name> --previous
# Logs from specific container
kubectl logs <pod-name> -c <container-name>
# Follow logs
kubectl logs -f <pod-name>
# Execute commands in pod
kubectl exec -it <pod-name> -- /bin/bash
# Copy files to/from pod
kubectl cp <pod-name>:/path/to/file ./local-file
kubectl cp ./local-file <pod-name>:/path/to/file
Common Issues
ImagePullBackOff:
# Check image name and registry access
kubectl describe pod <pod-name>
# Verify image exists
docker pull <image-name>
CrashLoopBackOff:
# Check logs for errors
kubectl logs <pod-name>
# Check previous container logs
kubectl logs <pod-name> --previous
# Verify resource limits
kubectl describe pod <pod-name>
Pending State:
# Check events
kubectl describe pod <pod-name>
# Verify node resources
kubectl describe nodes
# Check pod requirements
kubectl get pod <pod-name> -o yaml
Useful Commands Cheat Sheet
Quick Reference
# Get resources
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get nodes
# Describe resources
kubectl describe pod <pod-name>
kubectl describe service <service-name>
# Delete resources
kubectl delete pod <pod-name>
kubectl delete deployment <deployment-name>
kubectl delete -f manifest.yaml
# Edit resources
kubectl edit deployment <deployment-name>
# Apply configuration
kubectl apply -f manifest.yaml
# Dry run
kubectl apply -f manifest.yaml --dry-run=client
# Generate YAML
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml
# Port forwarding
kubectl port-forward pod/<pod-name> 8080:80
# Top resources
kubectl top nodes
kubectl top pods
Best Practices
1. Use Namespaces for Organization
Organize resources by environment or team:
kubectl create namespace production
kubectl create namespace staging
kubectl create namespace development
2. Always Define Resource Limits
Prevent resource exhaustion:
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
3. Use Labels Consistently
Label resources for easy management:
metadata:
labels:
app: myapp
environment: production
version: v1.0.0
4. Implement Health Checks
Always define liveness and readiness probes:
livenessProbe:
httpGet:
path: /health
port: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
5. Use Declarative Configuration
Manage resources with YAML files in version control:
kubectl apply -f deployment.yaml
6. Never Use latest Tag
Always use specific image tags:
# Bad
image: nginx:latest
# Good
image: nginx:1.25.3
Complete Example: Deploying a Web Application
Here's a complete example deploying a simple web application with all components:
Deployment
Create webapp-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
labels:
app: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.25.3
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: config
configMap:
name: webapp-config
Service
Create webapp-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: LoadBalancer
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
ConfigMap
Create webapp-configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
default.conf: |
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
Deploy Everything
# Create namespace
kubectl create namespace webapp
# Apply configurations
kubectl apply -f webapp-configmap.yaml -n webapp
kubectl apply -f webapp-deployment.yaml -n webapp
kubectl apply -f webapp-service.yaml -n webapp
# Verify deployment
kubectl get all -n webapp
# Check service
kubectl get service webapp-service -n webapp
# Access application
minikube service webapp-service -n webapp # For minikube
Next Steps
Now that you understand basic Kubernetes usage, explore:
- Image as Volumes - Advanced volume management features
- Helm - Package manager for Kubernetes
- Ingress - Advanced routing and load balancing
- StatefulSets - For stateful applications
- DaemonSets - Run pods on all nodes
- Jobs and CronJobs - Batch processing
Resources
- Official Documentation: kubernetes.io
- kubectl Cheat Sheet: kubernetes.io/docs/reference/kubectl/cheatsheet
- Interactive Tutorial: kubernetes.io/docs/tutorials
- Community: kubernetes.io/community
Conclusion
Kubernetes provides powerful container orchestration capabilities. By mastering these basic concepts and commands, you're well-equipped to deploy and manage containerized applications at scale. Remember to:
- Start simple with single pods and gradually move to deployments
- Always use namespaces to organize resources
- Implement proper health checks and resource limits
- Use declarative configuration with version control
- Monitor your applications and iterate based on real-world usage
Happy Kubernetes learning! 🚀