Part 12 · Kubernetes · 12.1.07

PV, PVC, CSI và StatefulSet

Kubernetes orchestration giúp gắn storage vào workload nhưng không tự biến một database thành durable, replicated hay recoverable. Độ bền dữ liệu vẫn phụ thuộc storage backend, CSI driver, topology, replication của ứng dụng và quy trình backup/restore.

Mental model: Pod là compute có thể bị thay thế; PVC là yêu cầu storage của workload; PV là volume đã cấp; StorageClass mô tả cách cấp volume; CSI là giao diện để Kubernetes gọi storage system. StatefulSet thêm identity ổn định cho Pod, không thêm replication hay consensus cho dữ liệu.

1. Storage: persistent không có nghĩa là highly available

Volume có thể tồn tại lâu hơn vòng đời của một Pod, nhưng điều đó chỉ giải quyết một phần bài toán durability. Một disk đơn lẻ trong một zone vẫn có thể mất availability khi node, zone hoặc storage control plane gặp sự cố. Database chạy trên Kubernetes vẫn phải có chiến lược replication, quorum, backup, restore và failover phù hợp với RPO/RTO.

LớpKubernetes cung cấpKubernetes không tự bảo đảm
Pod / controllerReconcile số replica, restart/rescheduleApplication-level leader election, transaction durability
PV/PVCClaim/binding và lifecycle của storageBackend replication, corruption protection, backup
CSIChuẩn provision/attach/mount/snapshotMọi driver đều có cùng capability hay failure behavior
StatefulSetStable ordinal, DNS identity, per-Pod claimsData replication, consensus, shard placement logic

2. Provisioning model: PVC → StorageClass → PV → CSI

PVC mô tả capacity, access mode và StorageClass mà workload cần. Với dynamic provisioning, provisioner/CSI driver tạo PV phù hợp rồi control plane bind PVC với PV. Sau đó kubelet và CSI node plugin thực hiện attach/mount theo capability của backend.

volumeBindingMode ảnh hưởng trực tiếp đến scheduling. Immediate có thể provision volume trước khi biết Pod sẽ chạy ở đâu; với storage giới hạn theo zone, lựa chọn này có thể tạo mismatch topology. WaitForFirstConsumer trì hoãn binding/provisioning cho tới khi scheduler có đủ context về node/zone của Pod.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: zonal-ssd
provisioner: csi.example.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain
Failure window: Pod có thể ở Pending nếu không còn capacity/topology phù hợp; hoặc stuck ở attach/mount nếu volume còn gắn vào node cũ, CSI controller/node plugin lỗi, credential hết hạn hay backend storage degraded. Đừng chẩn đoán mọi lỗi storage như lỗi scheduler.

3. Access và lifecycle

Các access mode mô tả cách volume có thể được mount, không phải performance SLA và cũng không thay thế locking ở application.

ModeÝ nghĩa thực hànhLưu ý
RWORead/write từ một nodeNhiều Pod trên cùng node có thể vẫn dùng tùy volume/backend
ROXRead-only từ nhiều nodeKhông phù hợp workload cần ghi
RWXRead/write từ nhiều nodeCần filesystem/backend hỗ trợ và application xử lý concurrent writes
RWOPRead/write bởi một PodHữu ích khi cần single-writer semantics ở mức Pod với CSI hỗ trợ

Reclaim policy quyết định backend volume sau khi claim bị giải phóng. Delete thường xóa storage asset cùng PV; Retain giữ lại để admin kiểm tra/recover thủ công. Với dữ liệu quan trọng, policy phải là quyết định lifecycle có chủ ý, không chỉ dùng mặc định của StorageClass.

Volume expansion yêu cầu StorageClass cho phép mở rộng và driver/filesystem hỗ trợ; thông thường chỉ grow, không shrink. Finalizer và storage object protection ngăn xóa resource đang được sử dụng, nhưng cũng có thể khiến deletion chờ lâu khi dependency hoặc CSI path không hoàn tất.

4. StatefulSet: identity ổn định, không phải database operator

StatefulSet phù hợp workload cần tên ổn định, thứ tự/ordinal và storage riêng cho từng replica. volumeClaimTemplates tạo PVC theo từng Pod; Headless Service thường được dùng để peer discovery qua DNS. OrderedReady triển khai tuần tự, còn Parallel cho phép tạo/xóa Pod song song khi semantics của ứng dụng cho phép.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: store
spec:
  serviceName: store
  replicas: 3
  selector:
    matchLabels:
      app: store
  template:
    metadata:
      labels:
        app: store
    spec:
      containers:
      - name: store
        image: example/store:1.4
        volumeMounts:
        - name: data
          mountPath: /var/lib/store
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: zonal-ssd
      resources:
        requests:
          storage: 100Gi

StatefulSet không replicate dữ liệu, không elect leader và không hiểu quorum. Nếu replica store-0 chết, controller có thể tạo Pod mới với cùng identity/PVC, nhưng application vẫn phải quyết định dữ liệu có đủ mới hay không, node cũ đã được fence chưa và replica mới có thể tham gia cluster an toàn không.

PVC retention: mặc định PVC tạo từ volumeClaimTemplates được giữ lại khi StatefulSet bị xóa hoặc scale down. Kubernetes cũng có persistentVolumeClaimRetentionPolicy để thay đổi hành vi này; dùng Delete chỉ khi data lifecycle đã được hiểu rõ và có backup/recovery phù hợp.

5. Rolling update, fencing và failure window

Với stateful workload, rollout không chỉ là thay image. Một Pod mới có thể cần cùng volume, phải chờ detach/attach từ node cũ, replay WAL/log, rejoin quorum hoặc resync data. Nếu node cũ chỉ mất network nhưng vẫn ghi được vào disk, việc attach volume ở nơi khác mà không có fencing đúng có thể tạo split-brain hoặc corruption.

6. Backup và restore: snapshot không tự bằng backup

CSI VolumeSnapshot chuẩn hóa việc yêu cầu snapshot cho driver hỗ trợ. Snapshot đơn volume thường chỉ phản ánh trạng thái block/filesystem tại một thời điểm; nó không tự bảo đảm application-consistent cho database đang có write in flight. Cần phối hợp quiesce, flush/checkpoint, WAL/binlog hoặc cơ chế backup native của database khi consistency requirement đòi hỏi.

Backup cluster objects và backup data là hai lớp khác nhau. Muốn phục hồi workload thực sự, phải biết cách tái tạo namespace/config/secret references, PVC/StorageClass, data, DNS/service identity và application/schema version.

Cần chứng minhCâu hỏi kiểm tra
RPOMất tối đa bao nhiêu phút/giờ dữ liệu khi region/storage/account mất?
RTOTừ incident đến lúc service phục vụ bình thường mất bao lâu?
ConsistencySnapshot crash-consistent hay application-consistent? Multi-volume có cùng recovery point không?
IsolationBackup có nằm cùng failure domain/credential/account với primary không?
CompatibilityRestore đã test với đúng engine, schema và app version chưa?
Backup chưa restore-test thì chưa phải recovery plan. Theo dõi backup age/success là chưa đủ; cần restore drill định kỳ và bằng chứng dữ liệu/app có thể khởi động, reconcile và phục vụ đúng.

7. Capacity và operational signals

Stateful systems thường hết headroom trước khi “hết disk” hoàn toàn. Capacity plan nên bao gồm usable capacity sau replication, zone loss, snapshot/backup overhead, growth rate, resync/rebuild bandwidth và thời gian cần để mở rộng volume hoặc thêm shard/replica.

Alert nên dựa trên tốc độ tăng và time-to-exhaustion, không chỉ threshold tĩnh. Khi một zone/node/storage path mất, hệ thống vẫn phải còn capacity để reschedule, reattach và rebuild mà không đẩy các replica còn lại vào saturation.

8. Security và data protection

Storage chứa dữ liệu lâu hơn Pod nên blast radius của credential và misconfiguration lớn. Áp dụng least privilege cho Kubernetes RBAC và cloud/storage API, mã hóa in transit/at rest theo threat model, quản lý key/secret tách biệt, hạn chế ai được tạo StorageClass/snapshot/restore và audit các thao tác delete/retain/restore.

9. Khi nào nên dùng managed service?

Managed database thường giảm operational burden cho replication/quorum, patching, backup, failover, monitoring và upgrade. Chạy database/stateful middleware trong cluster hợp lý khi có requirement rõ về locality, custom engine/topology, portability, cost hoặc control — và đội ngũ thực sự có năng lực vận hành storage, consensus, backup/restore và incident recovery.

Câu hỏi quyết địnhNghiêng về managed serviceNghiêng về tự vận hành trong Kubernetes
Quorum/failoverMuốn provider chịu phần lớn burdenTeam hiểu sâu engine và failure modes
Backup/PITRCần capability tích hợp, tested workflowCó pipeline + restore drill riêng đáng tin cậy
UpgradeMuốn giảm patching/compatibility toilCần kiểm soát version/topology đặc thù
Portability/controlÍt quan trọng hơn reliability/toilLà requirement có giá trị đủ lớn
Production review checklist: storage topology/binding rõ; reclaim/retention có chủ ý; StatefulSet không bị nhầm với replication; fencing và rollout được test; capacity có zone-loss headroom; backup tách failure domain và restore-tested; security/credential lifecycle rõ; rollback bao gồm data/schema chứ không chỉ image.
Tài liệu: Kubernetes Storage · Persistent Volumes · Storage Classes · Volume Snapshots · StatefulSets