1. Cấu hình Horizontal Pod Autoscaler (HPA) cho Backstage và ArgoCD
Để đảm bảo hệ thống tự động mở rộng tài nguyên khi tải tăng, ta cần triển khai HPA dựa trên CPU và Memory. HPA sẽ tự động tăng số lượng Pod khi độ sử dụng vượt ngưỡng và giảm khi tải giảm.
Tạo file hpa-backstage.yaml tại thư mục /opt/idp/manifests/hpa/ với nội dung hoàn chỉnh dưới đây:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: backstage-hpa
namespace: idp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backstage
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
File này cấu hình Backstage chạy tối thiểu 2 Pod, tối đa 10 Pod, tự động scale khi CPU > 70% hoặc RAM > 80%.
Áp dụng cấu hình HPA cho Backstage:
kubectl apply -f /opt/idp/manifests/hpa/hpa-backstage.yaml
Hệ thống sẽ báo horizontalpodautoscaler.autoscaling "backstage-hpa" created nếu thành công.
Tương tự, tạo file hpa-argocd.yaml tại cùng thư mục cho ArgoCD:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: argocd-repo-server-hpa
namespace: argocd
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: argocd-repo-server
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
File này tập trung vào repo-server của ArgoCD vì đây là thành phần chịu tải lớn nhất khi clone/sync nhiều repo.
Áp dụng cấu hình HPA cho ArgoCD:
kubectl apply -f /opt/idp/manifests/hpa/hpa-argocd.yaml
Verify kết quả bằng lệnh sau để xem trạng thái hiện tại của HPA:
kubectl get hpa -n idp
kubectl get hpa -n argocd
Đầu ra phải hiển thị REPLICAS khớp với MIN hoặc MAX tùy theo tải thực tế, và UTILIZATION hiện thị phần trăm tài nguyên đang dùng.
2. Tối ưu hóa Cache và Database Query trong Backstage
Backstage sử dụng PostgreSQL để lưu trữ catalog và Redis để cache query. Khi số lượng thành phần tăng, query chậm sẽ gây tắc nghẽn. Cần cấu hình Redis để cache kết quả query và tối ưu hóa index của PostgreSQL.
Cập nhật file app-config.yaml của Backstage tại /opt/idp/backstage/app-config.yaml, thêm phần cache vào backend:
backend:
cache:
store: redis
connection:
host: redis-idp
port: 6379
password: ${REDIS_PASSWORD}
catalog:
rules:
- allow: [Component, System, API, Resource, Group, User]
providers:
# Cấu hình cache cho catalog
config:
rules:
- allow: [Component, System, API, Resource, Group, User]
entities:
- kind: Component
apiVersion: backstage.io/v1alpha1
metadata:
name: my-service
spec:
type: service
lifecycle: production
owner: group:my-team
router:
cache:
store: redis
ttl: 300
Đoạn cấu hình trên bật cache Redis cho backend và router, với TTL 300 giây để giảm tải cho DB khi load trang catalog.
Khởi động lại Backstage để áp dụng cấu hình cache:
kubectl rollout restart deployment backstage -n idp
Backstage sẽ khởi động lại và kết nối với Redis instance đã cấu hình.
Tối ưu hóa PostgreSQL bằng cách thêm Index cho các cột thường xuyên query trong bảng catalog_entities. Chạy lệnh truy vấn SQL trực tiếp vào Pod PostgreSQL:
kubectl exec -it -n idp postgres-0 -- psql -U backstage -d backstage -c "CREATE INDEX IF NOT EXISTS idx_catalog_entities_kind ON catalog_entities (kind);"
kubectl exec -it -n idp postgres-0 -- psql -U backstage -d backstage -c "CREATE INDEX IF NOT EXISTS idx_catalog_entities_owner ON catalog_entities (owner);"
kubectl exec -it -n idp postgres-0 -- psql -U backstage -d backstage -c "CREATE INDEX IF NOT EXISTS idx_catalog_entities_name ON catalog_entities (name);"
3 lệnh trên tạo index cho các trường Kind, Owner và Name, giúp giảm thời gian tìm kiếm từ O(N) xuống O(log N) khi lọc catalog.
Verify hiệu năng bằng cách chạy EXPLAIN ANALYZE trên query tìm kiếm catalog:
kubectl exec -it -n idp postgres-0 -- psql -U backstage -d backstage -c "EXPLAIN ANALYZE SELECT * FROM catalog_entities WHERE kind = 'Component' AND owner = 'group:my-team';"
Đầu ra phải hiển thị Index Scan thay vì Seq Scan, chứng tỏ index đã hoạt động.
3. Xử lý số lượng lớn tài nguyên và dự án trong Catalog
Khi catalog chứa hàng nghìn entity, Backstage có thể bị chậm do load toàn bộ danh sách. Cần cấu hình pagination (phân trang) và giới hạn số lượng entity trả về mỗi lần gọi API.
Cập nhật file app-config.yaml tại /opt/idp/backstage/app-config.yaml, thêm phần catalog để giới hạn số lượng:
catalog:
entities:
# Giới hạn số lượng entity trả về mỗi lần query
limit: 100
processing:
# Tăng thời gian timeout cho việc xử lý entity lớn
timeout: 60s
rules:
- allow: [Component, System, API, Resource, Group, User]
providers:
# Cấu hình để chỉ load metadata cần thiết, bỏ qua content lớn
config:
# ... (giữ nguyên cấu hình cũ)
# Thêm cấu hình optimization
processing:
timeout: 60s
Đoạn cấu hình giới hạn mỗi lần query chỉ trả về 100 entity và tăng timeout xử lý để tránh lỗi timeout với file YAML lớn.
Cấu hình Backstage Client (Frontend) để hỗ trợ pagination tự động. Chỉnh sửa file src/components/catalog/CatalogPage.tsx (nếu có tùy chỉnh) hoặc cấu hình trong app-config.yaml cho plugin catalog:
catalog:
display:
# Kích hoạt chế độ lazy loading
pagination:
enabled: true
pageSize: 50
Thiết lập pagination giúp frontend chỉ tải 50 entity mỗi lần, giảm đáng kể RAM và thời gian render trên trình duyệt.
Để xử lý số lượng lớn entity trong Git, sử dụng tính năng backstage-cli để tạo script scan và chỉ upload metadata cần thiết thay vì toàn bộ source code vào catalog:
cat > /opt/idp/scripts/scan-catalog.sh
Script này minh họa việc chỉ xử lý file metadata, tránh việc upload toàn bộ code vào hệ thống catalog.
Verify kết quả bằng cách truy cập Backstage UI, tìm kiếm một thành phần và kiểm tra xem danh sách có phân trang hay không:
# Kiểm tra log của backend khi truy cập API catalog
kubectl logs -f -n idp deployment/backstage | grep "GET /api/catalog"
Log phải hiển thị các request với query parameter ?limit=50&offset=0 chứng tỏ pagination đã hoạt động.
4. Cấu hình High Availability (HA) cho các thành phần quan trọng
Để đảm bảo hệ thống không bị downtime khi một node hoặc Pod gặp sự cố, cần cấu hình HA cho PostgreSQL, Redis và các service stateful của Backstage.
Đối với PostgreSQL, sử dụng Operator (như CloudNativePG hoặc Zalando Operator) để chạy 3 replica (1 Primary, 2 Replica). Nếu chưa có operator, cấu hình StatefulSet với 3 replica và Pod Anti-Affinity:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres-ha
namespace: idp
spec:
replicas: 3
serviceName: postgres-ha
selector:
matchLabels:
app: postgres-ha
template:
metadata:
labels:
app: postgres-ha
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- postgres-ha
topologyKey: kubernetes.io/hostname
containers:
- name: postgres
image: postgres:14-alpine
# ... (cấu hình volume, env, port)
File này cấu hình 3 Pod PostgreSQL trên 3 node khác nhau nhờ podAntiAffinity, đảm bảo nếu 1 node mất, 2 node còn lại vẫn chạy.
Đối với Redis, sử dụng Redis Sentinel hoặc Redis Cluster. Ở đây ta dùng Redis với 3 master và 3 slave (tổng 6 pod) để đảm bảo HA:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-ha
namespace: idp
spec:
replicas: 6
serviceName: redis-ha
selector:
matchLabels:
app: redis-ha
template:
metadata:
labels:
app: redis-ha
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis-ha
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7-alpine
command: ["redis-server"]
args: ["--appendonly yes", "--requirepass", "${REDIS_PASSWORD}"]
# ... (cấu hình volume)
File này đảm bảo Redis chạy phân tán trên các node, với requiredDuringScheduling để bắt buộc phân tán tuyệt đối.
Áp dụng các cấu hình HA cho PostgreSQL và Redis:
kubectl apply -f /opt/idp/manifests/ha/postgres-ha.yaml
kubectl apply -f /opt/idp/manifests/ha/redis-ha.yaml
Để kiểm tra tính sẵn sàng cao, mô phỏng sự cố bằng cách xóa một Pod ngẫu nhiên:
kubectl delete pod postgres-ha-0 -n idp
kubectl delete pod redis-ha-0 -n idp
Hệ thống Kubernetes sẽ tự động khởi tạo lại Pod mới trên node khác.
Verify kết quả bằng cách kiểm tra trạng thái Pod sau khi xóa:
kubectl get pods -n idp -l app=postgres-ha
kubectl get pods -n idp -l app=redis-ha
Đầu ra phải hiển thị 3 Pod PostgreSQL và 6 Pod Redis (hoặc số lượng theo cấu hình) với trạng thái Running sau vài giây, chứng tỏ HA hoạt động đúng.
Cuối cùng, kiểm tra Backstage vẫn hoạt động bình thường sau khi xóa Pod database:
curl -s -o /dev/null -w "%{http_code}" http://backstage-idp.idp.svc.cluster.local:7007/api/catalog/entities
Phản hồi 200 chứng minh dịch vụ không bị gián đoạn trong quá trình failover.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Internal Developer Platform (IDP) với Backstage, Crossplane và GitOps trên Kubernetes để tối ưu trải nghiệm phát triển phần mềm
« Phần 6: Tùy chỉnh trải nghiệm người dùng và bảo mật
Phần 8: Xử lý sự cố, giám sát và tips nâng cao »