Appearance
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 minikube và kubectl
- 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ự restartDocker Compose vs Kubernetes
| Đặc điểm | Docker Compose | Kubernetes |
|---|---|---|
| Quy mô | 1 server | Multi-server cluster |
| Auto-scaling | ❌ | ✅ HPA |
| Self-healing | ❌ | ✅ Tự restart pod |
| Rolling update | Thủ công | ✅ Tự động |
| Load balancing | ❌ | ✅ Service |
| High availability | ❌ | ✅ Multi-node |
| Complexity | Đơn giản | Phức tạp |
| Use case | Dev, small apps | Production 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/minikubeCà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/kubectlKhở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.04. 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: 80bash
# 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-nginx5. 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-appRolling 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
| Type | Truy cập | Use case |
|---|---|---|
ClusterIP | Bên trong cluster | Service nội bộ (DB, cache) |
NodePort | Từ bên ngoài qua node IP:port | Dev/testing |
LoadBalancer | Từ internet qua LB | Production (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:300807. 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: 3File 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: 30080bash
# 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 --url8. Kubectl Cheat Sheet
Các lệnh thường dùng
| Lệnh | Ý nghĩa |
|---|---|
kubectl get pods | Liệt kê pods |
kubectl get deployments | Liệt kê deployments |
kubectl get services | Liệt kê services |
kubectl get all | Liệt kê tất cả |
kubectl describe pod NAME | Chi tiết pod |
kubectl logs POD_NAME | Xem logs |
kubectl exec -it POD -- bash | Shell vào pod |
kubectl apply -f FILE | Áp dụng config |
kubectl delete -f FILE | Xóa resources |
kubectl scale deployment NAME --replicas=N | Scale |
kubectl rollout status deployment NAME | Xem rollout |
kubectl rollout undo deployment NAME | Rollback |
kubectl top pods | Xem resource usage |
kubectl port-forward POD 8080:80 | Forward port |
🏋️ Bài tập thực hành
Bài 1: Cài đặt và khởi động
- Cài đặt minikube và kubectl
- Khởi động:
minikube start - Kiểm tra:
kubectl get nodes - Mở Dashboard:
minikube dashboard
Bài 2: Deploy Nginx
- Tạo file
deployment.yamlcho nginx (3 replicas) - Tạo file
service.yaml(NodePort) - Apply cả hai
- Truy cập qua trình duyệt
Bài 3: Self-healing
- Xem pods:
kubectl get pods - Xóa thủ công một pod:
kubectl delete pod <tên-pod> - Xem pods lại:
kubectl get pods→ K8s tự tạo pod mới!
Bài 4: Rolling update
- Deploy nginx:1.24
- Update lên nginx:1.25:
kubectl set image deployment/web-app nginx=nginx:1.25 - Xem rollout:
kubectl rollout status deployment/web-app - Rollback:
kubectl rollout undo deployment/web-app - Kiểm tra version hiện tại
Bài 5: Dọn dẹp
- Xóa tất cả resources:
kubectl delete -f k8s/ - Dừng minikube:
minikube stop - (Tuỳ chọn) Xóa cluster:
minikube delete