N
Nyanan

Kubernetes: Là Gì, Khi Nào, Ở Đâu & Cách Thức — Hướng Dẫn Thực Hành Chi Tiết

Kubernetes: Là Gì, Khi Nào, Ở Đâu & Cách Thức — Hướng Dẫn Thực Hành Chi Tiết

Bài viết này bao gồm Kubernetes là gì, khi nào nên sử dụng, chạy ở đâu / các thành phần nằm ở đâu, và cách thiết lập & migrate từ EC2 + Docker thông thường.


Tóm Tắt Nhanh

  • Là Gì: Kubernetes là platform mã nguồn mở, portable và extensible để quản lý containerized workloads và services. Nó hỗ trợ cả declarative configuration và automation.

  • Khi Nào: Sử dụng cho ứng dụng multi-service, deploy thường xuyên, autoscaling, và zero-downtime. Không nên dùng cho stack nhỏ/đơn giản mà single VM + Docker Compose xử lý được.

  • Ở Đâu: Trên bất kỳ Linux VMs nào (cloud/bare‑metal). Cần: container runtime (containerd), CNI (Flannel/Calico/Cilium), Ingress controller, Storage (CSI hoặc local‑path), Registry cho images, và nơi lưu configs/secrets.

  • Cách Thức: Bắt đầu đơn giản với K3s single‑node (nhanh) hoặc dùng kubeadm multi‑node (production control). Migrate từng service thành Deployment + Service + Ingress, chuyển envs sang ConfigMap/Secret, thêm probes, resources, và (tùy chọn) HPA.


1) Kubernetes Là Gì: Các Khái Niệm Cốt Lõi

Các thành phần cơ bản của Kubernetes

  • Node: một VM/physical server trong cluster (ví dụ: EC2 instance).
  • Pod: đơn vị deployable nhỏ nhất (thường là 1 container). K8s schedule pods lên các nodes.
  • Deployment: trạng thái mong muốn cho pods với rolling updates & self‑healing.
  • Service: virtual IP/name ổn định để reach pods (ClusterIP/NodePort/LoadBalancer).
  • Ingress: HTTP(S) routing từ Internet đến Services (với Ingress Controller như NGINX/Traefik).
  • ConfigMap / Secret: configuration/env vars (Secret được base64‑encoded, dùng KMS/SealedSecrets cho security thực sự).
  • Volume / PersistentVolume (PV) / PersistentVolumeClaim (PVC): stateful storage cho pods.
  • Namespace: logical isolation bên trong cluster (ví dụ: dev, prod).

Siêu năng lực của Kubernetes

  • Self‑healing (restart pods), desired state (reconcile loops), rolling deploys/rollback, autoscaling, service discovery, resource quotas/limits, RBAC, observability hooks.

1.2 Những Gì Cần Để Xây Dựng Kubernetes Cluster

AWS Load Balancer Controller and S3 Integration

Sơ đồ trên mô tả AWS Load Balancer Controller integration với Kubernetes:

  • YAML Manifest: Định nghĩa AWS Load Balancer resources (Bucket) trong Kubernetes
  • Kubernetes API: Nhận và xử lý các custom resources từ AWS Controllers
  • AWS Controllers for Kubernetes: Custom controllers quản lý AWS services từ trong K8s cluster
  • app-images-bucket: S3 bucket được tạo và quản lý thông qua Kubernetes manifests

Đây là ví dụ về cách Kubernetes có thể quản lý cloud resources (AWS S3) thông qua custom controllers, không chỉ containers.

Kubernetes Cluster Architecture - Control Plane and Worker Nodes

Kiến trúc Kubernetes Cluster gồm 2 phần chính:

  • Control Plane: Bộ não của cluster, bao gồm:
    • API Server: Điểm trung tâm nhận mọi request
    • etcd: Database lưu trữ trạng thái cluster
    • Scheduler: Quyết định pod chạy trên node nào
    • Controller Manager: Đảm bảo trạng thái mong muốn được duy trì
  • Worker Nodes: Nơi chạy các ứng dụng thực tế (containers)
  • Cloud Provider API: Tích hợp với cloud services (AWS, GCP, Azure)

Kubernetes Objects Hierarchy

Hệ thống phân cấp và quản lý objects trong Kubernetes:

  • Namespace: Cô lập logically các tài nguyên trong cluster (như "cluster trong cluster")
  • Deployment: Workload resource mô tả desired state, không phải step-by-step instructions
  • Pod: Đơn vị deployable nhỏ nhất, thường chứa 1 container (có thể nhiều container cho sidecar pattern)
  • Container: Ứng dụng thực tế, với ephemeral files system

Bạn thường không tạo Pods trực tiếp - sử dụng Deployment để Kubernetes tự động tạo và quản lý Pods, đảm bảo desired state được duy trì.

Kubernetes YAML Structure - Declarative Configuration Example

Cấu trúc Deployment YAML - Desired State Declaration:

  • DeploymentSpec: Khai báo số replicas (horizontal scaling) và strategy cho updates
  • PodTemplateSpec: Template mô tả cách tạo Pods, bao gồm labels (như app: directory-frontend)
  • PodSpec: Chi tiết container configuration (image, ports, resources)
  • Rolling Update Strategy: Chiến lược deploy tự động (maxSurge, maxUnavailable)

Deployment controllers sẽ liên tục monitor cluster state và tự động tạo/restart Pods để maintain desired state - không cần manual intervention.

Kubernetes Volumes - Persistent and Ephemeral Storage

Hệ thống quản lý storage trong Kubernetes:

  • Pod 1 & Pod 2: Các pods có thể chạy trên các nodes khác nhau nhưng vẫn truy cập được storage
  • EmptyDir Volume: Storage tạm thời được tạo khi Pod khởi chạy, sẽ bị xóa khi Pod removed
  • AWS ElasticBlockStore: EBS volumes cho persistent storage, không bị mất khi Pod restart
  • GlusterFS & CephFS: Network file systems cho shared storage giữa multiple pods

Files trong Pod containers là ephemeral - khi container biến mất thì files cũng biến mất. Volumes giải quyết vấn đề này bằng cách cung cấp persistent storage.

2) Khi Nào Nên Sử Dụng Kubernetes?

Sử dụng K8s khi một hoặc nhiều điều kiện sau đúng:

  • Ứng dụng đã vượt quá yêu cầu CPU, network, storage của single node
  • Bạn có > 5 services (hoặc dự kiến có), và/hoặc deploy thường xuyên (≥ 5 lần/tuần)
  • Cần zero‑downtime deploys, automatic recovery, blue‑green/canary
  • Traffic tăng đột biến (flash sales, events) → muốn autoscaling
  • Muốn loại bỏ các quy trình manual cho scheduling containers, scaling, monitoring health
  • Nhiều teams → cần standardized operations (RBAC, quotas, CI/CD)
  • Nhiều containers thực hiện các tasks khác nhau trên multiple nodes
  • Cần fault-tolerance: node có thể fail, hệ thống detect và relaunch services

Tránh/Hoãn K8s khi:

  • 1–2 apps, traffic ổn định, deploy hiếm → Docker Compose + Nginx trên single VM nhanh hơn/rẻ hơn
  • Team thiếu bandwidth ops: K8s thêm operational complexity và bạn phải chạy upgrades, monitoring, backups

Nguyên tắc: Bắt đầu đơn giản; adopt K8s khi release frequency, service count, fault-tolerance requirements, hoặc SLA yêu cầu.


3) Ở Đâu: Runtime, Networking, Storage, Registry, Config

K8s chạy ở đâu?

  • Bất kỳ đâu có Linux VMs: cloud (EC2/GCE), bare‑metal, on‑prem, edge. Bạn không nhất thiết phải dùng managed offerings (EKS/GKE/AKS) nếu thích DIY.

Containers chạy ở đâu?

  • Trên nodes sử dụng container runtime (thường là containerd). K8s schedule pods trên các nodes.

Services lấy IPs ở đâu?

  • CNI plugin (Flannel/Calico/Cilium) cung cấp Pod networking. Services nhận stable virtual IPs bên trong cluster.

Inbound traffic vào từ đâu?

  • Qua Ingress Controller (NGINX/Traefik) lắng nghe trên node ports/LB. Public DNS trỏ đến controller.

Dữ liệu được lưu ở đâu?

  • Cho stateful workloads: dùng CSI drivers (ví dụ: AWS EBS CSI) hoặc đơn giản hơn local‑path (single‑node dev). PVCs bind với PVs.

Images được giữ ở đâu?

  • Một container registry: Docker Hub, GHCR, GitLab Registry, hoặc AWS ECR. CI push images; K8s pull chúng.

Configs/secrets ở đâu?

  • ConfigMapSecret (tùy chọn sealed/encrypted). Infrastructure configs sống trong Git (Helm/Kustomize).

4) Cách Thức: Hai Hướng Thiết Lập

Hướng A — K3s (single‑node) — cách nhanh nhất để bắt đầu

Tốt cho dev/POC hoặc prod nhỏ mà single VM có thể chấp nhận được.

# Ubuntu VM (ví dụ: EC2)
sudo apt-get update -y && sudo apt-get upgrade -y
curl -sfL https://get.k3s.io | sh -

# Kubeconfig cho kubectl
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config

# Verify
kubectl get nodes
kubectl get pods -A

Mặc định, K3s mang theo Flannel (CNI), Traefik (Ingress), và local‑path storage. Bạn có thể thay Traefik bằng NGINX Ingress nếu thích.

Hướng B — kubeadm (multi‑node) — topology production tối thiểu

Cho 1 control‑plane + ≥1 worker. Bạn quản lý tất cả các phần.

# Trên tất cả nodes: disable swap, prepare kernel modules
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
cat <<'EOF' | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay && sudo modprobe br_netfilter
cat <<'EOF' | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system

# Install containerd + kubeadm/kubelet/kubectl (Ubuntu; v1.30 làm ví dụ)
# (bỏ qua chi tiết repo setup để ngắn gọn; theo official docs cho distro của bạn)

# Trên control-plane:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# Install CNI (Flannel được hiển thị)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

# Trên workers: join sử dụng token/sha được in bởi kubeadm init
sudo kubeadm join <CP_PRIVATE_IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

Sau đó install Ingress NGINX, MetalLB (nếu muốn LoadBalancer type trên bare VMs), metrics‑server, cert‑manager (TLS), và storage solution của bạn (EBS CSI / OpenEBS / local‑path).


5) Cách Thức: Từ EC2 + Docker → Kubernetes (Migration)

Từng bước

  1. Hardening images: thêm /health endpoint, small base images, proper CMD, clear listening port.
  2. Chuyển env/config:
    • Non‑secrets → ConfigMap; secrets → Secret (tùy chọn Sealed Secrets).
  3. Mô hình hóa từng service:
    • Deployment (replicas, probes, resources) + Service (ClusterIP) + Ingress.
  4. Expose ra Internet: Ingress rule per host/path; trỏ DNS đến Ingress entrypoint.
  5. Thêm autoscaling: install metrics‑server, sau đó HorizontalPodAutoscaler.
  6. Cut over: chạy K8s song song, route % traffic nhỏ (canary) hoặc flip DNS; monitor logs/metrics; rollback nhanh nếu cần.

Ánh xạ Compose → K8s

Docker ComposeTương đương Kubernetes
services.<name>.imageDeployment.spec.template.containers[].image
ports: "80:3000"Service (ClusterIP) + Ingress rules
environment:ConfigMap / Secret
volumes:PersistentVolumeClaim + VolumeMount
depends_on:
(thường được xử lý bởi probes & readiness)

Manifests tối thiểu (ví dụ: một backend trên port 3000)

apiVersion: v1
kind: Namespace
metadata: { name: prod }
---
apiVersion: v1
kind: ConfigMap
metadata: { name: app-a-config, namespace: prod }
data:
  NODE_ENV: "production"
---
apiVersion: v1
kind: Secret
metadata: { name: app-a-secret, namespace: prod }
type: Opaque
stringData:
  DATABASE_URL: "postgres://user:pass@host:5432/db"
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: app-a, namespace: prod }
spec:
  replicas: 2
  selector: { matchLabels: { app: app-a } }
  template:
    metadata: { labels: { app: app-a } }
    spec:
      containers:
        - name: app-a
          image: ghcr.io/you/app-a:1.2.3
          ports: [{ containerPort: 3000 }]
          envFrom:
            - configMapRef: { name: app-a-config }
            - secretRef: { name: app-a-secret }
          readinessProbe:
            httpGet: { path: /health, port: 3000 }
            initialDelaySeconds: 5
          livenessProbe:
            httpGet: { path: /health, port: 3000 }
            initialDelaySeconds: 15
          resources:
            requests: { cpu: "100m", memory: "128Mi" }
            limits:   { cpu: "500m", memory: "512Mi" }
---
apiVersion: v1
kind: Service
metadata: { name: app-a, namespace: prod }
spec:
  selector: { app: app-a }
  ports: [{ port: 80, targetPort: 3000 }]
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apps
  namespace: prod
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx # hoặc traefik nếu dùng Traefik
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /app-a
            pathType: Prefix
            backend: { service: { name: app-a, port: { number: 80 } } }

Autoscale

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: app-a, namespace: prod }
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app-a
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

6) Checklist Vận Hành (Day‑2)

  • Probes (liveness/readiness) cho mọi service.
  • Resources (requests/limits) để ngăn noisy neighbors & enable HPA.
  • TLS qua cert‑manager + Let's Encrypt.
  • Observability: metrics‑server → HPA; Prometheus/Grafana cho metrics; Loki/Promtail cho logs.
  • Backups: cho bất kỳ stateful storage/DB nào.
  • Upgrades: lập kế hoạch cho K8s version bumps và node OS patching.
  • RBAC & Namespaces: enforce least privilege và quotas.

7) FAQ: Chỉ là scaling containers hay EC2s?

  • K8s scale pods (containers) trước trên nodes bạn đã có.
  • Khi nodes hết CPU/RAM, bạn thêm nodes (nhiều EC2s hơn). Bạn có thể tự động hóa điều này với Cluster Autoscaler, nhưng nó cần extra setup trên DIY clusters.
  • Ngoài scaling, K8s cung cấp rolling updates, health management, service discovery, configuration, security, và visibility — platform xung quanh containers của bạn.

8) Troubleshooting Cheatsheet

# Cái gì đang chạy?
kubectl get nodes
kubectl get pods -A

# Mô tả tại sao pod không ready
kubectl describe pod <name> -n <ns>

# Inspect logs
kubectl logs deploy/app-a -n prod
kubectl logs pod/<pod-name> -n prod --previous

# Port-forward để debug locally
kubectl port-forward svc/app-a 8080:80 -n prod

# Apply và diff manifests
kubectl apply -f k8s/
kubectl diff -f k8s/

# Exec vào pod
kubectl exec -it deploy/app-a -n prod -- sh

9) Bước Tiếp Theo / Đi đâu từ đây

  • Sử dụng Helm hoặc Kustomize để template manifests per env.
  • Gate /editor hoặc internal tools phía sau Ingress + auth.
  • Giới thiệu GitOps (Argo CD/Flux) để reconcile từ Git.
  • Nếu vượt quá single‑node: thêm workers (k3s agent) hoặc chuyển sang kubeadm cluster.

Bây giờ bạn đã có mental model thực tế về Kubernetes (là gì/khi nào/ở đâu/cách thức) và migration path hoạt động từ EC2 + Docker thông thường.