Mục tiêu học tập
Kiến trúc Kubernetes
Hiểu Control Plane (API server, scheduler, controller-manager, etcd) và Data Plane (kubelet, container runtime, kube-proxy) trên worker nodes.
kubectl Commands
Thành thạo kubectl: get, describe, apply, delete, logs, exec, scale, rollout để quản lý resources trên Kubernetes cluster.
YAML Manifests
Viết Kubernetes manifests: Deployment, Service (ClusterIP/NodePort/LoadBalancer), ConfigMap, Namespace để deploy applications.
Minikube
Cài đặt và sử dụng Minikube để chạy Kubernetes cluster cục bộ trên laptop, phù hợp cho học tập và development.
Scaling & Rolling Updates
Scale deployments tăng/giảm replicas, thực hiện rolling updates và rollback khi deployment gặp vấn đề.
Helm Package Manager
Sử dụng Helm để install, upgrade và manage Kubernetes applications thông qua Helm charts.
Lý thuyết: Kubernetes
1. Kiến trúc Kubernetes Cluster
Control Plane
- kube-apiserver: API gateway, nhận tất cả requests. Trung tâm giao tiếp.
- kube-scheduler: Quyết định pod chạy trên node nào dựa vào resources.
- kube-controller-manager: Đảm bảo desired state (replicas, endpoints...).
- etcd: Distributed key-value store, lưu trữ cluster state.
- cloud-controller-manager: Tích hợp với cloud provider APIs (AWS/Azure/GCP).
Worker Nodes (Data Plane)
- kubelet: Agent trên mỗi node, nhận PodSpecs từ API server, đảm bảo containers chạy.
- containerd: Container runtime (thay Docker từ K8s v1.23).
- kube-proxy: Network proxy, maintain network rules cho pods.
- Pods: Đơn vị nhỏ nhất, chứa 1+ containers cùng network namespace.
Pod
Nhóm 1+ containers chia sẻ network/storage. Ephemeral — có thể bị destroy và recreate bất kỳ lúc nào.
Deployment
Quản lý ReplicaSets và Pods. Định nghĩa desired state: bao nhiêu replicas, container image nào.
Service
Stable IP/DNS name cho một set of pods. Load balances traffic. Types: ClusterIP, NodePort, LoadBalancer.
Namespace
Logical partitioning của cluster. Mặc định: default, kube-system, kube-public. Cô lập resources.
ConfigMap
Lưu config data dạng key-value. Inject vào pods qua env vars hoặc volume mounts.
Secret
Như ConfigMap nhưng cho sensitive data (passwords, tokens). Base64 encoded, có thể encrypt at rest.
2. Cài đặt Minikube
# Tải và cài đặt minikube binary
$ curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube
$ rm minikube-linux-amd64
# Khởi động cluster
$ minikube start
* minikube v1.35.0 on Fedora 42
* Automatically selected the kvm2 driver
* Creating kvm2 VM (CPUs=2, Memory=2200MB, Disk=20000MB) ...
* Preparing Kubernetes v1.31.0 on Docker 27.2.0 ...
* Done! kubectl is now configured to use "minikube"
# Kiểm tra cluster
$ minikube version
minikube version: v1.35.0
$ kubectl cluster-info
Kubernetes control plane is running at https://localhost:36355
CoreDNS is running at https://localhost:36355/api/v1/namespaces/kube-system/...
3. kubectl Cơ bản
# Xem thông tin nodes
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 5m v1.31.0
# Xem tất cả pods ở mọi namespace
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS
kube-system coredns-7db6d8ff4d-x9p5t 1/1 Running 0
kube-system etcd-minikube 1/1 Running 0
kube-system kube-apiserver-minikube 1/1 Running 0
# Deploy nginx nhanh
$ kubectl create deployment nginx-demo --image=nginx:latest
deployment.apps/nginx-demo created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-demo-7d458d8d74-xk9p2 1/1 Running 0 30s
# Describe pod chi tiết
$ kubectl describe pod nginx-demo-7d458d8d74-xk9p2
Name: nginx-demo-7d458d8d74-xk9p2
Namespace: default
Node: minikube/192.168.49.2
Status: Running
IP: 10.244.0.5
# Xem logs của pod
$ kubectl logs nginx-demo-7d458d8d74-xk9p2
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
# Exec vào container
$ kubectl exec -it nginx-demo-7d458d8d74-xk9p2 -- bash
root@nginx-demo-7d458d8d74-xk9p2:/# nginx -v
nginx version: nginx/1.27.3
4. YAML Manifests: Deployment + Service
---
apiVersion
: apps/v1kind
: Deploymentmetadata
:name: nginx-deployment
namespace: default
labels:
app: nginx
spec
:replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
---
apiVersion
: v1kind
: Servicemetadata
:name: nginx-service
spec
:type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
service/nginx-service created
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d9d547f98-4j2kp 1/1 Running 0 45s
nginx-deployment-5d9d547f98-7m9xz 1/1 Running 0 45s
nginx-deployment-5d9d547f98-r8qlt 1/1 Running 0 45s
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m
nginx-service NodePort 10.103.42.181 <none> 80:30080/TCP 45s
$ minikube service nginx-service --url
http://192.168.49.2:30080
5. Scaling và Rolling Updates
# Scale deployment lên 5 replicas
$ kubectl scale deployment nginx-deployment --replicas=5
deployment.apps/nginx-deployment scaled
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d9d547f98-4j2kp 1/1 Running 0 5m
nginx-deployment-5d9d547f98-7m9xz 1/1 Running 0 5m
nginx-deployment-5d9d547f98-r8qlt 1/1 Running 0 5m
nginx-deployment-5d9d547f98-wk2pl 1/1 Running 0 15s
nginx-deployment-5d9d547f98-zt8mn 1/1 Running 0 15s
# Rolling update - thay đổi image version
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.28
deployment.apps/nginx-deployment image updated
$ kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 5 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
# Rollback nếu có vấn đề
$ kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
$ kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
6. ConfigMap và Namespaces
apiVersion
: v1kind
: ConfigMapmetadata
:name: app-config
namespace: production
data
:APP_ENV: "production"
APP_PORT: "8080"
DATABASE_HOST: "db.production.svc.cluster.local"
nginx.conf: |
server {
listen 80;
root /var/www/html;
}
# Tạo namespace
$ kubectl create namespace production
namespace/production created
$ kubectl get namespaces
NAME STATUS AGE
default Active 30m
kube-system Active 30m
production Active 5s
# Apply ConfigMap
$ kubectl apply -f app-configmap.yaml
$ kubectl get configmap -n production
NAME DATA AGE
app-config 4 10s
$ kubectl describe configmap app-config -n production
7. Helm Package Manager
Helm là package manager cho Kubernetes. "Charts" là packages chứa tất cả Kubernetes resources cần thiết cho một application.
# Cài đặt Helm
$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Downloading https://get.helm.sh/helm-v3.16.2-linux-amd64.tar.gz
helm installed into /usr/local/bin/helm
# Thêm Bitnami repo
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update
# Cài WordPress qua Helm
$ helm install my-wordpress bitnami/wordpress \
--set wordpressUsername=admin \
--set wordpressPassword=securepass \
--namespace wordpress \
--create-namespace
NAME: my-wordpress
STATUS: deployed
# Liệt kê releases
$ helm list --all-namespaces
NAME NAMESPACE REVISION STATUS CHART
my-wordpress wordpress 1 deployed wordpress-23.0.1
# Upgrade và uninstall
$ helm upgrade my-wordpress bitnami/wordpress --set replicaCount=2
$ helm uninstall my-wordpress -n wordpress
8. Kubernetes Service Types
ClusterIP (mặc định)
Chỉ accessible trong cluster. Dùng cho internal services (databases, caches). IP chỉ routable trong cluster network.
type: ClusterIP
NodePort
Expose service trên port của mỗi node (range 30000-32767). Accessible từ ngoài cluster qua NodeIP:NodePort.
type: NodePort, nodePort: 30080
LoadBalancer
Tạo external load balancer (cloud provider). Assign external IP cố định. Best cho production workloads.
type: LoadBalancer
ExternalName
Map service đến DNS CNAME. Dùng để reference external services bên ngoài cluster qua DNS name.
type: ExternalName, externalName: api.external.com
Lab Thực Hành
Triển khai ứng dụng web hoàn chỉnh trên Kubernetes với Minikube: Deployment 3 replicas, NodePort Service, ConfigMap, rolling update và rollback.
Khởi động Minikube
$ minikube start --cpus=2 --memory=2048
* Done! kubectl is now configured to use "minikube"
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 2m v1.31.0
Tạo Namespace và ConfigMap
$ kubectl create namespace webapp
$ kubectl create configmap web-config \
--from-literal=APP_ENV=staging \
--from-literal=APP_VERSION=v1.0 \
-n webapp
configmap/web-config created
Deploy Nginx với 3 replicas
---
apiVersion
: apps/v1kind
: Deploymentmetadata
:name: webapp
namespace: webapp
spec
:replicas: 3
selector:
matchLabels: {app: webapp}
template:
metadata:
labels: {app: webapp}
spec:
containers:
- name: webapp
image: nginx:1.26
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: web-config
---
apiVersion
: v1kind
: Servicemetadata
:name: webapp-svc
namespace: webapp
spec
:type: NodePort
selector: {app: webapp}
ports:
- port: 80
targetPort: 80
nodePort: 30090
$ kubectl apply -f webapp-deploy.yaml
deployment.apps/webapp created
service/webapp-svc created
$ kubectl get pods -n webapp
NAME READY STATUS RESTARTS AGE
webapp-6b9db8c5fd-2kl4p 1/1 Running 0 30s
webapp-6b9db8c5fd-8nzxj 1/1 Running 0 30s
webapp-6b9db8c5fd-r4tmw 1/1 Running 0 30s
Truy cập ứng dụng
$ minikube service webapp-svc -n webapp --url
http://192.168.49.2:30090
$ curl http://192.168.49.2:30090
<!DOCTYPE html>
<title>Welcome to nginx!</title>
Rolling Update lên nginx:1.27
$ kubectl set image deployment/webapp \
webapp=nginx:1.27 -n webapp
$ kubectl rollout status deployment/webapp -n webapp
deployment "webapp" successfully rolled out
$ kubectl rollout history deployment/webapp -n webapp
REVISION CHANGE-CAUSE
1 <none>
2 <none>
Scale và Dọn dẹp
$ kubectl scale deployment webapp --replicas=5 -n webapp
deployment.apps/webapp scaled
$ kubectl get pods -n webapp --watch
NAME READY STATUS RESTARTS AGE
webapp-... 1/1 Running 0 5m (x5)
# Dọn dẹp
$ kubectl delete namespace webapp
namespace "webapp" deleted
$ minikube stop
* Stopping node "minikube"...
Câu hỏi ôn tập
Pod trong Kubernetes là gì?
Deployment khác gì so với chạy pod trực tiếp?
Sự khác biệt giữa NodePort và LoadBalancer service types?
kubectl apply khác kubectl create như thế nào?
apply là best practice vì idempotent — chạy nhiều lần an toàn. Giữ track của "desired state" qua annotation. Dùng apply -f file.yaml cho workflow chuẩn.
Rolling update trong Kubernetes hoạt động như thế nào?
maxSurge (pods tạm thời thêm) và maxUnavailable (pods tạm thời unavailable).
ConfigMap dùng để làm gì trong Kubernetes?
envFrom: configMapRef); (2) Volume mounts (mount config file vào container). Cho phép thay đổi config mà không cần rebuild image.
Minikube là gì và tại sao dùng nó?
Lệnh kubectl rollout undo dùng để làm gì?
kubectl rollout undo deployment/<name> rollback deployment về revision trước. Nếu rolling update gây ra lỗi (pods crash, liveness probe fail), rollback về version đang hoạt động. Dùng --to-revision=N để rollback về revision cụ thể. Kubernetes giữ lịch sử rollout (revisionHistoryLimit, mặc định 10).
Helm là gì và chart là gì?
helm install, upgrade, uninstall là các lệnh chính.
Namespace trong Kubernetes phục vụ mục đích gì?
default (app), kube-system (K8s components), kube-public (public data).