Skip to content

Buổi 8: Kubernetes Cơ Bản

🎯 Mục tiêu

  • Hiểu Kubernetes (K8s) là gì và tại sao cần dùng
  • Cài đặt minikubekubectl
  • Hiểu các khái niệm: Pod, Deployment, Service
  • Triển khai ứng dụng đầu tiên lên Kubernetes
  • So sánh Docker Compose vs Kubernetes

1. Tại sao cần Kubernetes?

Vấn đề khi chỉ dùng Docker

Docker Compose trên 1 server:
┌─────────────────────────────────┐
│          Server (1 máy)          │
│  ┌─────┐ ┌─────┐ ┌─────┐       │
│  │ API │ │ API │ │ DB  │       │
│  │  1  │ │  2  │ │     │       │
│  └─────┘ └─────┘ └─────┘       │
│                                  │
│  ⚠️ Server chết = App chết      │
│  ⚠️ Không auto-scaling          │
│  ⚠️ Không auto-healing          │
└─────────────────────────────────┘

Kubernetes giải quyết

Kubernetes Cluster:
┌──────────────────────────────────────────────┐
│                Control Plane                  │
│  ┌────────┐ ┌───────────┐ ┌──────────────┐  │
│  │  API   │ │ Scheduler │ │  Controller  │  │
│  │ Server │ │           │ │  Manager     │  │
│  └────────┘ └───────────┘ └──────────────┘  │
└──────────────────────────────────────────────┘
         │              │              │
    ┌────┴────┐    ┌────┴────┐    ┌────┴────┐
    │ Node 1  │    │ Node 2  │    │ Node 3  │
    │┌───┐┌──┐│    │┌───┐┌──┐│    │┌───┐    │
    ││API││DB││    ││API││API│    ││DB │    │
    │└───┘└──┘│    │└───┘└──┘│    │└───┘    │
    └─────────┘    └─────────┘    └─────────┘

    ✅ Node chết → K8s tự chuyển pods sang node khác
    ✅ Auto-scaling khi load tăng
    ✅ Rolling updates không downtime
    ✅ Self-healing: pod crash → tự restart

Docker Compose vs Kubernetes

Đặc điểmDocker ComposeKubernetes
Quy mô1 serverMulti-server cluster
Auto-scaling✅ HPA
Self-healing✅ Tự restart pod
Rolling updateThủ công✅ Tự động
Load balancing✅ Service
High availability✅ Multi-node
ComplexityĐơn giảnPhức tạp
Use caseDev, small appsProduction at scale

2. Kiến trúc Kubernetes

Các thành phần chính

┌─────────────────────────────────────────────────┐
│              Control Plane (Master)               │
│                                                   │
│  ┌──────────────┐  ┌───────────────────────────┐ │
│  │  API Server  │  │  etcd (key-value store)   │ │
│  │  (kube-api)  │  │  (lưu toàn bộ state)     │ │
│  └──────┬───────┘  └───────────────────────────┘ │
│         │                                         │
│  ┌──────┴───────┐  ┌───────────────────────────┐ │
│  │  Scheduler   │  │  Controller Manager       │ │
│  │  (lên lịch   │  │  (đảm bảo desired state)  │ │
│  │   pods)      │  │                           │ │
│  └──────────────┘  └───────────────────────────┘ │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│                  Worker Node                      │
│                                                   │
│  ┌──────────────┐  ┌───────────────────────────┐ │
│  │   kubelet    │  │  kube-proxy               │ │
│  │ (quản lý     │  │  (networking, routing)    │ │
│  │  pods)       │  │                           │ │
│  └──────────────┘  └───────────────────────────┘ │
│                                                   │
│  ┌──────────────────────────────────────────────┐ │
│  │  Container Runtime (containerd / CRI-O)      │ │
│  │  ┌──────┐  ┌──────┐  ┌──────┐               │ │
│  │  │ Pod  │  │ Pod  │  │ Pod  │               │ │
│  │  └──────┘  └──────┘  └──────┘               │ │
│  └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘

3. Cài đặt minikube & kubectl

Cài đặt minikube (Kubernetes cục bộ)

bash
# Windows (dùng winget)
$ winget install Kubernetes.minikube

# macOS
$ brew install minikube

# Linux
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube

Cài đặt kubectl

bash
# Windows
$ winget install Kubernetes.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"
$ sudo install kubectl /usr/local/bin/kubectl

Khởi động cluster

bash
# Khởi tạo minikube cluster
$ minikube start

# Kiểm tra trạng thái
$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

# Kiểm tra kubectl kết nối
$ kubectl cluster-info
Kubernetes control plane is running at https://192.168.49.2:8443

# Xem nodes
$ kubectl get nodes
NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.30.0

4. Pods

Pod là gì?

Pod là đơn vị nhỏ nhất trong Kubernetes – chứa một hoặc nhiều containers.

┌────────────────────────────┐
│           Pod              │
│  ┌──────────┐              │
│  │Container │  Shared:     │
│  │ (app)    │  - Network   │
│  └──────────┘  - Storage   │
│  ┌──────────┐  - IP addr   │
│  │Container │              │
│  │ (sidecar)│              │
│  └──────────┘              │
└────────────────────────────┘

Tạo Pod đơn giản

yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:alpine
      ports:
        - containerPort: 80
bash
# Tạo pod
$ kubectl apply -f pod.yaml

# Xem pods
$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
my-nginx   1/1     Running   0          30s

# Xem chi tiết
$ kubectl describe pod my-nginx

# Xem logs
$ kubectl logs my-nginx

# Exec vào pod
$ kubectl exec -it my-nginx -- bash

# Xóa pod
$ kubectl delete pod my-nginx

5. Deployments

Deployment là gì?

Deployment quản lý ReplicaSet → quản lý Pods. Đây là cách triển khai app trong production.

┌─────────────────────────────────────┐
│           Deployment                 │
│  replicas: 3                        │
│                                     │
│  ┌─────────────────────────────┐    │
│  │        ReplicaSet           │    │
│  │                             │    │
│  │  ┌──────┐ ┌──────┐ ┌──────┐│    │
│  │  │ Pod  │ │ Pod  │ │ Pod  ││    │
│  │  │ v1.0 │ │ v1.0 │ │ v1.0 ││    │
│  │  └──────┘ └──────┘ └──────┘│    │
│  └─────────────────────────────┘    │
└─────────────────────────────────────┘

Tạo Deployment

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: nginx:alpine
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "128Mi"
              cpu: "250m"
bash
# Tạo deployment
$ kubectl apply -f deployment.yaml

# Xem deployments
$ kubectl get deployments
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
my-app   3/3     3            3           1m

# Xem pods (3 replicas)
$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
my-app-7d9f8b6c5d-abc12   1/1     Running   0          1m
my-app-7d9f8b6c5d-def34   1/1     Running   0          1m
my-app-7d9f8b6c5d-ghi56   1/1     Running   0          1m

# Scale lên 5 replicas
$ kubectl scale deployment my-app --replicas=5

# Rolling update (đổi image)
$ kubectl set image deployment/my-app app=nginx:1.25

# Xem rollout status
$ kubectl rollout status deployment/my-app

# Rollback nếu có lỗi
$ kubectl rollout undo deployment/my-app

# Xem history
$ kubectl rollout history deployment/my-app

Rolling Update trực quan

Trước update (v1.0):
  Pod-1 [v1.0] ✅   Pod-2 [v1.0] ✅   Pod-3 [v1.0] ✅

Đang update (v1.0 → v2.0):
  Pod-1 [v2.0] ✅   Pod-2 [v1.0] 🔄   Pod-3 [v1.0] ✅
                      ↓ đang thay
  Pod-1 [v2.0] ✅   Pod-2 [v2.0] ✅   Pod-3 [v1.0] 🔄

Sau update (v2.0):
  Pod-1 [v2.0] ✅   Pod-2 [v2.0] ✅   Pod-3 [v2.0] ✅

→ ZERO downtime! Luôn có pods serving traffic.

6. Services

Service là gì?

Service cung cấp một địa chỉ ổn định để truy cập một nhóm Pods (Pods có thể bị tạo/xóa liên tục).

                  Service (my-app-svc)
                  ClusterIP: 10.96.0.100

            ┌────────────┼────────────┐
            ▼            ▼            ▼
        ┌──────┐    ┌──────┐    ┌──────┐
        │ Pod  │    │ Pod  │    │ Pod  │
        │ v1.0 │    │ v1.0 │    │ v1.0 │
        └──────┘    └──────┘    └──────┘

Các loại Service

TypeTruy cậpUse case
ClusterIPBên trong clusterService nội bộ (DB, cache)
NodePortTừ bên ngoài qua node IP:portDev/testing
LoadBalancerTừ internet qua LBProduction (cloud)

Tạo Service

yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  type: NodePort
  selector:
    app: my-app      # Kết nối với pods có label app=my-app
  ports:
    - protocol: TCP
      port: 80        # Port của service
      targetPort: 80  # Port trong container
      nodePort: 30080 # Port trên node (30000-32767)
bash
# Tạo service
$ kubectl apply -f service.yaml

# Xem services
$ kubectl get services
NAME          TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
my-app-svc    NodePort   10.96.0.100    <none>        80:30080/TCP   1m
kubernetes    ClusterIP  10.96.0.1      <none>        443/TCP        1h

# Truy cập qua minikube
$ minikube service my-app-svc
# → Mở trình duyệt tự động

# Hoặc lấy URL
$ minikube service my-app-svc --url
http://192.168.49.2:30080

7. Tổng hợp: Deploy app hoàn chỉnh

Kiến trúc

        Internet / Browser

               ▼ :30080
        ┌──────────────┐
        │   Service    │
        │  (NodePort)  │
        └──────┬───────┘

    ┌──────────┼──────────┐
    ▼          ▼          ▼
┌──────┐  ┌──────┐  ┌──────┐
│ Pod  │  │ Pod  │  │ Pod  │
│nginx │  │nginx │  │nginx │
└──────┘  └──────┘  └──────┘
        Deployment
        replicas: 3

File YAML tổng hợp

yaml
# k8s/app.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: "32Mi"
              cpu: "50m"
            limits:
              memory: "64Mi"
              cpu: "100m"
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
bash
# Deploy tất cả
$ kubectl apply -f k8s/app.yaml

# Kiểm tra
$ kubectl get all
NAME                           READY   STATUS    RESTARTS   AGE
pod/web-app-7d9f8b6c5d-abc12   1/1     Running   0          1m
pod/web-app-7d9f8b6c5d-def34   1/1     Running   0          1m
pod/web-app-7d9f8b6c5d-ghi56   1/1     Running   0          1m

NAME                  TYPE        CLUSTER-IP     PORT(S)        AGE
service/web-service   NodePort    10.96.0.100    80:30080/TCP   1m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web-app   3/3     3            3           1m

# Truy cập
$ minikube service web-service --url

8. Kubectl Cheat Sheet

Các lệnh thường dùng

LệnhÝ nghĩa
kubectl get podsLiệt kê pods
kubectl get deploymentsLiệt kê deployments
kubectl get servicesLiệt kê services
kubectl get allLiệt kê tất cả
kubectl describe pod NAMEChi tiết pod
kubectl logs POD_NAMEXem logs
kubectl exec -it POD -- bashShell vào pod
kubectl apply -f FILEÁp dụng config
kubectl delete -f FILEXóa resources
kubectl scale deployment NAME --replicas=NScale
kubectl rollout status deployment NAMEXem rollout
kubectl rollout undo deployment NAMERollback
kubectl top podsXem resource usage
kubectl port-forward POD 8080:80Forward port

🏋️ Bài tập thực hành

Bài 1: Cài đặt và khởi động

  1. Cài đặt minikube và kubectl
  2. Khởi động: minikube start
  3. Kiểm tra: kubectl get nodes
  4. Mở Dashboard: minikube dashboard

Bài 2: Deploy Nginx

  1. Tạo file deployment.yaml cho nginx (3 replicas)
  2. Tạo file service.yaml (NodePort)
  3. Apply cả hai
  4. Truy cập qua trình duyệt

Bài 3: Self-healing

  1. Xem pods: kubectl get pods
  2. Xóa thủ công một pod: kubectl delete pod <tên-pod>
  3. Xem pods lại: kubectl get pods → K8s tự tạo pod mới!

Bài 4: Rolling update

  1. Deploy nginx:1.24
  2. Update lên nginx:1.25: kubectl set image deployment/web-app nginx=nginx:1.25
  3. Xem rollout: kubectl rollout status deployment/web-app
  4. Rollback: kubectl rollout undo deployment/web-app
  5. Kiểm tra version hiện tại

Bài 5: Dọn dẹp

  1. Xóa tất cả resources: kubectl delete -f k8s/
  2. Dừng minikube: minikube stop
  3. (Tuỳ chọn) Xóa cluster: minikube delete