Declarative API, ownership và admission
Kubernetes quản lý hệ thống bằng API objects: spec mô tả desired state, status phản ánh observed state, còn metadata mang identity, selection, concurrency, ownership và lifecycle. Hiểu object model giúp đọc manifest đúng và chẩn đoán controller/admission/deletion khi production có sự cố.
API Objects
Một object điển hình có apiVersion, kind, metadata và phần cấu hình theo resource. Người dùng hoặc automation gửi desired state vào API server; control plane liên tục reconcile actual state về desired state. Vì vậy, việc request được API server chấp nhận không đồng nghĩa workload đã sẵn sàng.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: prod
labels:
app: api
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: example/api:1.4.2
kubectl apply chỉ xác nhận write path thành công; readiness cần kubectl wait, rollout checks hoặc signal tương đương.Metadata
metadata.name nhận diện object trong scope của resource; metadata.uid phân biệt các incarnation có cùng tên. Namespace cung cấp scope cho namespaced resources, trong khi cluster-scoped resources không thuộc namespace.
| Field | Ý nghĩa vận hành | Điểm dễ sai |
|---|---|---|
name / uid | Tên dùng cho API path; UID là identity duy nhất của incarnation. | Đừng coi tên là bằng chứng cùng object sau delete/recreate. |
labels | Metadata nhận diện để select/group; dùng bởi selectors của Service, Deployment và tooling. | Selector overlap có thể làm controller nhận nhầm object. |
annotations | Non-identifying metadata cho tool/controller/integration. | Không dùng annotation như selector; tránh nhét secret hoặc payload không kiểm soát. |
generation | Thông thường tăng khi desired configuration có thay đổi mà API loại đó xem là thay đổi generation. | Không dùng như business sequence; semantics cụ thể phụ thuộc resource. |
resourceVersion | Version opaque của object/list phục vụ concurrency và watch. | Không parse hoặc dùng như timestamp/business sequence; client nên truyền lại value nhận từ API. |
managedFields | API server ghi field ownership cho Server-Side Apply và các managers. | Không chỉnh tay. |
Labels phù hợp cho query/select; annotations dành cho metadata không dùng để identify/select. Với read-modify-write, client cần xử lý conflict thay vì giả định object không đổi giữa GET và PUT. Với watches, hãy thiết kế reconnect/re-list theo API semantics thay vì lưu resourceVersion như một số tăng tuyến tính của domain.
Spec/status/conditions
spec thường do user, GitOps tool hoặc controller cấp cao hơn ghi để mô tả desired state. status thường do controller cập nhật để phản ánh trạng thái quan sát. Khi resource có conditions, mỗi condition nên truyền đạt một khía cạnh cụ thể như Available, Ready hoặc Progressing thay vì ép mọi trạng thái vào một phase duy nhất.
| Signal | Dùng để trả lời | Production note |
|---|---|---|
status.observedGeneration hoặc condition observedGeneration | Controller đã quan sát generation nào? | Nếu thấp hơn metadata.generation, status có thể còn stale. |
Condition type/status | Aspect cụ thể có True/False/Unknown? | Unknown khác False; automation phải phân biệt. |
reason/message | Tại sao condition đổi? | Dùng để debug, nhưng đừng build business contract dựa vào free-form message. |
Readiness automation nên kiểm tra condition/generation phù hợp với resource và có timeout rõ ràng. Một write thành công nhưng controller chết, RBAC thiếu, image pull fail hoặc dependency không sẵn sàng đều tạo khoảng thời gian mà desired state đã lưu nhưng observed state chưa đạt.
# Apply chỉ ghi desired state
kubectl apply -f deployment.yaml
# Chờ condition thay vì giả định apply = ready
kubectl wait --for=condition=Available deployment/api -n prod --timeout=120s
# Với Deployment, rollout status cung cấp kiểm tra rollout chuyên biệt
kubectl rollout status deployment/api -n prod --timeout=120s
Ownership and deletion
metadata.ownerReferences mô tả quan hệ owner/dependent để garbage collector xử lý lifecycle. Deletion propagation có ba kiểu quan trọng: background, foreground và orphan. Background xóa owner trước rồi cleanup dependents; foreground giữ owner ở trạng thái deleting trong khi dependents chặn deletion được xử lý; orphan giữ dependents lại.
metadata.finalizers là các key yêu cầu cleanup hoàn tất trước khi object bị xóa vật lý. Khi delete object có finalizer, API server đặt deletionTimestamp, object tiếp tục tồn tại và controller chịu trách nhiệm finalizer phải cleanup rồi remove key đó. Nếu controller chết, mất quyền, webhook/conversion hỏng hoặc external API không đáp ứng, object có thể kẹt ở trạng thái terminating.
Runbook khi object kẹt deletion
- Đọc
deletionTimestamp,finalizers,ownerReferencesvà Events. - Xác định controller/operator nào sở hữu finalizer; kiểm tra pod health, logs, leader election, RBAC và connectivity tới dependency.
- Kiểm tra dependent objects và deletion propagation; với custom resource, xác minh CRD/conversion webhook vẫn hoạt động.
- Sửa nguyên nhân và quan sát controller tự remove finalizer.
- Chỉ manual-remove sau khi có evidence rằng cleanup đã xong hoặc chấp nhận rõ hậu quả orphan/leak.
Admission and field management
Admission nằm trên API write path sau authentication/authorization và trước khi object được persist. Mutating admission có thể default/inject; validating admission hoặc policy có thể reject request. Một webhook chậm hoặc unreachable trực tiếp làm tăng write latency và, tùy failurePolicy, có thể chặn write hoặc fail-open.
| Thiết kế | Trade-off | Signal cần theo dõi |
|---|---|---|
failurePolicy: Fail | Bảo vệ policy khi webhook lỗi nhưng có thể làm API write unavailable. | Webhook errors/timeouts, rejection count, API request latency. |
failurePolicy: Ignore | Giữ availability nhưng policy có thể bị bypass khi webhook lỗi. | Fail-open count/audit, drift scan sau sự cố. |
| Timeout ngắn | Giảm blast radius trên request path. | p95/p99 latency, timeout rate, dependency latency. |
| Narrow matching | Giảm số request gọi webhook và giảm coupling. | Request volume theo resource/operation. |
Kubernetes admission webhook hỗ trợ timeoutSeconds; timeout dẫn tới xử lý theo failure policy. Khi policy phù hợp, ưu tiên cơ chế in-process/declarative có sẵn trước khi thêm external webhook, vì webhook thêm network hop và dependency vào control-plane write path.
Server-Side Apply và field managers
Server-Side Apply (SSA) để API server track field ownership trong metadata.managedFields. Nếu một apply cố đổi field đang do manager khác sở hữu với giá trị khác, request conflict thay vì silently overwrite. Có thể force conflict, nhưng khi đó ownership bị chuyển và thay đổi của actor khác có thể bị ghi đè.
kubectl apply --server-side \
--field-manager=platform-gitops \
-f deployment.yaml
# Chỉ dùng sau khi hiểu conflict và ownership intent
kubectl apply --server-side \
--field-manager=platform-gitops \
--force-conflicts \
-f deployment.yaml
--force-conflicts như retry mặc định.CRD/operators
CustomResourceDefinition (CRD) mở rộng Kubernetes API bằng custom resource. Operator/controller watch custom resource rồi reconcile domain-specific desired state. Production responsibility không dừng ở việc tạo YAML: cần schema validation, API versioning, conversion, status, finalizers, RBAC, upgrade compatibility và disaster recovery.
| Concern | Câu hỏi production |
|---|---|
| Versioning | Version nào served, version nào storage? Client cũ còn được hỗ trợ bao lâu? |
| Conversion | Schema khác nhau có cần conversion webhook? Webhook downtime có làm read/write/delete custom resource thất bại không? |
| Status/conditions | Controller công bố observed generation, readiness/degraded state và reason như thế nào? |
| Finalizer | External resources nào phải cleanup? Controller restart có idempotent không? |
| RBAC/security | Ai được create/update spec, ai được update status/finalizers? Secret có bị copy vào status/annotations không? |
| Upgrade | Stored objects được migrate thế nào? Rollback có đọc được object đã chuyển sang schema/version mới không? |
Conversion webhook là một dependency quan trọng: lỗi conversion có thể làm gián đoạn cả read và write đối với custom resources. Trước upgrade, test conversion theo cả hai hướng cần thiết, backup/restore representative objects, và đảm bảo storage-version migration không vượt quá rollback window.
Failure windows, capacity và security
- API availability: admission/conversion webhook, etcd pressure hoặc API server overload có thể làm writes chậm/thất bại dù workloads đang chạy.
- Controller lag: API object đã đổi nhưng reconcile queue/backoff/dependency làm status chậm; alert trên queue depth, reconcile latency/error và stale observed generation nếu controller expose metrics.
- Watch/re-list: client/controller phải chịu được disconnect, expired resource version và relist; không giả định watch là stream vĩnh viễn.
- Object growth: quá nhiều CRs, Events, annotations hoặc managed-fields churn có thể làm tăng API/etcd load; capacity test cần include list/watch/write rate và object size.
- Least privilege: tách quyền update spec, status, finalizers và webhook/CRD administration. Admission/conversion endpoints phải dùng TLS và authentication model phù hợp.
- Recovery: Git manifests không thay thế backup của cluster state/external systems. Khôi phục controller/operator phải tính đến idempotency, finalizer backlog và external-resource reconciliation.