Chuyển đến nội dung chính

Containerd và Docker: Hiểu về các runtime container

Tìm hiểu những điểm khác biệt chính giữa Docker và container runtime containerd. Khám phá kiến trúc của chúng và khi nào nên dùng mỗi công cụ cho phát triển.
Benito Martin
Benito Martin

Tạo tài khoản miễn phí của bạn

Luyện tập và Lộ trình tiến trình của bạn.

Tiếp tục với GoogleBằng cách tiếp tục, bạn chấp nhận Điều khoản sử dụng, Chính sách quyền riêng tư và việc dữ liệu của bạn được lưu trữ tại Hoa Kỳ.

Trong hệ sinh thái container, một nguồn gây nhầm lẫn thường gặp là khi các nhà phát triển so sánh Docker (một nền tảng toàn diện) với containerd, vốn thực chất là một thành phần runtime tập trung. So sánh này giống như so một chiếc ô tô hoàn chỉnh với động cơ của nó: cả hai đều thiết yếu, nhưng phục vụ các mục đích khác nhau ở các mức độ trừu tượng khác nhau. 

Trong hướng dẫn này, tôi sẽ làm rõ mối quan hệ giữa hai công nghệ này, khám phá kiến trúc của chúng, khả năng tích hợp với Kubernetes, và các kịch bản cụ thể nơi mỗi công cụ tỏa sáng. Dù bạn đang xây dựng container cục bộ hay quản lý các cụm Kubernetes ở môi trường sản xuất, hiểu khi nào dùng Docker so với containerd có thể ảnh hưởng đáng kể đến các quyết định về hạ tầng.

Đến cuối bài viết, bạn sẽ nắm rõ cách Docker và containerd bổ trợ cho nhau, và cách chọn công cụ phù hợp cho nhu cầu cụ thể của bạn, dù là phát triển nhanh tại chỗ hay triển khai quy mô lớn trong sản xuất.

Nếu bạn mới làm quen với container hóa, tôi rất khuyến nghị tham gia khóa học Các khái niệm về Containerization và Virtualization của chúng tôi.

Docker là gì?

Docker đã làm thay đổi bức tranh phát triển phần mềm bằng cách khiến container hóa trở nên dễ tiếp cận và thực tế cho các nhà phát triển hằng ngày. Là một nền tảng toàn diện, Docker cung cấp mọi thứ cần thiết để xây dựng, phân phối và chạy các ứng dụng được đóng gói trong container.

Đối với người mới bắt đầu, Hướng dẫn Thực hành về Containers là phần mở đầu tuyệt vời về Docker và container.

Một nền tảng container toàn diện

Docker hoạt động như một nền tảng container tất-cả-trong-một, cung cấp một bộ công cụ tích hợp bao phủ hầu hết vòng đời container. Cốt lõi của Docker là đóng gói ứng dụng cùng mọi phụ thuộc thành các image di động, tự chứa, có thể chạy nhất quán trên bất kỳ môi trường nào, từ máy tính xách tay của nhà phát triển đến máy chủ sản xuất.

Logo Docker

Cách tiếp cận toàn diện này đã khiến Docker trở thành tiêu chuẩn trong ngành cho phát triển cục bộ và trải nghiệm dành cho nhà phát triển. Một số lợi ích chính gồm:

  • Hệ sinh thái phong phú: Docker Hub lưu trữ hàng triệu image dựng sẵn, từ cơ sở dữ liệu đến máy chủ web, loại bỏ các quy trình cài đặt phức tạp
  • Tính di động phổ quát: Một container dựng trên macOS chạy giống hệt trên Linux hoặc Windows, miễn là có cài Docker
  • Tập trung vào nhà phát triển: Trừu tượng hóa khác biệt hạ tầng để nhà phát triển tập trung vào ứng dụng thay vì phức tạp khi triển khai
  • Khởi động nhanh: Thành viên mới có thể thiết lập môi trường phát triển trong vài phút thay vì hàng giờ

Các thành phần và quy trình làm việc chính

Kiến trúc của Docker gồm nhiều thành phần liên kết với nhau, hoạt động trơn tru. 

Docker CLI cung cấp giao diện cho người dùng nơi nhà phát triển ra lệnh. Khi bạn chạy lệnh như docker run, CLI sẽ giao tiếp với Docker daemon (dockerd), dịch vụ lõi quản lý container, image, mạng và volume.

Đối với người dùng Windows và macOS, Docker Desktop mang lại một lớp tiện lợi bổ sung với giao diện đồ họa, giúp quản lý container dễ tiếp cận ngay cả với những người ít thoải mái với công cụ dòng lệnh. Môi trường tích hợp này bao gồm mọi thứ cần cho phát triển cục bộ, từ hỗ trợ Kubernetes đến quản lý volume.

Quy trình làm việc điển hình theo một khuôn mẫu rõ ràng: 

  1. Nhà phát triển dựng image bằng Dockerfile
  2. Đẩy chúng lên các registry như Docker Hub
  3. Cuối cùng, các image được chạy dưới dạng container trên bất kỳ máy chủ có Docker nào 

Điều nhiều nhà phát triển không nhận ra là Docker không trực tiếp thực thi container. Thay vào đó, dockerd ủy quyền việc thực thi container thực tế cho containerd, vốn chạy nền như một tiến trình riêng.

Các thành phần Docker

Thiết kế mô-đun này, nơi Docker dùng containerd cho các thao tác cấp thấp, cho phép mỗi thành phần tập trung vào thế mạnh của mình: Docker cung cấp giao diện thân thiện với nhà phát triển và hệ sinh thái, trong khi containerd xử lý các chi tiết tỉ mỉ của việc thực thi container.

Dù bạn mới bắt đầu với Docker hay muốn tiến xa hơn, hãy xem 10 ý tưởng dự án Docker cho mọi cấp độ.

Containerd là gì?

Sau khi khám phá cách tiếp cận nền tảng toàn diện của Docker, giờ hãy xem xét containerd, runtime chuyên biệt cung cấp năng lực thực thi container cả trong Docker và trên toàn hệ sinh thái rộng lớn hơn.

Một container runtime tiêu chuẩn trong ngành

Containerd là một core container runtime nhẹ, theo tiêu chuẩn ngành, đã tốt nghiệp từ Cloud Native Computing Foundation (CNCF), cho thấy mức độ trưởng thành, độ tin cậy và được áp dụng rộng rãi. Vốn là một phần của Docker, containerd được tách ra vào năm 2017 và đóng góp cho CNCF để cho phép hệ sinh thái chấp nhận rộng hơn.

Logo Containerd

Không như bộ tính năng toàn diện của Docker, phạm vi của containerd được giới hạn có chủ đích: nó quản lý các hoạt động vòng đời container cốt lõi như khởi động, dừng, tạm dừng và xóa, đồng thời xử lý truyền tải và lưu trữ image. Cách tiếp cận tập trung này khiến containerd đặc biệt ổn định và hiệu quả, những phẩm chất thiết yếu cho môi trường sản xuất.

Hãy coi containerd như “đường ống”: phần hạ tầng được thiết kế để nhúng vào các hệ thống lớn hơn thay vì do con người sử dụng trực tiếp. Các nền tảng lớn như Kubernetes, AWS Fargate và Google Kubernetes Engine đều dựa vào containerd để thực thi container, dù người dùng tương tác với những nền tảng này qua giao diện riêng của chúng.

Kiến trúc và thiết kế

Để hiểu vì sao containerd được chấp nhận rộng rãi trong các hệ thống sản xuất, chúng ta cần xem xét các nguyên lý kiến trúc của nó.

Kiến trúc của containerd thể hiện các nguyên tắc thiết kế mô-đun. Được xây dựng dựa trên các tiêu chuẩn của Open Container Initiative (OCI), containerd đảm bảo khả năng tương thích trên toàn hệ sinh thái container. Điều này có nghĩa là bất kỳ image tuân theo OCI nào cũng sẽ hoạt động với containerd, bất kể công cụ nào đã tạo ra nó.

Kiến trúc gồm một vài lớp chính:

  • Lớp API gRPC: Cung cấp mô hình client-server, nơi nhiều client (Docker, Kubernetes, công cụ tùy chỉnh) giao tiếp với một instance containerd duy nhất
  • Daemon containerd: Duy trì trạng thái về các container đang chạy, quản lý lưu trữ image qua snapshotter, và điều phối mạng thông qua plugin
  • Runtime runc: Runtime nhẹ, tuân thủ OCI, giao tiếp trực tiếp với các tính năng của nhân Linux, tạo namespace, thiết lập cgroup và khởi chạy tiến trình container
  • Các plugin mô-đun: Có thể tích hợp các snapshotter tùy chỉnh cho lưu trữ chuyên biệt, các runtime thay thế (gVisor, Kata Containers), và plugin mạng mà không cần sửa đổi containerd

Khi containerd cần khởi động một container, nó sinh runc, thành phần thực hiện công việc thực tế là tạo các namespace cách ly, thiết lập cgroup cho giới hạn tài nguyên, và khởi chạy tiến trình container. 

Sự tách bạch trách nhiệm này khiến containerd có khả năng mở rộng cao. Tổ chức có thể tùy biến gần như mọi khía cạnh mà không cần chạm vào mã lõi của containerd.

Những khác biệt chính giữa Containerd và Docker

Khi đã hiểu vững mỗi công cụ làm gì, hãy xem chúng khác nhau thế nào trong thực tế, từ kiến trúc đến mô hình tích hợp.

Runtime container so với nền tảng

Khác biệt căn bản nằm ở phạm vi và mục đích. 

Docker dùng kiến trúc daemon tập trung, trong đó dockerd điều phối nhiều khía cạnh khác nhau, như:

  • Dựng image
  • Thực thi container
  • Networking
  • Quản lý volume

Thiết kế tất-cả-trong-một này đơn giản hóa trải nghiệm cho nhà phát triển nhưng tạo thêm chi phí do nhiều lớp trừu tượng.

Ngược lại, containerd tập trung hẹp vào việc thực thi container. Nó không bao gồm khả năng dựng image, tính năng điều phối hay giao diện đồ họa. Về networking, Docker tích hợp Libnetwork trong daemon của mình, còn containerd dựa vào các plugin Container Network Interface (CNI) bên ngoài có thể hoán đổi theo nhu cầu.

Khác biệt kiến trúc này có tác động đến hiệu năng. Trong các môi trường có tần suất thay đổi cao, nơi container thường xuyên khởi động và dừng như các cụm Kubernetes tự động mở rộng, thiết kế tinh gọn của containerd có thể mang lại thời gian khởi động nhanh hơn và tiêu thụ tài nguyên thấp hơn. Chi phí giảm bớt đồng nghĩa containerd dùng ít bộ nhớ và CPU hơn, điều trở nên đáng kể khi mở rộng.

Tích hợp với Kubernetes

Nói về Kubernetes, mối quan hệ giữa các container runtime và nền tảng điều phối đã phát triển đáng kể, đặc biệt là cách Kubernetes kết nối với containerd.

Mối quan hệ giữa Kubernetes và các container runtime đã có bước chuyển lớn với Kubernetes 1.24, phát hành năm 2022. Phiên bản này loại bỏ "Dockershim", lớp tương thích cho phép Kubernetes dùng Docker làm runtime.

Dockershim luôn được coi là cầu nối tạm thời. Khi Kubernetes giới thiệu Container Runtime Interface (CRI) để tiêu chuẩn hóa giao tiếp với runtime, Docker không thể triển khai trực tiếp vì Docker có trước thiết kế CRI. Dockershim dịch giữa Kubernetes và Docker, thêm một lớp chuyển đổi về sau không còn cần thiết.

Các phiên bản Kubernetes hiện đại giao tiếp trực tiếp với containerd qua CRI, loại bỏ hoàn toàn lớp chuyển đổi của Docker. Sự đơn giản hóa này mang lại lợi ích cụ thể:

  • Giảm độ trễ: Giao tiếp trực tiếp loại bỏ chi phí dịch trong các thao tác container
  • Tăng ổn định: Ít thành phần chuyển động hơn đồng nghĩa ít điểm lỗi tiềm ẩn
  • Hiệu năng tốt hơn: Chuỗi runtime tinh gọn đặc biệt có lợi cho triển khai quy mô lớn
  • Gỡ lỗi đơn giản: Tích hợp CRI trực tiếp giúp khắc phục sự cố dễ dàng hơn

Với người dùng Kubernetes, thay đổi này phần lớn là trong suốt. Các image Docker vẫn hoàn toàn tương thích vì tuân thủ tiêu chuẩn OCI. Tác động thực tế là các cụm Kubernetes sản xuất nay chạy hiệu quả hơn khi dùng trực tiếp containerd, trong khi nhà phát triển vẫn có thể dùng Docker cục bộ để dựng và kiểm thử.

Nếu bạn chưa chắc về ưu nhược điểm của việc dùng Kubernetes ngay từ đầu, hãy xem bài so sánh Docker Compose vs Kubernetes.

Dựng và quản lý image

Trong khi tích hợp runtime là then chốt cho điều phối, quy trình làm việc của nhà phát triển phụ thuộc nhiều vào cách mỗi công cụ xử lý việc tạo và lưu trữ image. Dựng image thể hiện khoảng cách năng lực đáng kể giữa Docker và containerd. 

Docker cung cấp hệ thống dựng tích hợp qua Dockerfile và BuildKit, cho phép nhà phát triển xây dựng các bản dựng đa giai đoạn phức tạp với caching, song song hóa và các tính năng nâng cao như build secrets và chuyển tiếp SSH agent.

Theo thiết kế, containerd không bao gồm quy trình dựng image nguyên bản. Để dựng image với containerd, nhà phát triển phải dùng công cụ bên ngoài. Các lựa chọn gồm chạy BuildKit như một daemon riêng và dùng buildctl cho các bản dựng dòng lệnh, hoặc dùng nerdctl, một CLI tương thích Docker tích hợp BuildKit.

Cơ chế lưu trữ cũng khác nhau về triết lý. Quản lý volume của Docker cung cấp một lớp trừu tượng thân thiện với nhà phát triển, với các volume có tên lưu dữ liệu bền vững độc lập với vòng đời container. Containerd dùng hệ thống snapshotter ở mức thấp hơn, nơi các driver snapshot khác nhau có thể được cắm vào để xử lý hệ thống tệp phân lớp theo yêu cầu lưu trữ bên dưới.

Sự khác biệt này phản ánh đối tượng người dùng mục tiêu của các công cụ: 

  • Docker tối ưu cho năng suất nhà phát triển với các tiện ích tích hợp
  • Containerd cung cấp các nguyên thủy linh hoạt để những người xây dựng nền tảng lắp ghép theo nhu cầu cụ thể

CLI, trải nghiệm nhà phát triển và nerdctl

Ngoài kiến trúc và tính năng, trải nghiệm hàng ngày của nhà phát triển được định hình trực tiếp nhất bởi giao diện dòng lệnh mà mỗi công cụ cung cấp. Trải nghiệm dòng lệnh cho thấy rõ nhất khác biệt về triết lý thiết kế. 

CLI của Docker nổi tiếng thân thiện. Các lệnh như docker run, docker build và docker logs trực quan, được tài liệu hóa tốt và thiết kế cho con người. CLI bao gồm các mặc định hữu ích, thông báo lỗi rõ ràng và nhiều tùy chọn bao phủ hầu hết tình huống sử dụng.

Containerd đi kèm ctr, một CLI tối giản chỉ nhằm mục đích gỡ lỗi và kiểm thử chức năng cấp thấp của containerd. Công cụ ctr cố ý không thân thiện với nhà phát triển. Nó thiếu các tính năng phổ biến như viết tắt ánh xạ cổng, chính sách tự khởi động lại và tích hợp trình trợ giúp thông tin xác thực. Nó được thiết kế cho nhà phát triển containerd, không phải nhà phát triển ứng dụng.

Thu hẹp khoảng cách với nerdctl

Khoảng cách về khả dụng này dẫn đến việc tạo ra nerdctl, một CLI tương thích Docker cho containerd. Dùng nerdctl cảm giác giống hệt dùng Docker, cùng cú pháp lệnh, cùng cờ, cùng quy trình làm việc, nhưng với containerd là runtime bên dưới. Điều này khiến nerdctl trở thành cầu nối tuyệt vời cho các đội ngũ chuyển từ Docker sang containerd trong môi trường phát triển.

Trên thực tế, các nhà phát triển hiếm khi tương tác trực tiếp với containerd. Khi cần, nerdctl cung cấp giao diện quen thuộc như họ mong đợi, trong khi các nhà vận hành nền tảng và quản trị viên dùng API của containerd một cách lập trình thông qua các hệ thống điều phối như Kubernetes.

Để minh họa khác biệt trong thực tế, dưới đây là cách các thao tác container phổ biến so sánh giữa ba công cụ CLI:

Nhiệm vụ

Docker

nerdctl

ctr

Chạy container

docker run -d -p 8080:80 nginx

nerdctl run -d -p 8080:80 nginx

ctr run --net-host -d docker.io/library/nginx:latest nginx_id

Liệt kê container

docker ps

nerdctl ps

ctr tasks list

Dựng image

docker build -t myapp .

nerdctl build -t myapp .

Không hỗ trợ

Xem log

docker logs <container>

nerdctl logs <container>

Không hỗ trợ

Inspect container

docker inspect <container>

nerdctl inspect <container>

ctr containers info <container>

Kéo image

docker pull nginx

nerdctl pull nginx

ctr images pull docker.io/library/nginx:latest

Hỗ trợ Compose

docker compose up

nerdctl compose up

Không hỗ trợ

Lưu ý: ctr thiếu ánh xạ cổng (-p) và yêu cầu mạng host (--net-host) để mở dịch vụ. Nó cũng không tự động kéo image.

Tổng quan về các khác biệt chính

Trước khi đi vào khuyến nghị cho các trường hợp sử dụng cụ thể, hãy điểm lại các khác biệt đã đề cập. Bảng sau tóm tắt những khác biệt chức năng chính giữa Docker và containerd, làm nổi bật năng lực và đối tượng mục tiêu riêng của chúng:

Tính năng

Docker

Containerd

Dựng image

Tích hợp (Dockerfile, BuildKit)

Cần công cụ ngoài (buildctl, nerdctl)

Điều phối

Docker Swarm / Kubernetes

Không (được Kubernetes sử dụng)

Quản lý lưu trữ

Quản lý volume

Hệ thống snapshotter

Giao diện đồ họa

Docker Desktop

Không có

Vòng đời container

Quản lý đầy đủ (thông qua containerd)

Trọng tâm cốt lõi (tương thích CRI)

Người dùng chính

Nhà phát triển ứng dụng

Người vận hành cụm, Nhà xây dựng nền tảng

Vì sao chọn Docker?

Giờ khi đã đề cập khác biệt kỹ thuật, hãy xem các kịch bản thực tế nơi mỗi công cụ vượt trội. Dù containerd gia tăng hiện diện trong môi trường sản xuất, Docker vẫn là lựa chọn vượt trội cho các tình huống mà trải nghiệm nhà phát triển và bộ công cụ toàn diện là quan trọng nhất.

Cho phát triển cục bộ và thử nghiệm ý tưởng

Docker tỏa sáng khi bạn cần một giải pháp “tất-cả-trong-một” để viết và kiểm thử mã. Bộ công cụ tích hợp nghĩa là nhà phát triển có thể đi từ con số 0 đến chạy container trong vài phút, không cần lắp ghép nhiều thành phần hay cấu hình mạng phức tạp.

Hệ sinh thái Docker mang lại lợi ích năng suất to lớn:

  • Docker Hub: Hàng triệu image sẵn dùng cho cơ sở dữ liệu, hàng đợi thông điệp và máy chủ web
  • Docker Compose: Định nghĩa ứng dụng đa container trong một tệp YAML và khởi chạy toàn bộ môi trường phát triển bằng một lệnh
  • GUI Docker Desktop: Quản lý container trực quan, duyệt volume, điều chỉnh giới hạn tài nguyên và tích hợp hỗ trợ Kubernetes
  • Rào cản gia nhập thấp: Công cụ đồ họa và lệnh trực quan giúp container trở nên dễ tiếp cận với người mới

Hệ sinh thái Docker

Với các nhóm dùng Docker Desktop, GUI mang lại những tiện ích bổ sung giúp tăng tốc đáng kể quá trình nhập môn và công việc hằng ngày.

Cho pipeline dựng phức tạp

Vượt ra ngoài phát triển, khả năng dựng của Docker khiến nó là lựa chọn tự nhiên cho các quy trình tích hợp liên tục và triển khai liên tục tinh vi.

BuildKit tích hợp của Docker cung cấp các tính năng nâng cao thiết yếu cho pipeline CI/CD hiện đại. Các bản dựng đa giai đoạn tối ưu kích thước image đồng thời giữ Dockerfile dễ đọc. Cơ chế caching của BuildKit tái sử dụng thông minh các layer qua nhiều bản dựng, giảm đáng kể thời gian dựng trong môi trường CI.

Hầu hết nền tảng tự động hóa, như GitHub Actions, GitLab CI, Jenkins, và các nền tảng khác, đều có tích hợp Docker trưởng thành, dày dạn kinh nghiệm. Các tích hợp này xử lý xác thực, cache và xuất bản image một cách trơn tru. 

Dù công cụ khác có thể đạt kết quả tương tự, mức độ phổ biến của Docker có nghĩa là giải pháp và trợ giúp khắc phục sự cố luôn sẵn có, đây là một điểm cộng lớn.

Vì sao chọn Containerd?

Containerd tỏa sáng trong các kịch bản sản xuất nơi chủ nghĩa tối giản, hiệu năng và ổn định quan trọng hơn sự tiện lợi của bộ công cụ tích hợp.

Cho các cụm Kubernetes sản xuất

Dùng containerd làm runtime cho các node Kubernetes mang lại lợi ích đo lường được:

  • Giảm chi phí: Loại bỏ daemon của Docker giúp giảm tiêu thụ tài nguyên trên mỗi node và tiết kiệm đáng kể khi mở rộng
  • Tăng ổn định: Ít thành phần chuyển động hơn đồng nghĩa ít điểm lỗi tiềm ẩn trong hạ tầng
  • Bề mặt tấn công nhỏ hơn: Ít mã cần kiểm toán và ít lỗ hổng bảo mật tiềm ẩn hơn
  • Gỡ lỗi đơn giản: Tích hợp CRI trực tiếp loại bỏ lớp chuyển đổi dockershim, giúp khắc phục sự cố dễ hơn
  • Hiệu năng tốt hơn: Chuỗi runtime tinh gọn cải thiện thời gian khởi động container và độ phản hồi

Containerd với Kubernetes

Tình trạng tốt nghiệp CNCF của containerd là tín hiệu về độ chín muồi và độ tin cậy. Các nhà cung cấp đám mây lớn, bao gồm AWS, Google Cloud và Azure, đã tiêu chuẩn hóa containerd cho các dịch vụ Kubernetes quản lý của họ, thể hiện sự tự tin vào mức độ sẵn sàng sản xuất cho hạ tầng then chốt.

Cho môi trường chuyên biệt, tối giản

Dù Kubernetes là trường hợp sử dụng sản xuất phổ biến nhất, bản chất nhẹ của containerd mở ra các kịch bản triển khai nơi Docker sẽ không thực tế.

Điện toán biên và thiết bị IoT thường hoạt động với ràng buộc tài nguyên nghiêm ngặt. Thiết kế nhẹ của containerd khiến nó khả thi trong các môi trường mà toàn bộ stack của Docker là cản trở. Mỗi MB bộ nhớ và mỗi chu kỳ CPU đều đáng giá khi chạy trên phần cứng nhúng.

Các kịch bản bảo mật nâng cao hưởng lợi từ kiến trúc runtime mô-đun của containerd. Tổ chức có thể tích hợp các runtime sandbox cho khối lượng công việc cần ranh giới bảo mật bổ sung. Ví dụ gồm:

  • gVisor: cung cấp cách ly nhân mạnh mẽ
  • Kata Containers: chạy container trong máy ảo nhẹ

Các tích hợp này cắm vào containerd mà không cần sửa đổi lớn.

Di trú từ Docker sang Containerd

Hiểu khi nào dùng mỗi công cụ là quan trọng, nhưng biết cách chuyển đổi giữa chúng cũng quan trọng không kém. Chuyển từ Docker sang containerd trong môi trường hiện hữu đòi hỏi lập kế hoạch cẩn thận, nhưng quy trình đã được tài liệu hóa tốt và khá thẳng thắn.

Di trú các node Kubernetes

Các bước vận hành để di trú các node Kubernetes từ Docker sang containerd theo một mẫu chuẩn:

  1. Cordon node: Ngăn pod mới được lên lịch (kubectl cordon <node-name>)

  2. Drain các pod hiện có: Di chuyển khối lượng công việc sang node khác (kubectl drain <node-name>)

  3. Cập nhật cấu hình Kubelet: Trỏ tới socket CRI của containerd tại /run/containerd/containerd.sock

  4. Kiểm tra plugin CNI: Đảm bảo containerd có các plugin mạng cần thiết đã cài

  5. Khởi động lại Kubelet: Đăng ký với runtime mới và tham gia lại cụm

Kiểm thử di trú trên các node không thuộc sản xuất trước giúp phát hiện các vấn đề đặc thù môi trường trước khi triển khai trên toàn cụm. Để tránh lỗi thường gặp, hãy bảo đảm làm theo các thông lệ tốt sau:

  • Thay đổi đường dẫn log: Docker và containerd dùng vị trí log mặc định khác nhau, nên cập nhật hạ tầng logging cho phù hợp
  • Cài plugin CNI còn thiếu: Containerd cần các binary plugin CNI cho networking; chúng không phải lúc nào cũng được cài mặc định
  • Chú ý khác biệt khi kéo image: Cấu hình xác thực và registry có thể cần điều chỉnh
  • Cẩn thận lệch driver lưu trữ: Đảm bảo volume bền vững của bạn tương thích với snapshotter của containerd

Điều hướng khác biệt CLI

Khi hạ tầng đã được di trú, các nhà phát triển cần thích ứng quy trình làm việc hằng ngày để làm việc với runtime mới.

Với các nhà phát triển đã quen lệnh Docker, nerdctl mang lại trải nghiệm gần như giống hệt. Các lệnh như nerdctl run, nerdctl build và nerdctl compose up hoạt động đúng như các lệnh tương đương của Docker, giúp quá trình chuyển đổi liền mạch.

Đối với gỡ lỗi, việc hiểu cách ánh xạ các quy trình gỡ lỗi của Docker sang containerd là thiết yếu. Nơi bạn có thể dùng docker inspect để xem xét một container, ctr containers info cung cấp thông tin tương tự, dù ở định dạng khác. Tương tự, ctr tasks list hiển thị các container đang chạy.

Đa số nhà phát triển thấy rằng nerdctl loại bỏ nhu cầu học cú pháp của ctr cho các tác vụ hằng ngày. Công cụ cấp thấp ctr vẫn hữu ích để xử lý sự cố đặc thù runtime hoặc khi làm việc trực tiếp với API của containerd.

Kết luận

Mối quan hệ giữa Docker và containerd là ví dụ hoàn hảo về thiết kế mô-đun thành công trong hạ tầng phần mềm. Docker vẫn là công cụ tối ưu cho con người viết mã, vì nó cung cấp trải nghiệm tích hợp, hệ sinh thái toàn diện và giao diện thân thiện với nhà phát triển, giúp việc xây dựng ứng dụng container hóa trở nên hiệu quả (và thú vị).

Trong khi đó, containerd xuất sắc với vai trò runtime cho máy móc thực thi code, mang lại sự ổn định, hiệu năng và tính tối giản cần thiết cho các nền tảng điều phối sản xuất. Việc Docker Engine dùng containerd bên dưới cho thấy hai công cụ bổ trợ nhau thay vì cạnh tranh.

Tôi khuyến nghị cách tiếp cận thực dụng cho hầu hết tổ chức: tiếp tục dùng Docker trên máy của nhà phát triển nơi bộ công cụ của nó tăng tốc quy trình, nhưng cân nhắc di trú các cụm Kubernetes sản xuất sang containerd trực tiếp để hưởng lợi vận hành từ chi phí giảm và chuỗi runtime đơn giản hơn.

Dù bạn chọn nền tảng toàn diện của Docker hay runtime tập trung của containerd, cả hai vẫn là thành phần thiết yếu của hệ sinh thái container hiện đại, mỗi công cụ được tối ưu cho những giai đoạn khác nhau của vòng đời ứng dụng.

Để tiếp tục học, hãy đăng ký lộ trình kỹ năng Containerization và Virtualization với Docker và Kubernetes của chúng tôi.

Containerd và Docker: Câu hỏi thường gặp

Tôi có thể dùng image Docker với containerd không?

Có, chắc chắn rồi. Containerd hỗ trợ mọi image container tuân thủ OCI, bao gồm cả những image được dựng bằng Docker. Vì Docker dựng các image theo chuẩn OCI, chúng hoạt động trơn tru với containerd và mọi runtime tuân thủ OCI khác. Bạn có thể dùng docker build cục bộ và chạy các image đó với containerd trong sản xuất mà không gặp vấn đề tương thích.

Docker có dùng containerd ở tầng bên dưới không?

Có, Docker Engine dùng containerd làm core container runtime của nó. Bắt đầu từ Docker 1.11, Docker tích hợp containerd để xử lý các thao tác vòng đời container như tạo, thực thi và quản lý. Khi bạn chạy docker run, Docker daemon (dockerd) ủy quyền việc thực thi container thực tế cho containerd, sau đó containerd dùng runc để tương tác với nhân Linux.

Tại sao Kubernetes loại bỏ hỗ trợ Docker?

Năm 2022, Kubernetes đã loại bỏ dockershim (lớp tương thích với Docker) để loại bỏ một lớp chuyển đổi không cần thiết. Docker có trước Container Runtime Interface (CRI), vì vậy Kubernetes cần dockershim để dịch giữa API của mình và Docker. Bằng cách giao tiếp trực tiếp với containerd qua CRI, Kubernetes đạt được hiệu năng tốt hơn, ổn định hơn và chuỗi runtime đơn giản hơn. Các image Docker vẫn hoạt động hoàn hảo trong Kubernetes.

Tôi có nên chuyển từ Docker sang containerd cho phát triển cục bộ không?

Không, Docker vẫn là lựa chọn tốt hơn cho phát triển cục bộ. Docker cung cấp bộ công cụ tích hợp với Docker Compose, GUI của Docker Desktop và hỗ trợ hệ sinh thái rộng rãi giúp tăng tốc quy trình phát triển. Hãy dùng containerd cho các cụm Kubernetes sản xuất nơi chi phí thấp hơn và tích hợp CRI trực tiếp mang lại lợi ích rõ ràng, nhưng giữ Docker trên máy của nhà phát triển vì trải nghiệm vượt trội.

Nerdctl là gì và tôi có cần nó không?

Nerdctl là một CLI tương thích Docker cho containerd, cung cấp trải nghiệm người dùng giống Docker (hỗ trợ hầu hết lệnh và cờ phổ biến) nhưng dùng containerd làm runtime. Bạn cần nó nếu muốn tương tác trực tiếp với containerd bằng các lệnh Docker quen thuộc. Nó đặc biệt hữu ích cho môi trường phát triển dùng containerd hoặc khi chuyển đội ngũ từ quy trình dựa trên Docker sang containerd.

Benito Martin

Tác giả

Benito Martin

Với vai trò Nhà sáng lập Martin Data Solutions và Nhà khoa học dữ liệu/ Kỹ sư ML & AI tự do, tôi sở hữu danh mục năng lực đa dạng về Hồi quy, Phân loại, Xử lý ngôn ngữ tự nhiên (NLP), LLM, RAG, Mạng nơ-ron, Phương pháp tổ hợp (Ensemble) và Thị giác máy tính.

  • Phát triển thành công nhiều dự án ML end-to-end, bao gồm làm sạch dữ liệu, phân tích, xây dựng mô hình và triển khai trên AWS và GCP, mang lại các giải pháp có tác động và khả năng mở rộng.
  • Xây dựng các ứng dụng web tương tác, có khả năng mở rộng bằng Streamlit và Gradio cho nhiều bài toán trong các ngành khác nhau.
  • Giảng dạy và cố vấn cho học viên về khoa học dữ liệu và phân tích, thúc đẩy sự phát triển nghề nghiệp của họ thông qua phương pháp học tập cá nhân hóa.
  • Thiết kế nội dung khóa học cho các ứng dụng retrieval-augmented generation (RAG) được điều chỉnh theo yêu cầu doanh nghiệp.
  • Viết các blog kỹ thuật AI & ML có sức ảnh hưởng, bao gồm các chủ đề như MLOps, cơ sở dữ liệu vector và LLM, đạt được mức độ tương tác đáng kể.

Trong mỗi dự án tôi đảm nhận, tôi luôn áp dụng các thực hành cập nhật trong kỹ thuật phần mềm và DevOps như CI/CD, linting mã, định dạng, giám sát mô hình, theo dõi thí nghiệm và xử lý lỗi mạnh mẽ. Tôi cam kết cung cấp các giải pháp hoàn chỉnh, chuyển hóa những hiểu biết từ dữ liệu thành chiến lược thực tiễn giúp doanh nghiệp phát triển và khai thác tối đa giá trị của khoa học dữ liệu, học máy và AI.

Chủ đề

Liên quan