Giao diện
Container Runtime & Networking: Sự thật về "Docker is Dead"
"Container không phải là máy ảo. Nó chỉ là những process nói dối hệ điều hành."
Nếu bạn từng hoang mang khi nghe tin "Kubernetes khai tử Docker" (Dockershim deprecation), hãy bình tĩnh. Docker không chết, nó chỉ không còn là "thành phần đặc quyền" duy nhất trong Kubernetes nữa.
Chào mừng đến với kỷ nguyên của CRI (Container Runtime Interface) và CNI (Container Network Interface).
1. Sự thật về "Docker is Dead" & CRI
Dockershim là gì và tại sao nó bị khai tử?
Ngày xưa (trước v1.24), Kubernetes buộc phải viết một đoạn code cầu nối gọi là dockershim để nói chuyện được với Docker. Tại sao? Vì Docker sinh ra không phải để dành riêng cho Kubernetes.
- Kubernetes nói: "CRI".
- Docker nói: "Docker API". ->
kubeletphải gánh thêmdockershimđể phiên dịch. Điều này cồng kềnh và khó bảo trì.
CRI (Container Runtime Interface)
Kubernetes chuẩn hóa việc giao tiếp với runtime thông qua giao diện CRI. Bất kỳ runtime nào implement đúng chuẩn CRI đều có thể chạy dưới Kubernetes.
Các "Hậu duệ" chuẩn mực (Modern Standards):
- containerd: Đây chính là "trái tim" của Docker đã được tách ra thành project riêng. Nó gọn nhẹ, ổn định và là runtime phổ biến nhất hiện nay. Docker cũng dùng
containerdbên dưới! - CRI-O: Một runtime siêu nhẹ được thiết kế đặc biệt cho Kubernetes (OpenShift rất thích cái này). Nó tuân thủ 100% chuẩn OCI (Open Container Initiative).
TIP
Kết luận: Bạn vẫn dùng Docker để build image ở máy local (Dev). Nhưng trên Production Cluster, containerd hoặc CRI-O mới là kẻ thực thi nhiệm vụ chạy container.
2. The Pod Concept: Đơn vị nguyên tử (Atomic Unit)
Tại sao Kubernetes lại đẻ ra khái niệm Pod mà không chạy thẳng Container?
Analogy: "Peas in a Pod" (Những hạt đậu trong vỏ)
Hãy tưởng tượng Pod là cái vỏ đậu, còn Containers là những hạt đậu bên trong. Bạn không thể ném từng hạt đậu lẻ loi vào cluster. Bạn ném cả cái vỏ đậu (Pod). Pod là đơn vị triển khai nhỏ nhất.
Shared Context (Những thứ dùng chung)
Mọi container trong cùng một Pod đều sống chung trong một "căn hộ":
- Network Namespace (Quan trọng nhất):
- Tất cả container trong Pod dùng chung MỘT địa chỉ IP.
- Chúng có thể giao tiếp với nhau qua
localhost.
- IPC Namespace: Có thể giao tiếp qua Inter-Process Communication (SystemV semaphores, shared memory).
- UTS Namespace: Chung Hostname.
Ví dụ thực tế: Sidecar Pattern
Giả sử bạn có một Pod gồm 2 Container:
- Main App (Node.js): Chạy port 8080.
- Log Shipper (Fluentd): Chạy port 24224.
Vì chúng chung Network Namespace:
- Main App có thể gửi log thẳng đến
localhost:24224. Không cần biết IP của Log Shipper là gì. - Nếu Log Shipper cố gắng listen port 8080 => Port Conflict (Lỗi xung đột cổng, giống như 2 process trên cùng 1 máy ảo tranh nhau port).
3. Networking 101: The Flat World
Kubernetes đặt ra một luật chơi cực kỳ nghiêm ngặt về mạng, gọi là Flat Network Model.
3 Nguyên Tắc Vàng:
- Pod-to-Pod: Mọi Pod phải giao tiếp được với mọi Pod khác mà không cần NAT (Network Address Translation).
- Node-to-Pod: Mọi Node có thể giao tiếp với mọi Pod trên Node đó.
- IP-Per-Pod: Một Pod có một IP duy nhất. IP mà Pod thấy chính là IP mà người khác thấy nó.
Tại sao điều này quan trọng?
Hãy nhớ lại thời Docker cũ kỹ ("Port Mapping Hell"):
- Bạn chạy container A trên port 80.
- Bạn phải map nó ra port 8080 của Host (
-p 8080:80). - Container B muốn gọi Container A, phải gọi IP của Host + Port 8080.
- Nếu Host đổi IP hoặc Port 8080 bị chiếm? -> Vỡ trận.
Với Kubernetes Model:
- Pod A có IP
10.42.0.1. - Pod B có IP
10.42.0.2. - Pod A gọi thẳng
10.42.0.2. Không cần quan tâm Pod B đang nằm trên Node nào. - Không có port mapping rối rắm. Ứng dụng hoạt động như thể nó đang chạy trên một mạng LAN phẳng khổng lồ.
IMPORTANT
Để làm được phép màu "Flat Network" này giữa các Node vật lý khác nhau, chúng ta cần các CNI Plugin (như Calico, Flannel, Cilium). Chúng tạo ra mạng ảo (Overlay Network) hoặc dùng BGP routing để nối thông các Pod với nhau.
Tổng kết
- Docker không chết, nhưng trên Cluster, CRI (containerd/CRI-O) là vua.
- Pod là nhóm các container dùng chung IP và
localhost. - Mạng Kubernetes là một Mạng Phẳng (Flat Network): Mỗi Pod là một công dân hạng nhất với IP riêng.