1. Các mô hình triển khai dịch vụ trong Kubernetes
1.1 Phân loại mô hình triển khai dịch vụ
- Truy cập từ người dùng
- Giao tiếp giữa các dịch vụ nội bộ
- Truy cập các thành phần hạ tầng (database, cache...)
1.2 Thiết kế kiến trúc không có registry trung tâm
Không sử dụng registry, các client tìm và kết nối trực tiếp tới Pod thông qua Service và DNS.
1.3 Thiết kế kiến trúc có registry trung tâm
Sử dụng registry (như etcd, Consul) để đăng ký/danh mục dịch vụ, giúp quản lý động các endpoint.
1.4 Cơ chế Proxy của Service
Label là cặp key/value gắn vào resource để tổ chức, phân loại các đối tượng (Pod, Deployment, Node...). Ví dụ: app=frontend, region=subnet7.
Selector cho phép truy vấn các resource có label phù hợp qua các biểu thức logic như app in (frontend, backend), env!=prod,...
1.5 Khái niệm Service
Service là một abstract layer đại diện cho một nhóm các Pod có cùng chức năng, đảm bảo endpoint tĩnh ngay cả khi Pod restart, scale hoặc di chuyển.
Tính năng chính:
- Service Discovery (qua DNS hoặc biến môi trường)
- Load balancing nội bộ
- Support port mapping & session persistence
1.6 Endpoints
Endpoints là resource lưu trữ danh sách IP + port của các Pod được Service selector chọn. Khi Pod thay đổi, controller cập nhật tự động Endpoints.
Service và Endpoints liên kết khi:
- Cùng名称 service name và namespace
- Đủ thông tin port matching
2. Quản lý East-West traffic qua Service
2.1 Label & Selector nâng cao
Thêm label
kubectl label deployment nginx version=1
# Thêm nhiều label trên tất cả deployment trong namespace
kubectl label deployment --all env=prod tier=v2
# Thêm label có điều kiện
kubectl label service -l app=inventory secure=true
# Thêm nhiều nhãn đồng thời
kubectl label pod app=web appVer=2.0 tier=cache --overwrite
Sửa & xóa label
# Ghi đè label đã tồn tại phải dùng --overwrite
kubectl label deploy nginx version=2 --overwrite
# Xóa nhãn: thêm dấu "-" sau key
kubectl label node k8s-node01 region-
#####Selector mẫu
(app=nginx)→ chỉ service có label app=nginxapp in (nginx,counter)→ chọn nhiều giá trịapp in (nginx,counter), version!=2→ lọc phức tạp hơn
Ứng dụng bài toán network isolation
Giả sử yêu cầu chỉ giao tiếp với ngân hàng qua subnet 192.168.7.0/24 → gắn node label:
kubectl label node k8s-node02 region=subnet7
# Deployment yêu cầu node selector
spec:
template:
spec:
nodeSelector:
region: subnet7
2.2 Định nghĩa Service
# Tạo Service từ Deployment sẵn
kubectl expose deploy nginx --port=80 --target-port=8080
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80 # Cổng ClusterIP thấy được
targetPort: 80 # Cổng Pod cần nhận
protocol: TCP
type: ClusterIP
- Nếu
targetPortbỏ trống → tự động bằngport targetPortcó thể là tên port định nghĩa trong container → giữ vững khi cập nhật image
2.3 Các loại Service
| Loại | Mô tả | 适用场景 |
|---|---|---|
| ClusterIP | Mặc định, chỉ truy cập trong cluster | Internal service, DB, cache... |
| NodePort | Mở port 30000~32767 trên mỗi node | Dev/test, API exposed đơn giản |
| LoadBalancer | Sam với cloud LoadBalancer (AWS GCP...) | Production cần load-balancing cấp độ hạ tầng |
| ExternalName | Trả về CNAME → trỏ sang DNS bên ngoài | Truy cập service bên ngoài cluster |
2.4 Thực hành NodePort Service
kubectl expose deploy nginx --type=NodePort --port=80 --target-port=80
kubectl get svc nginx
# output: 80:31532/TCP
2.5 ExternalName Service
# ExternalName mẫu
apiVersion: v1
kind: Service
metadata:
name: external-dbf
spec:
type: ExternalName
externalName: db.prod.internal.svc.cluster.local
Ứng dụng quản lý nhiều môi trường chung config
- Dev: Redis trong namespace
basic-dev - UAT: Redis trong namespace
basic-uat
# Service proxy trong namespace projecta-dev
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: projecta-dev
spec:
type: ExternalName
externalName: redis.basic-component-dev.svc.cluster.local
---
# مشروع aUAT
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: projecta-uat
spec:
type: ExternalName
externalName: redis.basic-component-uat.svc.cluster.local
Từ ứng dụng clockwise: redis:6379 → tự chuyển tới môi trường tương ứng.
2.6 Service đại diện external service (không có selector)
apiVersion: v1
kind: Service
metadata:
name: external-baidu
spec:
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-baidu
subsets:
- addresses: [{ip: "182.61.201.211"}]
ports: [{port: 80}]
Các IP không được là loopback, link-local hay multicast.
2.7 Service đa cổng (multi-port)
# RabbitMQ: AMQP (5672),Management (15672)
spec:
ports:
- name: amqp
port: 5672
targetPort: 5672
- name: mgmt
port: 15672
targetPort: 15672
2.8 Session persistence
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
2.9 Headless Service (ไม่ม ClusterIP)
spec:
clusterIP: None
selector:
app: redis-stateful
DNS trả pod hostname dạng <pod-name>.<service>.<namespace>.svc.cluster.local
Ứng dụng:
- StatefulSet (Database, Kafka, Zookeeper…)
- Yêu cầu kết nối trực tiếpPod
- Mô hình mpich no central scheduler
Ví dụ tạo Headless Service:
kubectl create -f headless.yaml
# Output Service: clusterIP = None
# Tạo pod: headless-0, headless-1, headless-2
# Kiểm tra DNS
nslookup headless-1.headless.default.svc.cluster.local
# → trả về IP cụ thể của Pod
2.10 Các chế độ proxy của kube-proxy
Iptables mode
kube-proxytheo dõi API server, tự động cập nhật rule iptables- nodes xử lý load-balance nội tại
Ưu điểm:
- Không cần daemon riêng, hiệu quả giai đoạn đầu
- Tích hợp sẵn trên Linux
Hạn chế:
- Scaling kém khi số service lớn → rule iptables tăng tuyến tính
- Rebuild rule gây lag ngắn
IPVS mode (khuyến nghị production Scale cao)
- Dùng🐇 kernel modules:
ip_vs,ip_vs_rr,ip_vs_wrr,...
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
Các thuật toán:
- rr (round-robin)
- lc (least-connection)
- sh (source-address hash → session affinity)
- sed (shortest-exp-delay)
- nq (never-queue)
Ưu điểm:
- Thời gian truy suất O(1) nhờ cấu trúc hash-table
- Hỗ trợ server health check nâng cao
- Không khởi tạo lại toàn bộ rule khi thay đổi
3. Quản lý North-South traffic qua Ingress
3.1 Ingress là gì?
Ingress là resource API định nghĩa rules routing HTTP/HTTPS truy cập vào service bên trong cluster.
Ingress Controller: thực thi logic routing (Nginx, Traefik, HAProxy, Istio).
Các chức năng:
- HTTP(S) routing theo hostname/path
- TLS termination
- Basic / OAuth2 auth
- Rate-limiting, black/white-listing
- Canary / blue-green deployment
- Rewriting, redirect, retry-policy
3.2 Cài đặt Ingress Controller thực tế
Sử dụng DaemonSet trên dedicated worker node:
spec:
template:
spec:
nodeSelector:
ingress: "true"
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
Gán label node:
kubectl label node k8s-node02 ingress=true
kubectl apply -f ingress-nginx-daemonset.yaml
3.3 Cấu trúc Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts: ["app.example.com"]
secretName: app-tls-secret
rules:
- host: "app.example.com"
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080
pathType:
Exact: khớp danh sách path chính xác →/api≠/api/Prefix: khớp tiền tố/abcsẽ khớp/abc/xImplementationSpecific: ứng xử tùy controller (mặc định trước v1.18)
3.4 Hướng dẫn thực hành Ingress
3.4.1 Ví dụ basic routing
kubectl create deploy nginx --image=nginx:1.15 --replicas=2
kubectl expose deploy nginx --port=80
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
spec:
rules:
- host: demo.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
Cập nhật /etc/hosts → truy cập http://demo.local
3.4.2 HTTPS rate-limit user-auth
# Generate self-signed cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=demo.local"
kubectl create secret tls demo-tls --cert=tls.crt --key=tls.key
# Ingress HTTPS + basic auth
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/limit-rps: "10"
spec:
rules:
- host: demo.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
tls:
- hosts: ["demo.local"]
secretName: demo-tls
3.4.3 Stripping prefix & rewrite
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: api.example.com
http:
paths:
- path: /service(/|$)(.*)
pathType: Prefix
backend:
service:
name: service-svc
port:
number: 8080
URL https://api.example.com/service/users/123 → backend nhận /users/123
3.4.4 Ví dụ stream (SSE, gRPC)
annotations:
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
3.4.5 Redirect và Rewrite
# Redirect 308
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: https://newsite.com
nginx.ingress.kubernetes.io/permanent-redirect-code: "308"
3.4.6 Thanh toán điều kiện IP (whitelist/blacklist)
# Blacklist cụ thể
annotations:
nginx.ingress.kubernetes.io/denylist-source-range: "10.20.0.0/16,192.168.1.1"
# Whitelist toàn cluster
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8"
Cấu hình global qua ConfigMap ingress-nginx-controller:
data:
denylist-source-range: "192.168.100.0/24"
whitelist-source-range: "10.0.0.0/8"
3.4.7 Custom error page
# Deploy default backend server
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-error
spec:
template:
spec:
containers:
- image: your-registry/custom-error-pages:v1.0
ports:
- containerPort: 8080
Cấu hình controller args:
args:
- --default-backend-service=ingress-nginx/custom-error
ConfigMap:
data:
custom-http-errors: "404,502,503"
3.4.8 Phân luồng theo User-Agent (Mobile/Desktop)
# laptop web
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
set $isMobile 0;
if ($http_user_agent ~* "Mobile|Android|iPhone") {
set $isMobile 1;
}
if ($isMobile = 1) {
return 302 http://m.example.com;
}
3.4.9 Canaryblue-green deployment
Canary qua annotation:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% traffic tới v2
Ví dụ:
v1deployments ởproduction/nsv2(canary) ởcanary/ns
Tạo Ingress cho v1, sau đó tạo v2 có canary-weight.
Kiểm tra bằng script:
(0..200).each do |i|
r = `curl -s http://canary.local/`
puts r.include?("v2") ? "2" : "1"
end | sort | uniq -c
4. Chẩn đoán sự cố Ingress
| ErrorCode | Nguyên nhân | Giải pháp |
|---|---|---|
| 404 | Domain/path không tồn tại trong Ingress | Kiểm tra kubectl get ingress -A, kubectl describe ingress |
| 413 | Body quá lớn (upload) | Set nginx.ingress.kubernetes.io/proxy-body-size: 64m |
| 502/503 | Backend dịch vụ không khả dụng | Kiểm tra pod status, service endpoint, kubectl get ep |
| 504 | Gateway timeout | Tăng proxy-read-timeout qua annotation |
| CORS errors | Thiếu header access-control-* | Khai báo nginx.ingress.kubernetes.io/cors-allow-origin |