Cuộc gọi lúc 2 giờ sáng: Tại sao Namespace là chưa đủ
Điện thoại của tôi bắt đầu reo inh ỏi lúc 2:14 sáng. PagerDuty báo cáo rằng toàn bộ cluster staging của chúng tôi đã ngừng hoạt động. Sau mười phút điều tra, tôi đã tìm ra thủ phạm: một lập trình viên từ đội Data Science đã chạy một job Spark yêu cầu 128 core mà không có bất kỳ giới hạn tài nguyên nào. Nó đã ngốn sạch mọi chu kỳ CPU hiện có, khiến các dịch vụ Frontend và API bị nghẽn cho đến khi sụp đổ hoàn toàn.
Vấn đề thực sự không chỉ là thiếu quota. Tôi đã cấp quyền quá rộng vì việc quản lý các vai trò RBAC riêng lẻ cho 15 nhóm khác nhau đang trở thành một công việc toàn thời gian. Tôi đã bị mắc kẹt trong “Địa ngục Namespace”. Các ranh giới quá lỏng lẻo, và một sai lầm nhỏ có thể nhấn chìm toàn bộ hệ thống.
Làm chủ multi-tenancy là một kỹ năng bắt buộc đối với các kỹ sư nền tảng (platform engineer). Bạn cần cung cấp một trải nghiệm giống như cloud, nơi các nhóm cảm thấy họ sở hữu môi trường của riêng mình, nhưng bạn vẫn duy trì được quyền kiểm soát phạm vi ảnh hưởng (blast radius). Capsule giúp điều này trở nên khả thi.
So sánh các phương pháp tiếp cận Multi-tenancy
Việc chọn chiến lược phù hợp phụ thuộc vào ngân sách và quy mô đội ngũ của bạn. Dưới đây là cách các phương pháp phổ biến nhất so với Capsule.
1. Phương pháp “Mỗi nhóm một Cluster”
Cách này mang lại khả năng cô lập tốt nhất nhưng lại làm thâm hụt ngân sách của bạn. Nếu bạn hỗ trợ 15 nhóm, bạn phải trả tiền cho 15 control plane và 15 bộ logging stack. Việc bảo trì là một cơn ác mộng. Nâng cấp lần lượt 15 cluster không phải là cách sử dụng thời gian hiệu quả.
2. Kubernetes Namespace tiêu chuẩn
Đây là cách tiếp cận mặc định, theo kiểu phẳng. Bạn tạo một namespace và gán một RoleBinding. Tuy nhiên, các namespace không thể được nhóm lại. Bạn không thể dễ dàng yêu cầu Kubernetes: “Nhóm cụ thể này chỉ được dùng tối đa 64GB RAM cho tổng cộng tất cả năm dự án của họ.” Đó là một trò chơi được ăn cả ngã về không.
3. Capsule (Operator quản lý “Tenant”)
Capsule thêm một lớp trừu tượng Tenant nằm trên các namespace. Nó nhóm các namespace thành một đơn vị quản trị duy nhất. Bằng cách sử dụng Admission Controller, nó chặn các lệnh gọi API để đảm bảo các nhóm luôn nằm trong phạm vi sandbox của họ. Người dùng không bao giờ cần đến quyền trên toàn cluster.
Ưu và nhược điểm khi sử dụng Capsule
| Ưu điểm | Nhược điểm |
|---|---|
Trải nghiệm Native: Các nhóm sử dụng kubectl tiêu chuẩn. Không cần học thêm CLI riêng của công cụ. |
Quản lý CRD: Bạn đang thêm nhiều Custom Resource Definition hơn vào cluster của mình. |
| Tổng hợp tài nguyên: Thiết lập giới hạn trên nhiều namespace (ví dụ: Nhóm A nhận tổng cộng 20 CPU). | Phụ thuộc Webhook: Nếu pod Capsule bị lỗi, người dùng có thể không tạo hoặc cập nhật được namespace. |
| Quản trị tự động: Tự động thực thi các hostname Ingress và danh sách trắng (whitelist) của registry. | Thiết lập OIDC: Việc tích hợp với các nhà cung cấp như Okta hoặc Keycloak đòi hỏi phải lập kế hoạch trước. |
Stack khuyến nghị cho môi trường Production
Đừng chỉ cài đặt operator rồi dừng lại ở đó. Một sandbox cấp độ production thực sự an toàn cần thêm một vài thành phần bổ trợ:
- Cert-Manager: Cần thiết để quản lý các chứng chỉ TLS được sử dụng bởi các admission webhook của Capsule.
- OIDC Provider (Dex/Keycloak): Ánh xạ trực tiếp các nhóm AD của công ty bạn tới các Tenant trong Capsule.
- Capsule Proxy: Tiện ích bổ sung thông minh này đảm bảo rằng khi người dùng chạy
kubectl get namespaces, họ chỉ thấy những namespace thuộc về mình.
Hướng dẫn triển khai: Xây dựng Sandbox
Hãy xây dựng một Tenant cho đội ‘Fintech’. Họ cần quyền tự do tạo namespace của riêng mình, nhưng chúng ta phải giới hạn họ ở mức 32GB RAM và một domain cụ thể của công ty.
Bước 1: Cài đặt Capsule qua Helm
Chúng ta sẽ bắt đầu bằng cách triển khai controller. Tôi giả định bạn đã có sẵn một cluster và đã cài đặt Helm.
# Thêm repository
helm repo add projectcapsule https://projectcapsule.github.io/charts
# Cập nhật và cài đặt
helm repo update
helm install capsule projectcapsule/capsule -n capsule-system --create-namespace
Bước 2: Định nghĩa Tenant
Đối tượng Tenant là trọng tâm của cấu hình. Manifest này định nghĩa các ranh giới nghiêm ngặt cho đội Fintech.
# fintech-tenant.yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: fintech-team
spec:
owners:
- name: [email protected]
kind: User
namespaceOptions:
quota: 10 # Alice có thể tạo tối đa 10 namespace
resourceQuotas:
- scope: Tenant
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
ingressOptions:
allowedHostnames:
allowedRegex: ".*\.fintech.mycompany.com"
limitRanges:
- limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "256Mi"
type: Container
Áp dụng cấu hình này bằng lệnh kubectl apply -f fintech-tenant.yaml. Alice hiện là chủ sở hữu chính thức của sandbox này.
Bước 3: Tạo Namespace với tư cách là Chủ sở hữu Tenant
Đây là nơi quy trình làm việc được cải thiện. Alice không cần quyền cluster-admin. Khi cô ấy yêu cầu một namespace mới, Capsule sẽ kiểm tra yêu cầu đó dựa trên giới hạn Tenant của cô ấy. Nếu hợp lệ, Capsule sẽ tạo namespace cho cô ấy.
Alice hiện có thể chạy:
kubectl create ns fintech-prod
kubectl create ns fintech-dev
Nếu cô ấy cố gắng tạo namespace thứ 11, Capsule sẽ từ chối yêu cầu. Nếu nhóm của cô ấy cố gắng triển khai một pod khiến tổng lượng bộ nhớ sử dụng lên đến 33Gi, API server sẽ chặn nó ngay lập tức.
Bước 4: Tự động hóa cô lập mạng
Kubernetes tiêu chuẩn cho phép tất cả các pod giao tiếp với nhau. Đó là một rủi ro bảo mật trong các thiết lập multi-tenant. Capsule có thể tự động chèn các Network Policy vào mọi namespace mới mà đội Fintech tạo ra.
# Thêm nội dung này vào spec của Tenant
networkPolicies:
items:
- policyTypes:
- Ingress
podSelector: {}
ingress:
- from:
- podSelector: {} # Chỉ cho phép lưu lượng truy cập từ trong cùng một tenant
Khắc phục các lỗi thường gặp
Nếu các namespace của bạn không xuất hiện, hãy kiểm tra log của Capsule trước. Sử dụng lệnh sau: kubectl logs -l app.kubernetes.io/instance=capsule -n capsule-system.
Hầu hết các lỗi bắt nguồn từ sự không khớp chứng chỉ giữa Kubernetes API và webhook của Capsule. Nếu bạn sử dụng CA tùy chỉnh, Capsule phải được cấu hình để tin cậy nó. Ngoài ra, hãy nhớ rằng Capsule quản lý định danh, không phải người dùng. Bạn vẫn cần một ClusterRoleBinding cơ bản cho phép người dùng thử tạo namespace; Capsule chỉ đơn giản đóng vai trò là người gác cổng phê duyệt hoặc từ chối hành động đó.
Lời kết
Việc hợp nhất các cluster phân mảnh của chúng tôi bằng Capsule đã cắt giảm hóa đơn AWS hàng tháng khoảng 4.200 USD—tiết kiệm được 40%. Quan trọng hơn, nó mang lại cho tôi sự an tâm. Tôi không còn lo lắng về việc một job Spark chạy sai làm sập các dịch vụ quan trọng. Bạn trao cho lập trình viên sự tự chủ mà họ khao khát, và bạn có được những rào chắn bảo vệ cần thiết để giữ cho hệ thống ổn định.

