Target Audience: Developers who want to practice Kubernetes core resources hands-on Prerequisites: Pod, Deployment, Service concepts After reading this: You’ll be able to create and manage Pod, Deployment, Service, and ConfigMap directly
TL;DR
- Create Nginx Deployment and expose via Service
- Inject configuration with ConfigMap
- Practice rolling updates and rollbacks
Prerequisites#
You need:
- Local Kubernetes cluster (Minikube or Kind)
- kubectl
# Check cluster status
kubectl cluster-infoExercise 1: Deployment and Service#
Create Deployment#
Deploy a web server.
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
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
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"# Create Deployment
kubectl apply -f nginx-deployment.yaml
# Check status
kubectl get deployment nginx
kubectl get pods -l app=nginxExpected output:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 30sCreate Service#
Create a Service to access the Pods.
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80# Create Service
kubectl apply -f nginx-service.yaml
# Check status
kubectl get service nginx
kubectl get endpoints nginxTest Internal Access#
# Access Service from temporary Pod
kubectl run test --image=busybox:1.36 --rm -it --restart=Never \
-- wget -qO- http://nginx
# Multiple requests will be distributed across different Pods
kubectl run test --image=busybox:1.36 --rm -it --restart=Never \
-- sh -c 'for i in 1 2 3 4 5; do wget -qO- http://nginx 2>/dev/null | head -1; done'External Access (NodePort)#
# Change Service type
kubectl patch service nginx -p '{"spec":{"type":"NodePort"}}'
# Access via Minikube
minikube service nginx --url
# Check assigned port
kubectl get service nginxExercise 2: Using ConfigMap#
Create ConfigMap#
Manage Nginx configuration with ConfigMap.
# nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /health {
return 200 'healthy\n';
add_header Content-Type text/plain;
}
}
index.html: |
<!DOCTYPE html>
<html>
<head><title>Hello Kubernetes!</title></head>
<body>
<h1>Hello from Kubernetes!</h1>
<p>Pod Name: $HOSTNAME</p>
</body>
</html>kubectl apply -f nginx-configmap.yamlMount ConfigMap in Deployment#
# nginx-deployment-with-config.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.conf
- name: config
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
volumes:
- name: config
configMap:
name: nginx-config# Update Deployment
kubectl apply -f nginx-deployment-with-config.yaml
# Check rollout status
kubectl rollout status deployment/nginx
# Test
kubectl run test --image=busybox:1.36 --rm -it --restart=Never \
-- wget -qO- http://nginxExercise 3: Rolling Updates and Rollbacks#
Update Image#
# Check current image
kubectl get deployment nginx -o jsonpath='{.spec.template.spec.containers[0].image}'
# Update image
kubectl set image deployment/nginx nginx=nginx:1.26
# Check rollout status
kubectl rollout status deployment/nginx
# Watch Pods (gradual replacement)
kubectl get pods -l app=nginx -wRollout History#
# Check history
kubectl rollout history deployment/nginx
# Detailed info for specific revision
kubectl rollout history deployment/nginx --revision=2Rollback#
# Rollback to previous version
kubectl rollout undo deployment/nginx
# Rollback to specific version
kubectl rollout undo deployment/nginx --to-revision=1
# Verify
kubectl get deployment nginx -o jsonpath='{.spec.template.spec.containers[0].image}'Exercise 4: Scaling#
Manual Scaling#
# Scale out to 5
kubectl scale deployment/nginx --replicas=5
# Verify
kubectl get pods -l app=nginx
# Scale down to 2
kubectl scale deployment/nginx --replicas=2HPA Setup (Optional)#
# Enable Metrics Server (Minikube)
minikube addons enable metrics-server
# Create HPA
kubectl autoscale deployment nginx --cpu-percent=50 --min=2 --max=10
# Check HPA status
kubectl get hpa nginxExercise 5: Cleanup#
Delete Individually#
kubectl delete service nginx
kubectl delete deployment nginx
kubectl delete configmap nginx-configDelete All at Once#
# Delete by label
kubectl delete all -l app=nginx
# Delete by YAML files
kubectl delete -f nginx-deployment.yaml -f nginx-service.yamlComplete YAML File#
A single file containing all resources used in the exercises.
# complete-example.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
location / {
root /usr/share/nginx/html;
}
location /health {
return 200 'healthy\n';
}
}
index.html: |
<h1>Hello from Kubernetes!</h1>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.conf
- name: config
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: config
configMap:
name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80# Deploy all
kubectl apply -f complete-example.yaml
# Delete all
kubectl delete -f complete-example.yamlNext Steps#
After completing the basic example, proceed to:
| Goal | Recommended Document |
|---|---|
| Deploy real app | Spring Boot Deployment |
| Troubleshooting | Pod Troubleshooting |
| Deepen concepts | Resource Management |