Thiết kế Cluster
Cluster Staging (3 node)
Cluster tối thiểu dành cho kiểm thử nội bộ, demo, và kiểm thử tích hợp.
| Node Pool | Số lượng | Cấu hình | Taint | Workload |
|---|---|---|---|---|
default | 2 | 4 vCPU, 8 GB | — | nginx-ingress, Traefik, backend, frontend, cert-manager, monitoring |
stateful | 1 | 8 vCPU, 16 GB | — | PostgreSQL, Redis, Kafka ×3, Typesense |
Staging giữ mọi thứ đơn giản — không có node riêng cho system hay monitoring. Mọi thứ ngoại trừ dữ liệu chạy trên node default. Tất cả dịch vụ dữ liệu (bao gồm 3 Kafka broker) chạy chung trên một node stateful duy nhất với bộ nhớ tăng cường. Triển khai thủ công qua kubectl apply -k.
Cluster Production (7+ node)
Cluster cấp production toàn diện với node pool riêng biệt, HA, autoscaling, và observability đầy đủ.
| Node Pool | Số lượng | Cấu hình | Taint | Workload |
|---|---|---|---|---|
system | 2 | 2 vCPU, 4 GB | dedicated=system:NoSchedule | nginx-ingress (HA), cert-manager, Sealed Secrets controller |
app | 3+ | 4 vCPU, 8 GB | — | Traefik, backend service, frontend app |
stateful | 2 | 8 vCPU, 16 GB | — | PostgreSQL, Redis, Kafka, Typesense |
monitoring | 1 | 4 vCPU, 8 GB | dedicated=monitoring:NoSchedule | Prometheus, Grafana, Loki, Tempo, OTel, Promtail |
Tại sao cần Node Pool Riêng biệt (Production)
- Node system (có taint): Ingress và cert-manager không bao giờ bị đẩy ra bởi workload ứng dụng. Taint đảm bảo chỉ pod system được lên lịch tại đây.
- Node monitoring (có taint): Stack observability tiêu tốn nhiều tài nguyên. Cô lập nó ngăn monitoring chiếm tài nguyên của ứng dụng (và ngược lại).
- Node app (có thể autoscale): Cluster autoscaler có thể thêm
app-4,app-5, v.v. khi lưu lượng tăng đột biến. Không rủi ro mở rộng node chứa dữ liệu stateful. - Node stateful: Dành riêng cho dịch vụ dữ liệu. Pod anti-affinity phân tán Kafka broker trên cả hai node để đảm bảo chịu lỗi.
Label & Taint của Node
System nodes
# System nodes
node.kubernetes.io/pool: system
taint: dedicated=system:NoSchedule
# App nodes
node.kubernetes.io/pool: app
# Stateful nodes
node.kubernetes.io/pool: stateful
# Monitoring node
node.kubernetes.io/pool: monitoring
taint: dedicated=monitoring:NoSchedulePhân bổ Node Stateful
Staging — một node duy nhất, tất cả dữ liệu chạy chung:
Production — phân tán trên 2 node để đảm bảo chịu lỗi:
Chiến lược Namespace
Cả hai cluster sử dụng cùng 7 namespace:
| Namespace | Mục đích | Nội dung |
|---|---|---|
nx-internal | Hạ tầng | nginx-ingress, Traefik (API gateway), cert-manager, API Portal |
nx-backend | Workload backend | Tất cả backend service |
nx-app | Workload frontend | Frontend nginx pod (client, bo, overture, sale-renderer, wiki) |
nx-persistent | Cơ sở dữ liệu | PostgreSQL primary + replica, PgBouncer |
nx-broker | Message broker & cache | Redis Cluster, Kafka KRaft |
nx-search | Tìm kiếm & CDC | Typesense, Debezium |
nx-watcher | Stack observability | (chưa triển khai) |
YAML Namespace
Namespace: nx-internal
apiVersion: v1
kind: Namespace
metadata:
name: nx-internal
labels:
app.kubernetes.io/part-of: bana
---
apiVersion: v1
kind: Namespace
metadata:
name: nx-backend
labels:
app.kubernetes.io/part-of: bana
---
apiVersion: v1
kind: Namespace
metadata:
name: nx-app
labels:
app.kubernetes.io/part-of: bana
---
apiVersion: v1
kind: Namespace
metadata:
name: nx-persistent
labels:
app.kubernetes.io/part-of: bana
---
apiVersion: v1
kind: Namespace
metadata:
name: nx-broker
labels:
app.kubernetes.io/part-of: bana
---
apiVersion: v1
kind: Namespace
metadata:
name: nx-search
labels:
app.kubernetes.io/part-of: bana
---
apiVersion: v1
kind: Namespace
metadata:
name: nx-watcher
labels:
app.kubernetes.io/part-of: banaPhân bổ Tài nguyên
Workload Ứng dụng (node default/app)
| Workload | Bản sao (staging) | Bản sao (prod) | CPU yêu cầu | CPU giới hạn | Mem yêu cầu | Mem giới hạn |
|---|---|---|---|---|---|---|
| traefik | 1 | 2 | 100m | 1 | 128Mi | 512Mi |
| identity | 1 | 2 | 200m | 2 | 256Mi | 1Gi |
| commerce | 1 | 1 | 200m | 2 | 256Mi | 1Gi |
| sale | 1 | 2 | 200m | 2 | 256Mi | 1Gi |
| finance | 1 | 1 | 200m | 2 | 256Mi | 1Gi |
| inventory | 1 | 1 | 200m | 2 | 256Mi | 1Gi |
| ledger | 1 | 1 | 200m | 2 | 384Mi | 1Gi |
| pricing | 1 | 1 | 200m | 2 | 320Mi | 1Gi |
| payment-api | 1 | 2 | 200m | 2 | 256Mi | 1Gi |
| payment-worker | 1 | 1 | 100m | 1 | 256Mi | 1Gi |
| signal | 1 | 2 | 100m | 1 | 256Mi | 512Mi |
| client | 1 | 1 | 50m | 500m | 64Mi | 256Mi |
| bo | 1 | 1 | 50m | 500m | 64Mi | 256Mi |
| overture | 1 | 1 | 50m | 500m | 64Mi | 256Mi |
| sale-renderer | 1 | 1 | 50m | 500m | 64Mi | 256Mi |
| wiki | 1 | 1 | 50m | 500m | 64Mi | 256Mi |
Workload Dữ liệu (node stateful)
| Workload | Số lượng | CPU yêu cầu | Mem yêu cầu | Lưu trữ |
|----------|-----------|---------|---------|---------|
| PG Primary | 1 | 500m | 1Gi | 20Gi |
| PG Replica | 1 | 250m | 512Mi | 20Gi |
| PgBouncer | 1 | 100m | 256Mi | - |
| Redis | 3 | 300m | 1.125Gi | 15Gi |
| Kafka | 3 | 1.5 CPU | 3.75Gi | 30Gi |
| Typesense | 1 | 200m | 512Mi | 5Gi |
| Debezium | 1 | 250m | 512Mi | - || Workload | Số lượng | CPU yêu cầu | Mem yêu cầu | Lưu trữ |
|----------|-----------|---------|---------|---------|
| PostgreSQL (CNPG) | 3 (1 primary + 2 replica) | 1.5 CPU | 3Gi | 60Gi + 15Gi WAL |
| Redis + Sentinel | 3 + 3 | 750m | 1.7Gi | 15Gi |
| Kafka (Strimzi) | 3 | 1.5 CPU | 3.75Gi | 30Gi |
| Typesense (raft) | 3 | 600m | 1.5Gi | 15Gi |Xem Tầng Dữ liệu để biết chi tiết cấu hình operator, cơ chế failover, và chiến lược backup.
Phân bổ Lưu trữ
| PVC | Staging | Production |
|---|---|---|
pg-data | 20Gi (×1) | 20Gi (×3) + 5Gi WAL (×3) |
redis-data | 5Gi (×1) | 5Gi (×3) |
kafka-data | 10Gi (×3) | 10Gi (×3) |
typesense-data | 5Gi (×1) | 5Gi (×3) |
prometheus-data | 10Gi | 10Gi |
grafana-data | 5Gi | 5Gi |
loki-data | 5Gi | 5Gi |
tempo-data | — | 10Gi |
| Tổng cộng | 80Gi | 170Gi |
Quản trị Tài nguyên
ResourceQuota
Mỗi namespace có ResourceQuota để ngăn workload vượt kiểm soát tiêu thụ hết tài nguyên cluster.
nx-backend — namespace lớn nhất (tất cả dịch vụ backend)
# nx-backend — namespace lớn nhất (tất cả dịch vụ backend)
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-backend-quota
namespace: nx-backend
spec:
hard:
requests.cpu: "12"
requests.memory: 16Gi
limits.cpu: "24"
limits.memory: 32Gi
pods: "30"
---
# nx-app — ứng dụng frontend (pod nginx nhẹ)
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-app-quota
namespace: nx-app
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
limits.cpu: "4"
limits.memory: 8Gi
pods: "12"
---
# nx-persistent — PostgreSQL + PgBouncer
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-persistent-quota
namespace: nx-persistent
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "8"
persistentvolumeclaims: "10"
---
# nx-broker — Redis + Kafka
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-broker-quota
namespace: nx-broker
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 12Gi
pods: "12"
persistentvolumeclaims: "12"
---
# nx-search — Typesense + Debezium
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-search-quota
namespace: nx-search
spec:
hard:
requests.cpu: "1"
requests.memory: 2Gi
limits.cpu: "2"
limits.memory: 4Gi
pods: "4"
---
# nx-internal — nginx-ingress, Traefik, cert-manager, API Portal
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-internal-quota
namespace: nx-internal
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
limits.cpu: "4"
limits.memory: 8Gi
pods: "6"
---
# nx-watcher — stack observability (chưa triển khai)
apiVersion: v1
kind: ResourceQuota
metadata:
name: nx-watcher-quota
namespace: nx-watcher
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
limits.cpu: "4"
limits.memory: 8Gi
pods: "8"LimitRange
LimitRange đặt request/limit mặc định cho container không khai báo, và áp dụng giới hạn min/max.
Mặc định cho nx-backend
# Mặc định cho nx-backend
apiVersion: v1
kind: LimitRange
metadata:
name: nx-backend-limits
namespace: nx-backend
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
min:
cpu: 50m
memory: 64Mi
max:
cpu: "2"
memory: 2Gi
---
# Mặc định cho nx-app (giới hạn nhẹ hơn cho frontend nginx)
apiVersion: v1
kind: LimitRange
metadata:
name: nx-app-limits
namespace: nx-app
spec:
limits:
- type: Container
default:
cpu: 200m
memory: 256Mi
defaultRequest:
cpu: 50m
memory: 64Mi
min:
cpu: 25m
memory: 32Mi
max:
cpu: "1"
memory: 1Gi
---
# Mặc định cho nx-broker
apiVersion: v1
kind: LimitRange
metadata:
name: nx-broker-limits
namespace: nx-broker
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 768Mi
defaultRequest:
cpu: 200m
memory: 256Mi
min:
cpu: 100m
memory: 128Mi
max:
cpu: "2"
memory: 2Gi
---
# Mặc định cho nx-persistent
apiVersion: v1
kind: LimitRange
metadata:
name: nx-persistent-limits
namespace: nx-persistent
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 1Gi
defaultRequest:
cpu: 250m
memory: 512Mi
min:
cpu: 100m
memory: 256Mi
max:
cpu: "2"
memory: 4Gi
---
# Mặc định cho nx-search
apiVersion: v1
kind: LimitRange
metadata:
name: nx-search-limits
namespace: nx-search
spec:
limits:
- type: Container
default:
cpu: 200m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 256Mi
min:
cpu: 50m
memory: 128Mi
max:
cpu: "1"
memory: 2Gi
---
# Mặc định cho nx-internal
apiVersion: v1
kind: LimitRange
metadata:
name: nx-internal-limits
namespace: nx-internal
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
min:
cpu: 50m
memory: 64Mi
max:
cpu: "2"
memory: 2Gi
---
# Mặc định cho nx-watcher
apiVersion: v1
kind: LimitRange
metadata:
name: nx-watcher-limits
namespace: nx-watcher
spec:
limits:
- type: Container
default:
cpu: 200m
memory: 256Mi
defaultRequest:
cpu: 50m
memory: 64Mi
min:
cpu: 25m
memory: 32Mi
max:
cpu: "1"
memory: 1GiTIP
LimitRange áp dụng cho pod không khai báo tài nguyên rõ ràng. Tất cả workload BANA đều khai báo tài nguyên, nên LimitRange đóng vai trò mạng lưới an toàn cho pod debug hoặc job ad-hoc.
Cấu trúc Thư mục Manifest
Triển khai thực tế sử dụng các thư mục manifest được đánh số, áp dụng tuần tự bằng kubectl apply -f, không dùng Kustomize overlay.
infrastructure/deployments/staging/
├── 00-cluster-setup/ # Namespace, ResourceQuota, LimitRange
├── 01-network-policies/ # NetworkPolicy cho từng namespace
├── 02-persistent/ # PostgreSQL, PgBouncer StatefulSet & Service
├── 03-broker/ # Redis Cluster, Kafka KRaft StatefulSet
├── 04-search/ # Typesense, Debezium
├── 05-internal/ # nginx-ingress, Traefik, cert-manager, API Portal
├── 06-backend/ # Tất cả backend service Deployment & Service
├── 07-app/ # Frontend nginx Deployment (client, bo, overture, v.v.)
├── 08-watcher/ # Stack observability (chưa triển khai)
├── 09-jobs/ # Job chạy một lần (DDL migration, seed, Kafka topic init)
└── kc # Script wrapper kubectl (thiết lập kubeconfig)Triển khai
# Áp dụng tất cả manifest theo thứ tự
for dir in 00-* 01-* 02-* 03-* 04-* 05-* 06-* 07-*; do
./kc apply -f "$dir/"
doneProduction (dự kiến)
- Áp dụng taint cho system + monitoring
- nginx-ingress HA (2 bản sao trên node system)
- Traefik HA (2 bản sao trên node app)
- HPA cho các dịch vụ quan trọng (identity, sale, payment-api, signal)
- PodDisruptionBudget (minAvailable: 1 cho các dịch vụ HA)
- topologySpreadConstraints + podAntiAffinity
- Triển khai qua pipeline GitLab CI/CD