Docker không phải Kubernetes thu nhỏ
Docker tooling build và chạy containers trên một engine/host; Kubernetes quản desired state của workloads trên cluster qua API/controllers. Kubernetes hiện không cần Docker Engine để chạy Pod.
1. Trách nhiệm khác nhau
| Concern | Docker/OCI | Kubernetes |
|---|---|---|
| Build | Dockerfile/BuildKit tạo OCI image | Không build image; pull image từ registry |
| Runtime | Docker Engine → containerd → runc | kubelet → CRI runtime như containerd/CRI-O → OCI runtime |
| Desired state | CLI/Compose trên một engine | API + controllers reconcile trên cluster |
| Network | Bridge/veth/DNS/NAT/published port | CNI Pod network, Service, EndpointSlice, Ingress/Gateway |
| Storage | Writable layer, bind mount, named volume | emptyDir, PV/PVC, StorageClass, CSI |
| Scaling/recovery | Manual/Compose restart policy | Deployment/StatefulSet/Job, scheduler, HPA, rescheduling |
| Security | Image/runtime user, capabilities, seccomp, rootless | Thêm RBAC, ServiceAccount, admission, policy, namespace/cluster controls |
2. Image tới process trong Pod
docker build / buildx
→ OCI manifest + config + layers
→ registry by tag/digest
→ kubelet observes assigned Pod
→ CRI ImageService pulls/unpacks image
→ CRI RuntimeService creates Pod sandbox + containers
→ OCI runtime configures namespaces/cgroups/mounts/seccomp
→ application becomes PID 1 inside container namespace
Kubernetes bỏ dockershim từ lâu; image do Docker build vẫn chạy vì tuân OCI image format. Docker Engine và containerd không đồng nghĩa: Engine dùng containerd, nhưng kubelet nói qua CRI implementation chứ không gọi Docker CLI/API.
3. Dockerfile contract trở thành Pod behavior
| Image/runtime choice | Ảnh hưởng trong Kubernetes |
|---|---|
| Exec-form ENTRYPOINT | PID 1 nhận SIGTERM đúng hơn khi Pod termination. |
App bind 0.0.0.0 | Service/other Pods truy cập được Pod IP; bind loopback chỉ trong Pod. |
| Non-root UID | Phải tương thích runAsNonRoot, volume ownership và port. |
| Writable paths | Phải khai báo emptyDir/PVC/tmpfs khi root filesystem read-only. |
| Health endpoint | Startup/readiness/liveness probes dùng được nhưng semantics phải đúng. |
| Multi-arch manifest | Node architecture pull đúng variant; sai platform gây exec format error. |
| Image digest | Immutable rollout/reproducibility; tag mutable gây version ambiguity. |
4. Compose không chuyển 1:1 sang Kubernetes
- Compose service thường map sang Deployment/StatefulSet + Service, nhưng lifecycle/identity/storage khác.
depends_onkhông trở thành startup ordering. Kubernetes giả định dependencies có thể restart; app cần retry/backoff/readiness.- Published port map sang Service/Ingress/Gateway, không phải
hostPortmặc định. - Named volume không tự map PVC; cần StorageClass/access mode/reclaim/backup/topology.
- Environment variables có thể map ConfigMap/Secret, nhưng secret lifecycle/rotation/RBAC cần thiết kế.
- Replicas yêu cầu stateless/shared state design; chỉ tăng replica không sửa local session/file state.
5. Resource limits: cùng kernel, khác scheduling layer
Docker runtime cgroups enforce CPU/memory/pids. Kubernetes thêm requests để scheduler đặt Pod và limits để runtime/cgroup enforce. CPU limit có thể throttle; memory limit có thể OOMKill. JVM memory gồm heap, metaspace, code cache, direct buffers, thread stacks và native/page cache.
resources:
requests: { cpu: "500m", memory: "768Mi" }
limits: { cpu: "1", memory: "1Gi" }
Request quá thấp tạo noisy neighbor/overpacking và HPA utilization sai; limit quá chặt tạo throttle/OOM. Tune từ workload và downstream capacity, không copy defaults.
6. Signals và termination timeline
Pod deletion / rollout
→ Endpoint readiness/removal bắt đầu hội tụ
→ preStop hook nếu có
→ SIGTERM tới container PID 1
→ app stop intake, drain in-flight, checkpoint
→ grace period hết thì SIGKILL
Endpoint propagation và proxy/LB connection draining không instant. App phải xử lý repeated/late requests và idempotency. preStop tiêu trong cùng terminationGracePeriodSeconds, không cộng thêm thời gian.
7. Networking mapping
| Docker concept | Kubernetes tương ứng gần nhất | Không tương đương ở đâu |
|---|---|---|
| User-defined bridge DNS | Pod network + CoreDNS + Service | Service là virtual stable frontend, không chỉ container name DNS. |
-p host:container | Service NodePort/LoadBalancer, Ingress/Gateway | K8s route qua cluster networking/controllers. |
| Container network namespace | Pod network namespace | Containers trong cùng Pod chia localhost/IP. |
| Docker network isolation | NetworkPolicy qua CNI | Policy enforcement phụ thuộc CNI; namespace không tự deny. |
8. Storage mapping
Container writable layer vẫn ephemeral. emptyDir sống theo Pod, không theo container restart nhưng mất khi Pod bị xóa/reschedule. PVC có lifecycle riêng và được CSI provision/attach/mount; access modes không tự chứng minh storage thật sự hỗ trợ concurrent application semantics. StatefulSet cho identity/order/PVC templates, không tự replicate database hoặc backup.
9. Security layers
- Supply chain: trusted base, pin digest, SBOM, scan/sign/provenance.
- Container: non-root, read-only, drop capabilities, seccomp, no privilege escalation.
- Pod/workload: ServiceAccount, securityContext, resource bounds.
- Cluster/API: RBAC, admission, audit, Secret encryption/external manager.
- Network/tenant: default-deny policies, namespace/cluster boundaries theo threat model.
10. Debug theo layer
- Image: digest/platform/config/user/entrypoint/file permissions.
- Runtime: container state, exit code, OOM, mounts, cgroups.
- Pod: init, probes, events, previous logs, security context.
- Scheduling: requests, taints, affinity, topology, PVC.
- Network: listener → Pod IP → EndpointSlice → Service → Ingress/Gateway/DNS.
- Controller: rollout conditions, ReplicaSet ownership, desired/available replicas.
- Application: request trace, pool/queue/downstream saturation và business invariant.