02 03.docker containerd
1. Câu chuyện Lịch sử: Docker, Kubernetes và sự ra đời của CRI¶
- Thuở sơ khai: Docker là "vua" của thế giới container. Kubernetes ban đầu được xây dựng để dàn dựng (orchestrate) chuyên biệt cho Docker. Lúc này, chúng "dính liền" với nhau.
- Sự trỗi dậy: Kubernetes ngày càng phổ biến, và các container runtime khác (như
rkt
) cũng muốn được Kubernetes hỗ trợ. Cộng đồng cần Kubernetes phải làm việc được với nhiều runtime chứ không chỉ riêng Docker. -
Giải pháp: CRI (Container Runtime Interface): Kubernetes giới thiệu CRI - một giao diện chuẩn. Bất kỳ container runtime nào tuân thủ tiêu chuẩn OCI (Open Container Initiative) đều có thể làm việc với Kubernetes thông qua CRI.
-
OCI định nghĩa tiêu chuẩn về cách build một image (
imagespec
) và cách một runtime hoạt động (runtimespec
). -
Vấn đề của Docker: Docker ra đời trước khi có CRI, nên nó không tương thích trực tiếp với chuẩn này.
- Miếng vá "tạm bợ":
dockershim
: Vì Docker quá phổ biến, Kubernetes đã tạo ra một "miếng vá" tên làdockershim
. Đây là một cầu nối tạm thời để Kubernetes có thể tiếp tục hỗ trợ Docker engine. - Cuộc chia ly định mệnh (Kubernetes v1.24): Việc duy trì
dockershim
ngày càng trở thành gánh nặng. Do đó, từ phiên bản 1.24, Kubernetes đã loại bỏ hoàn toàndockershim
, đồng nghĩa với việc chấm dứt hỗ trợ trực tiếp Docker engine như một container runtime.
Lưu ý cực kỳ quan trọng: Các Docker image mà bạn đã build vẫn hoạt động bình thường! Vì Docker build image theo chuẩn OCI
imagespec
, nên các runtime tương thích CRI khác (như Containerd) vẫn có thể chạy chúng ngon lành. Chỉ có Docker engine là không còn được hỗ trợ trực tiếp nữa thôi.
2. Hiểu về Containerd - "Trái tim" của Docker¶
- Docker không chỉ là một runtime. Nó là một bộ công cụ bao gồm Docker CLI, API, build tools,... và bên trong nó chính là Containerd - thành phần cốt lõi chịu trách nhiệm chạy container.
- Containerd vốn dĩ đã tương thích với CRI. Hiện nay, nó đã là một dự án độc lập, tốt nghiệp tại CNCF. Bạn có thể cài đặt và sử dụng riêng Containerd mà không cần cài cả bộ Docker engine.
3. "Dụng cụ" trong Kỷ nguyên mới: ctr
vs. nerdctl
vs. crictl
¶
Khi không còn docker
trên các node Kubernetes, chúng ta sẽ dùng gì để tương tác với container? Đây là 3 công cụ bạn cần phân biệt:
ctr
¶
- Nguồn gốc: Đi kèm khi bạn cài đặt Containerd.
- Mục đích: Chỉ dùng để debug Containerd. Nó có rất ít tính năng và không thân thiện với người dùng.
- Kết luận: Trong thực tế, bạn gần như sẽ không dùng đến nó. Có thể bỏ qua.
nerdctl
(Nerd Control)¶
- Nguồn gốc: Từ cộng đồng Containerd.
- Mục đích: Là một công cụ dòng lệnh giống hệt Docker (Docker-like CLI) dành riêng cho Containerd. Dùng cho mục đích phổ thông (general purpose).
- Điểm mạnh: Cú pháp gần như y hệt
docker
. Bạn chỉ cần thaydocker
bằngnerdctl
. Ví dụ:nerdctl run
,nerdctl ps
,nerdctl images
. Nó còn hỗ trợ các tính năng mới hơn của Containerd mà Docker chưa có. - Kết luận: Đây là công cụ bạn nên dùng nếu muốn có trải nghiệm tương tự Docker để quản lý container khi chỉ có Containerd.
crictl
(CRI Control)¶
- Nguồn gốc: Từ cộng đồng Kubernetes.
- Mục đích: Là một công cụ dòng lệnh để tương tác và debug BẤT KỲ CRI-compatible runtime nào (không chỉ riêng Containerd). Đây là công cụ nhìn từ "góc độ của Kubernetes".
- Điểm mạnh:
- Hoạt động trên nhiều runtime khác nhau.
- Cú pháp cũng rất giống
docker
cho các lệnh cơ bản (ps
,logs
,exec
,images
...). - Nó "hiểu" về Pod (
crictl pods
), điều mà Docker không có. - Sử dụng:
- Đây là công cụ thay thế cho
docker
khi bạn cần troubleshoot container trên một Kubernetes node. Ví dụ, ngày xưa bạnssh
vào worker node và gõdocker ps
, thì bây giờ bạn sẽ gõcrictl ps
. - Lưu ý:
crictl
chủ yếu dùng để debug. Bạn không nên dùng nó để tạo container thủ công, vìkubelet
sẽ không biết về container đó và có thể sẽ xóa nó đi.
4. Bảng so sánh "Nhanh"¶
Công cụ | Mục đích | Cộng đồng | Phạm vi |
---|---|---|---|
ctr |
Debugging | Containerd | Chỉ Containerd |
nerdctl |
Phổ thông (Giống Docker) | Containerd | Chỉ Containerd |
crictl |
Debugging (Trên K8s node) | Kubernetes | Mọi CRI-compatible runtime |
5. "Chốt hạ" cho Kỳ thi 📝¶
- Hiểu rõ quá trình Kubernetes chuyển từ phụ thuộc
dockershim
sang thế giới CRI thuần túy. - Khi nào dùng gì?
nerdctl
: Dùng khi bạn muốn có một trải nghiệm giống Docker để quản lý container nói chung với Containerd.crictl
: Dùng khi bạn đang ở trên một node Kubernetes và cần troubleshoot/debug các container và pod. Đây là công cụ chẩn đoán chính của bạn trên K8s node ngày nay.
"Docker bị khai tử" trong Kubernetes - Hiểu sao cho đúng? 🤔¶
Đây là một điểm gây nhiều nhầm lẫn. "Khai tử" ở đây không có nghĩa là Docker đã "chết" hoàn toàn. Nó chỉ có nghĩa là đã có một sự thay đổi lớn trong cách Kubernetes làm việc với container runtime.
1. Tóm tắt lại "Cuộc chia ly"¶
-
Docker không chỉ là một runtime: Bạn cần nhớ rằng, Docker là một bộ công cụ hoàn chỉnh, bao gồm:
-
Docker CLI (dòng lệnh
docker
) - API
- Công cụ build image
- Quản lý volumes, networking, auth...
-
Và quan trọng nhất, bên trong nó chứa thành phần runtime cốt lõi là
Containerd
. -
Containerd
mới là thứ Kubernetes cần: -
Containerd
là phần chịu trách nhiệm thực thi và quản lý vòng đời của container. - Nó hoàn toàn tương thích với CRI (Container Runtime Interface) - tiêu chuẩn mà Kubernetes dùng để giao tiếp với các container runtime.
-
Do đó, Kubernetes có thể làm việc trực tiếp với
Containerd
(hoặc các CRI-compatible runtime khác). -
Vậy tại sao Kubernetes không cần Docker Engine nữa?
-
Kubernetes đã có cơ chế riêng để quản lý mạng, volumes, và các tác vụ khác. Nó không cần đến các công cụ phụ trợ đi kèm trong bộ Docker Engine.
- Kubernetes chỉ cần một thứ duy nhất từ bộ Docker: thành phần runtime. Và vì nó có thể nói chuyện trực tiếp với
Containerd
, việc phải đi qua cả một Docker Engine cồng kềnh trở nên không cần thiết và phức tạp (phải thông quadockershim
).
2. Vậy Docker "chết" thật hay không? 👻¶
Câu trả lời dứt khoát là: KHÔNG! 🚫
- Docker vẫn là công cụ container phổ biến nhất và được hàng triệu lập trình viên sử dụng hàng ngày cho việc phát triển cục bộ (local development) và build image.
- Sự thay đổi này chỉ có nghĩa là: Kubernetes không còn yêu cầu Docker Engine làm container runtime cho nó nữa.
3. Áp dụng trong khóa học này và thực tế¶
- Trong các bài học, việc tiếp tục dùng Docker làm ví dụ để giảng dạy các khái niệm cơ bản về container là hoàn toàn ổn. Nó giúp chúng ta hiểu cách container hoạt động trước khi đi vào thế giới dàn dựng phức tạp của Kubernetes.
- Mẹo thực hành: Nếu máy bạn không cài Docker mà chỉ cài
Containerd
riêng lẻ, bạn vẫn có thể làm theo hầu hết các ví dụ bằng cách thay thế lệnhdocker
bằng lệnhnerdctl
.
"Chốt hạ" cho Kỳ thi 📝¶
- "Docker deprecation" có nghĩa là Kubernetes đã loại bỏ hỗ trợ cho Docker Engine như một runtime, không phải là khai tử Docker nói chung.
- Docker images bạn build vẫn hoạt động 100% trên Kubernetes vì chúng tuân theo chuẩn OCI.
- Kỹ năng làm việc với Docker (build image, phát triển ứng dụng trong container) vẫn cực kỳ quan trọng và cần thiết.
- Trong môi trường Kubernetes hiện đại, runtime được sử dụng trực tiếp là một runtime tương thích CRI, phổ biến nhất chính là
Containerd
.