Chuyển đến nội dung chính

LESSON 9: PRACTICE — BASIC KUBERNETES OBJECTS

Module 2 practice: Deploy web applications with Deployment and Sidecar containers, perform rolling updates, expose services, debug with ephemeral containers, manage namespaces and resource quotas.

🔒 DevSecOps — Lesson 9 LESSON 9: PRACTICE — KUBERNETES OBJECTS TABLE

KUBERNETES: FROM BASIC TO ADVANCED

Module 2: Basic Kubernetes Objects

xdev.asia

🎯 Practice objective__HTMLTAG_68___
  • Deploy real web application with Deployment + Sidecar container (log forwarder)
  • Perform rolling update and rollback__HTMLTAG_73___
  • Expose service with NodePort
  • Debug containers with ephemeral containers
  • Manage namespaces and ResourceQuotas for multi-team__HTMLTAG_79___

Preparation

# Đảm bảo cluster đang chạy
kubectl cluster-info
kubectl get nodes

Tạo namespace cho bài thực hành

kubectl create namespace lab2 kubectl config set-context --current --namespace=lab2

Lab 1: Deploy Web App with Sidecar Container

Deploy nginx with Grafana Alloy as sidecar log forwarder (simulated, no need to configure actual Loki).

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: lab2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
        version: v1
    spec:
      initContainers:
      # Sidecar container (K8s 1.33+)
      - name: log-agent
        image: busybox:1.36
        restartPolicy: Always
        command: ['sh', '-c', 'while true; do echo "[$(date)] Sidecar running"; sleep 30; done']
        resources:
          requests:
            cpu: "10m"
            memory: "16Mi"
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "256Mi"
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 10
EOF
# Theo dõi deployment
kubectl rollout status deployment/webapp -n lab2
kubectl get pods -n lab2 -w

Xem logs của từng container trong pod

kubectl logs -n lab2 -l app=webapp -c nginx kubectl logs -n lab2 -l app=webapp -c log-agent

Kiểm tra pods có 2 containers (nginx + log-agent)

kubectl get pods -n lab2

READY column sẽ hiển thị 2/2

Lab 2: Expose Service and Test Load Balancing__HTMLTAG_88___
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
  namespace: lab2
spec:
  type: NodePort
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 80
    nodePort: 31080
EOF

Lấy Node IP

kubectl get nodes -o wide

Test (thay NODE_IP bằng IP thực)

curl http://NODE_IP:31080

Xem EndpointSlices

kubectl get endpointslices -n lab2 -l kubernetes.io/service-name=webapp-service

Lab 3: Rolling Update

# Update sang nginx 1.28
kubectl set image deployment/webapp nginx=nginx:1.28 -n lab2

Theo dõi quá trình update

kubectl rollout status deployment/webapp -n lab2

Xem pods cũ bị terminate và pods mới được tạo

kubectl get pods -n lab2 -w

Xem revision history

kubectl rollout history deployment/webapp -n lab2

Rollback về version cũ

kubectl rollout undo deployment/webapp -n lab2 kubectl rollout status deployment/webapp -n lab2

Lab 4: Debug with Ephemeral Containers

# Lấy tên một pod
POD=$(kubectl get pods -n lab2 -l app=webapp -o jsonpath='{.items[0].metadata.name}')
echo "Pod: $POD"

Attach ephemeral container debug

kubectl debug -it $POD -n lab2 --image=busybox:1.36 --target=nginx

Trong ephemeral container:

wget -O- http://localhost # test localhost

ps aux # xem processes trong nginx container

exit

Lab 5: Multi-team Namespaces with ResourceQuota

# Tạo namespaces cho 2 teams
kubectl create namespace team-alpha
kubectl create namespace team-beta

Áp dụng ResourceQuota cho team-alpha

cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ResourceQuota metadata: name: alpha-quota namespace: team-alpha spec: hard: requests.cpu: "2" requests.memory: 4Gi limits.cpu: "4" limits.memory: 8Gi pods: "10" EOF

Áp dụng LimitRange

cat <<EOF | kubectl apply -f - apiVersion: v1 kind: LimitRange metadata: name: alpha-limits namespace: team-alpha spec: limits:

  • type: Container default: cpu: "200m" memory: "256Mi" defaultRequest: cpu: "100m" memory: "128Mi" EOF

Deploy trong team-alpha (không cần khai báo resources — LimitRange sẽ tự áp dụng)

cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: alpha-app namespace: team-alpha spec: replicas: 3 selector: matchLabels: app: alpha-app template: metadata: labels: app: alpha-app spec: containers: - name: app image: nginx:1.27 # Không khai báo resources — LimitRange sẽ áp dụng default EOF

Kiểm tra quota usage

kubectl describe resourcequota alpha-quota -n team-alpha

Thử vượt quá quota (sẽ bị từ chối)

kubectl scale deployment alpha-app --replicas=15 -n team-alpha

Error: pods "alpha-app-xxx" is forbidden: exceeded quota

Lab 6: Canary Deployment

# Stable: 9 replicas (90% traffic)
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-stable
  namespace: lab2
spec:
  replicas: 9
  selector:
    matchLabels:
      app: webapp-v2
      track: stable
  template:
    metadata:
      labels:
        app: webapp-v2
        track: stable
    spec:
      containers:
      - name: nginx
        image: nginx:1.27
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-canary
  namespace: lab2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp-v2
      track: canary
  template:
    metadata:
      labels:
        app: webapp-v2
        track: canary
    spec:
      containers:
      - name: nginx
        image: nginx:1.28   # phiên bản mới
---
apiVersion: v1
kind: Service
metadata:
  name: webapp-v2-service
  namespace: lab2
spec:
  selector:
    app: webapp-v2   # match cả stable và canary
  ports:
  - port: 80
EOF

Kiểm tra traffic distribution

~10% requests sẽ đến canary pod

for i in $(seq 1 10); do kubectl exec -n lab2 debug-pod -- curl -s http://webapp-v2-service; done

Troubleshooting — Common Issues

Pod stuck in Pending__HTMLTAG_100___
kubectl describe pod <pod-name> -n lab2
# Xem Events section: thường là InsufficientCPU, InsufficientMemory, hoặc ImagePullBackOff

ImagePullBackOff

kubectl describe pod <pod-name> -n lab2
# Events: Failed to pull image — kiểm tra tên image và registry credentials

CrashLoopBackOff

kubectl logs <pod-name> -n lab2 --previous
# Xem logs của lần chạy trước để tìm nguyên nhân crash

Cleanup

kubectl delete namespace lab2 team-alpha team-beta
kubectl config set-context --current --namespace=default

Summary__HTMLTAG_108___

You have practiced:

  • ✅ Deploy Deployment with Sidecar container (K8s 1.33+)
  • ✅ Rolling update and safe rollback
  • ✅ Service with NodePort and EndpointSlices
  • ✅ Debug with ephemeral containers
  • ✅ Namespaces + ResourceQuota + LimitRange for multi-team
  • ✅ Canary deployment pattern