Part 12 · Kubernetes · 12.1.02

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
Mental model: write object → authentication/authorization/admission → persist → watch/reconcile → controller cập nhật status. 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 / uidTê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.
labelsMetadata 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.
annotationsNon-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.
generationThô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.
resourceVersionVersion 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.
managedFieldsAPI 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 GETPUT. 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.

SignalDùng để trả lờiProduction note
status.observedGeneration hoặc condition observedGenerationController đã quan sát generation nào?Nếu thấp hơn metadata.generation, status có thể còn stale.
Condition type/statusAspect cụ thể có True/False/Unknown?Unknown khác False; automation phải phân biệt.
reason/messageTạ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.

Không xóa finalizer mù. Việc force-remove có thể bỏ qua cleanup external resource, để lại cloud load balancer, volume, DNS record hoặc child resource bị orphan. Chỉ remove khi đã hiểu invariant và hoàn tất cleanup bằng cách khác.

Runbook khi object kẹt deletion

  1. Đọc deletionTimestamp, finalizers, ownerReferences và Events.
  2. 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.
  3. Kiểm tra dependent objects và deletion propagation; với custom resource, xác minh CRD/conversion webhook vẫn hoạt động.
  4. Sửa nguyên nhân và quan sát controller tự remove finalizer.
  5. 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-offSignal cần theo dõi
failurePolicy: FailBả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: IgnoreGiữ availability nhưng policy có thể bị bypass khi webhook lỗi.Fail-open count/audit, drift scan sau sự cố.
Timeout ngắnGiảm blast radius trên request path.p95/p99 latency, timeout rate, dependency latency.
Narrow matchingGiả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
Ownership rule: phân chia field ownership theo workflow rõ ràng. Ví dụ GitOps quản image/template, HPA quản replicas. Đừng để nhiều automation cạnh tranh cùng field rồi dùng --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.

ConcernCâu hỏi production
VersioningVersion nào served, version nào storage? Client cũ còn được hỗ trợ bao lâu?
ConversionSchema 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/conditionsController công bố observed generation, readiness/degraded state và reason như thế nào?
FinalizerExternal resources nào phải cleanup? Controller restart có idempotent không?
RBAC/securityAi được create/update spec, ai được update status/finalizers? Secret có bị copy vào status/annotations không?
UpgradeStored 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

Review checklist: object identity và selectors rõ; readiness dựa trên status/conditions chứ không dựa trên apply success; deletion có owner/finalizer runbook; admission có timeout/failure policy/metrics; SSA có ownership map; CRD có version/conversion/status/finalizer/RBAC/rollback plan.
Tài liệu chính thức: Kubernetes Objects · API Concepts · Labels · Annotations · Finalizers · Garbage Collection · Dynamic Admission Control · Server-Side Apply · Custom Resources · CRD Versioning