11 điểm bởi GN⁺ 2026-03-08 | 1 bình luận | Chia sẻ qua WhatsApp
  • Đây là bài báo của ACM làm nổi bật quá trình tiến hóa về mặt kỹ thuật của Docker, công nghệ đã thay đổi tận gốc cách các nhà phát triển build, triển khai và chạy ứng dụng kể từ lần phát hành đầu tiên vào năm 2013, đồng thời tổng hợp hàng chục năm nghiên cứu hệ thống ẩn sau một CLI tưởng chừng đơn giản
  • Nền tảng kỹ thuật cốt lõi của Docker là cách đạt được sự cô lập tiến trình mà không cần máy ảo bằng cách tận dụng namespace của Linux; bằng cách kết hợp 7 loại namespace được bổ sung dần từ năm 2001, Docker hiện thực hóa container nhẹ
  • Để hỗ trợ macOS và Windows, Docker áp dụng một kiến trúc ngược lối tư duy thông thường: nhúng library virtual machine monitor (HyperKit) ngay bên trong ứng dụng desktop, chạy Linux trong tiến trình người dùng thay vì dùng cách tiếp cận hypervisor truyền thống
  • Hiện nay Docker hỗ trợ phần cứng dị chủng như ARM·RISC-V cùng các workload AI, và đã trở thành hạ tầng phát triển tiêu chuẩn trên toàn bộ môi trường cloud, desktop và edge
  • Sự trỗi dậy của workload AI khiến quản lý phụ thuộc GPU trở thành thách thức mới; Docker vẫn đang tiếp tục tiến hóa với hỗ trợ GPU thông qua CDI(Container Device Interface) và tích hợp TEE(môi trường thực thi tin cậy)

Nguồn gốc kỹ thuật

  • Vào đầu những năm 2000, việc cài đặt thủ công vô số dependency vào bản phân phối Linux rồi tự biên dịch và cấu hình phần mềm là chuyện phổ biến; sự trỗi dậy của điện toán đám mây vào năm 2010 càng khiến quá trình này trở nên phức tạp hơn
  • Docker đơn giản hóa việc này bằng cách cho phép nhà phát triển đóng gói ứng dụng và mọi dependency thành ảnh hệ thống tệp ("container"), để có thể chạy trên bất kỳ máy nào chỉ cần cài Docker
  • Khác với máy ảo, có thể chạy chỉ với vài lệnh mà không cần cài đặt cả hệ điều hành đầy đủ

Quy trình làm việc điển hình

  • Khi nhà phát triển viết Dockerfile, họ định nghĩa quy trình build theo từng bước dựa trên cú pháp shell
    • Ví dụ website Python: bắt đầu với FROM python:3, sau đó mô tả trong một tệp việc cài dependency, sao chép mã nguồn, mở cổng và lệnh chạy
  • Tạo container image bằng docker build và đẩy lên Docker Hub bằng docker push
  • Chạy với việc chỉ định mount volume dữ liệu và mở cổng mạng như docker run -v data:/app/data -p 80:80
  • Từ năm 2013 đến nay, CLI đã được mở rộng đáng kể và backend được thiết kế lại toàn diện, nhưng quy trình cơ bản viết Dockerfile → docker builddocker run vẫn được giữ nhất quán
  • Đã tìm thấy hơn 3,4 triệu Dockerfile nằm ở thư mục gốc của các kho công khai trên GitHub

Cơ chế hoạt động bên trong: namespace của Linux

  • Kernel hệ điều hành cô lập bộ nhớ tiến trình, nhưng nhiều tài nguyên hệ thống như hệ thống tệp, tệp cấu hình và thư viện động vẫn ở trạng thái dùng chung
    • Việc cài nhiều ứng dụng có yêu cầu thư viện động xung đột trên cùng một máy là cực kỳ khó
    • Cũng có thể phát sinh can nhiễu ngoài ý muốn giữa các tiến trình như xung đột cổng mạng
  • Có thể giải quyết bằng cách chạy từng ứng dụng trong máy ảo(VM) riêng, nhưng cách này rất nặng do trùng lặp kernel, hệ thống tệp, cache, bridge network...
    • Vì mỗi guest OS hoạt động độc lập nên việc khử trùng lặp lưu trữ và bộ nhớ cũng rất khó
  • chroot() của Unix v7 năm 1978 cho phép dùng hệ thống tệp gốc riêng, nhưng không hỗ trợ ghép hệ thống tệp cho nhiều ứng dụng
  • NixGuix giải quyết bằng cách đóng gói lại theo thư mục cho từng ứng dụng + liên kết động, nhưng khó áp dụng cho phần mềm độc quyền và không giải quyết được vấn đề xung đột cổng mạng
  • Docker chọn namespace của Linux: cho phép mỗi tiến trình điều khiển riêng cách truy cập các tài nguyên dùng chung như tệp và thư mục
    • Ví dụ: hai tiến trình ở các namespace khác nhau có thể diễn giải /etc/passwd thành /alice/etc/passwd/bob/etc/passwd khác nhau
    • Namespace chỉ được áp dụng khi mở tài nguyên; sau đó file descriptor hoạt động như tài nguyên kernel thông thường mà không có overhead bổ sung
  • Lịch sử đưa namespace vào Linux
    • Năm 2001, Linux 2.5.2: mount namespace
    • Năm 2006, Linux 2.6.19: IPC namespace
    • Năm 2007, Linux 2.6.24: network stack namespace
    • Hỗ trợ tổng cộng 7 loại namespace
  • Không giống Plan 9, namespace không được thiết kế ngay từ đầu mà được bổ sung dần dần, nên ở mức low-level và khó sử dụng
  • Các tính năng tương tự trên FreeBSD và Solaris cũng không đạt tới mức sử dụng đại chúng
  • Đóng góp cốt lõi của Docker năm 2013: tìm ra điểm cân bằng thực dụng giữa sự cô lập nặng nề của VMtính dễ dùng của các thành phần cơ bản của hệ điều hành

Cấu trúc thực thi container Linux của Docker

  • Docker có cấu trúc client-server, gồm daemon máy chủ chạy trên host (dockerd) và client CLI gửi yêu cầu qua RESTful API
  • Khoảng năm 2015, daemon nguyên khối được tách ra và tái cấu trúc thành các thành phần chuyên biệt
    • BuildKit: lắp ráp ảnh hệ thống tệp
    • containerd: khởi tạo image thành container đang chạy và quản lý tài nguyên mạng, lưu trữ

Container image

  • Khi gọi docker build, Docker tạo image hệ thống tệp phân lớp biểu diễn các tệp thực thi và dữ liệu trong Dockerfile
    • Lớp thấp nhất: bản phân phối hệ điều hành như Debian hoặc Alpine Linux (hoặc được lắp ráp thủ công từ tar archive)
    • Các lớp phía trên: khác biệt hệ thống tệp sinh ra từ kết quả thực thi từng lệnh riêng lẻ trong Dockerfile
  • Được lưu trong hệ thống lưu trữ định địa chỉ theo nội dung: dùng hash của image hệ thống tệp làm khóa
    • Khử trùng lặp hiệu quả, bảo đảm tính bất biến, và xác minh sửa đổi thông qua hash
  • Năm 2016, Open Container Initiative(OCI) chuẩn hóa định dạng image, và hiện có nhiều triển khai độc lập
  • Tận dụng các hệ thống tệp Linux như overlayfs, btrfs, ZFS để snapshot và clone hiệu quả các lớp copy-on-write
  • Hỗ trợ lazy-pulling image thông qua storage snapshotter stargz

Container instance

  • Khi gọi docker run, Docker cấp phát tài nguyên hệ thống để tạo tiến trình được cô lập bằng namespace ("container") từ OCI image
  • containerd thiết lập động các namespace cần thiết cho từng container và thực hiện các tác vụ sau:
    • Định nghĩa cgroups(control groups) của tiến trình để cô lập tài nguyên và giới hạn tốc độ I/O
    • Ánh xạ lại cổng mạng cục bộ bên trong container sang cổng được công khai ra ngoài trên giao diện host
    • Gắn storage volume có thể thay đổi của hệ thống tệp host để duy trì trạng thái ứng dụng bền vững
    • Cô lập cây tiến trình của container bằng PID namespace
    • Dùng user namespace để ánh xạ UID cục bộ trong container sang UID khác trên host (ví dụ: UID 1000 trong container → UID 12345 hoặc 23456 trên host)
  • Việc cấu hình namespace có một chút overhead, nhưng thấp hơn rất nhiều so với khởi tạo toàn bộ Linux VM, và phần lớn dưới 1 giây
  • Kernel Linux thu gom rác các container đã kết thúc như các tiến trình thông thường

Vượt ra ngoài Linux: hỗ trợ macOS và Windows

  • Nhờ kiến trúc client-server, CLI có thể gửi lệnh tới instance Docker từ xa qua kết nối mạng an toàn
  • Năm 2015, Docker đã được chấp nhận rộng rãi trong phát triển Linux, nhưng vấp phải rào cản về tính khả dụng khi nhà phát triển macOS/Windows không thể chạy container Linux
    • Phần lớn nhà phát triển dùng macOS/Windows làm môi trường phát triển chính, nhưng image hệ thống tệp Docker chỉ có thể chạy trên kernel Linux
    • Cùng với sự trỗi dậy của public cloud, Linux trở thành môi trường được ưa chuộng để triển khai

Xây dựng ứng dụng Docker for Mac

  • Ràng buộc cốt lõi: phải hoạt động mà không cần cấu hình bổ sung đối với các nhà phát triển đã quen với Docker bản Linux, đồng thời có thể chạy cùng một image Docker
  • Đảo ngược cách làm trước đây (chạy Linux riêng bên cạnh hệ điều hành desktop), bằng cách nhúng hypervisor bên trong ứng dụng không gian người dùng trên macOS/Windows và chạy Linux trong đó
    • Lấy cảm hứng từ nghiên cứu unikernel: chứng minh rằng các thành phần hệ điều hành có thể được nhúng linh hoạt vào bên trong các ứng dụng lớn hơn
  • HyperKit: một library VMM chạy nhân Linux trong tiến trình người dùng thông thường bằng cách sử dụng các phần mở rộng ảo hóa phần cứng của CPU Intel
    • Nhân Linux được nhúng chạy Docker daemon, daemon này quản lý container và đóng vai trò là endpoint máy chủ Docker thông thường
    • Mọi chi tiết quản lý Linux đều được ẩn bên trong ứng dụng desktop → docker builddocker run trên desktop được chuyển tới phiên bản Linux được nhúng và "cứ thế mà chạy"
  • Cách tiếp cận này sau đó cũng được các hệ thống container khác như Podman áp dụng, trở thành phương thức tiêu chuẩn để chạy container trên macOS/Windows

LinuxKit: bản phân phối Linux tùy biến nhúng

  • Một bản phân phối Linux tùy biến được thiết kế để nhúng làm thành phần của ứng dụng khác, thay vì chạy độc lập
  • Xây dựng không gian người dùng tùy biến chỉ gồm các thành phần tối thiểu cần để chạy container Docker, nhằm giảm tối đa thời gian khởi động ứng dụng
  • Chạy mọi thành phần đơn lẻ bên trong container, nên ở root namespace dùng khi khởi động không chạy gì cả
  • Tận dụng cùng hệ thống tập tin copy-on-write và network namespace mà container Docker sử dụng
  • Kết hợp LinuxKit + HyperKit cho phép khởi động tiến trình Linux với tốc độ gần như tương đương tiến trình macOS native
  • Ra mắt trong ứng dụng Docker for Mac và Windows vào năm 2016

Vấn đề mạng và giải pháp SLIRP

  • Kết nối mạng từ container Linux nhúng sang macOS/Windows là một vấn đề khó hơn dự kiến
  • Cách dùng Ethernet bridging trước đây đòi hỏi quản lý mạng phức tạp, và tường lửa/trình kiểm tra virus trên desktop doanh nghiệp phát hiện đó là lưu lượng có khả năng độc hại, khiến hàng nghìn báo cáo lỗi từ người dùng beta xuất hiện
  • Giải pháp SLIRP: công cụ lần đầu được dùng vào giữa thập niên 1990 để kết nối Palm Pilot PDA với Internet
    • Khi container thực hiện bắt tay TCP, frame Ethernet được truyền tới host qua bộ nhớ chia sẻ bằng giao thức virtio
    • Tận dụng thư viện unikernel của MirageOS để chuyển các yêu cầu mạng Linux thành các lời gọi socket native của macOS/Windows
    • Stack TCP/IP không gian người dùng vpnkit viết bằng OCaml nhận các yêu cầu này trên hệ điều hành host rồi gọi syscall macOS connect()
    • Từ góc nhìn chính sách VPN, lưu lượng đi ra được nhận diện là phát sinh từ ứng dụng Docker chứ không phải từ một máy riêng biệt
  • Sau khi triển khai vpnkit trong giai đoạn beta năm 2016, số báo cáo lỗi từ người dùng doanh nghiệp đã giảm hơn 99%
  • Cách tiếp cận SLIRP sau đó còn được áp dụng trong lĩnh vực cloud serverless, nơi kỹ thuật mạng thời dial-up cũ được dùng để giải quyết bài toán quản lý container mới

Xử lý lưu lượng mạng đầu vào

  • Khi container Linux lắng nghe trên một cổng, nó sẽ không tự động bị phơi ra Internet nếu CLI không được yêu cầu rõ ràng (ví dụ: docker run -p 80:80 nginx)
  • Trải nghiệm người dùng lý tưởng: cổng của container xuất hiện trực tiếp trên IP của desktop để có thể truy cập từ trình duyệt qua http://localhost:8080
    • Các nền tảng ảo hóa desktop cũ như VMware Fusion hiển thị một IP trung gian tạm thời thay vì localhost
  • Cài đặt chương trình eBPF tùy biến vào nhân LinuxKit → kích hoạt việc tạo socket lắng nghe tương ứng trên host desktop → bật bộ chuyển tiếp cổng
  • Kết quả: khi chạy container Linux trên Mac, có thể truy cập ngay qua localhost, mang lại trải nghiệm nhà phát triển giống hệt máy Linux native

Lưu trữ

  • Nhà phát triển cần chỉnh sửa mã cục bộ trong khi chạy mã và bài kiểm thử trong container
  • Trên Linux, có thể truy cập tập tin trực tiếp theo thời gian thực qua bind mount bằng docker run -v /host:/container
  • macOS và Windows dùng nhân khác nên bind mount không hoạt động
    • Docker sử dụng giao thức bộ nhớ chia sẻ virtio-fs bắt nguồn từ hypervisor KVM để chuyển các thao tác hệ thống tập tin tới host (ở dạng yêu cầu FUSE)
    • Host nhận các yêu cầu này rồi gọi các syscall open, read, write tương ứng
  • Mã và dữ liệu của nhà phát triển vẫn nằm trên hệ thống tập tin của host, nên các công cụ sao lưu và tìm kiếm như Time Capsule hay Spotlight của Apple vẫn có thể truy cập

Windows Services for Linux (WSL)

  • Năm 2017, Microsoft ra mắt WSL: chạy trực tiếp ứng dụng Linux trên Windows
    • Phiên bản đầu tiên dùng cách tiếp cận library OS, chuyển đổi động system call của binary Linux sang system call Windows thay vì dùng ảo hóa
    • Thành công với nhiều ứng dụng, nhưng thiếu các system call được hỗ trợ để chạy container Docker
  • Năm 2018, WSL2 ra mắt: được thiết kế lại theo cách chạy Linux VM đầy đủ ở nền, tương tự Docker for Mac
    • Docker trên WSL2 chạy daemon và container người dùng bên trong bản phân phối LinuxKit WSL
    • Xử lý Docker API và chuyển tiếp cổng mạng từ chính Windows và từ các bản phân phối Linux khác
  • Kiến trúc cốt lõi giúp container Docker tiến hóa đa nền tảng: cách tiếp cận library OS, tái sử dụng phần vốn được xem là "mã chỉ dành cho nhân" thành thư viện không gian người dùng để nhúng vào ứng dụng khác
  • Thành công của kiến trúc này được chứng minh ở chỗ nó vô hình nhưng hiện diện khắp nơi: hàng triệu nhà phát triển dùng Docker mỗi ngày mà không phải bận tâm nó đang chạy trên hệ điều hành nào

Quy trình làm việc mới cho nhà phát triển: đa kiến trúc CPU

  • Trong giai đoạn đầu của Docker, phần lớn workload trên cloud dựa trên kiến trúc Intel
  • Tình hình thay đổi khi Amazon Graviton ARM ra mắt năm 2018 và CPU Apple M1 ARM ra mắt năm 2020
    • Chạy workload trên ARM có thể giảm chi phí và tăng hiệu năng
  • Cần hỗ trợ nhiều kiến trúc CPU như Intel, ARM, POWER và RISC-V trong cùng một image Docker
  • Ở phía máy chủ, định dạng image OCI được mở rộng thành multiarch manifests
  • Để build image cho nhiều kiến trúc CPU trên một host duy nhất, sử dụng tính năng binfmt_misc của Linux
    • Thông qua QEMU, có thể chuyển đổi minh bạch giữa binary ARM và Intel
    • Overhead chủ yếu chỉ phát sinh ở giai đoạn build, còn image đa kiến trúc kết quả sẽ chạy native trên bất kỳ host nào
  • Apple đưa vào hỗ trợ phần cứng và phần mềm cho việc chuyển đổi tập lệnh CPU thông qua Rosetta → dễ dàng tích hợp vào kiến trúc Docker
  • Hiện nay, việc chạy song song container Intel và ARM đã trở thành quy trình làm việc phổ biến của nhà phát triển

Quản lý bí mật bằng môi trường thực thi tin cậy (TEE)

  • Trong môi trường container, quản lý bí mật (secrets) như mật khẩu hay API key luôn là một bài toán khó
    • Cần tiêm động thay vì bake trực tiếp vào image hệ thống tệp
  • Docker hỗ trợ socket forwarding, cho phép mount socket miền cục bộ vào container
    • Với Docker for Mac/Windows, còn có thể forward socket tới Linux VM
    • Có thể dùng các hệ thống quản lý khóa như ssh-agent bên trong container mà không phải trực tiếp lộ khóa
  • Socket forwarding cung cấp mức bảo vệ cơ bản, nhưng trước phần mềm độc hại trong chuỗi cung ứng phần mềm ngày càng mở rộng thì vẫn cần nhiều lớp phòng vệ hơn
  • Áp dụng trực tiếp bảo vệ hypervisor vào bên trong container runtime để nâng cao mức độ bảo vệ giữa các container
  • Môi trường thực thi tin cậy (TEE): tính năng phần cứng của CPU hiện đại cho phép tạo ra "VM bảo mật (confidential VMs)" có thể bảo vệ dữ liệu bí mật ngay cả khỏi host OS
    • Có thể áp dụng giới hạn truy cập dữ liệu vượt qua ranh giới ứng dụng, kernel và hypervisor
    • Tuy nhiên, việc cấu hình và sử dụng TEE cũng có độ phức tạp trong vận hành tương tự ảo hóa hệ điều hành
  • Nhóm làm việc Confidential Containers đang phát triển ứng dụng chạy trong TEE và được quản lý bằng Docker
    • Docker CLI thực hiện chuyển tiếp thông điệp được mã hóa từ TEE cục bộ trên desktop, qua host, tới môi trường TEE đám mây từ xa
    • Nhà phát triển có thể xác thực vào môi trường đám mây nhạy cảm mà không cần đến tận nơi, còn thông tin xác thực được lưu an toàn trong enclave trên desktop

Hỗ trợ GPGPU cho workload AI

  • Sự trỗi dậy của workload AI đã tạo ra một thách thức hoàn toàn mới: phần lớn workload machine learning chạy trên GPU
  • Vấn đề cốt lõi: workload GPU cần kernel GPU driver và thư viện user-space khớp chính xác, trong khi nhiều container chạy trên một kernel dùng chung
    • Nếu hai ứng dụng yêu cầu các phiên bản khác nhau của cùng một kernel GPU driver, thì sẽ phát sinh đúng xung đột nền tảng mà Docker vốn được tạo ra để giải quyết
  • Từ tháng 3/2023, Docker hỗ trợ CDI (Container Device Interface)
    • Tùy biến image hệ thống tệp tại thời điểm khởi động container
    • Bind mount các file thiết bị GPU và thư viện động dành riêng cho GPU, rồi tái tạo cache ld.so
  • CDI đảm bảo tính di động của image giữa một số lớp GPU và nhà cung cấp nhất định, nhưng giữa các OS hay thương hiệu phần cứng khác nhau thì vẫn chưa hoàn toàn liền mạch
    • Các thư viện động do CDI bổ sung định nghĩa những API khác nhau, nên không có thứ gì tương đương với Linux system call ABI ổn định vốn là giao diện truyền thống của container
    • Lý do ứng dụng cho Nvidia GPU khó chạy trên CPU Apple dòng M: hỗ trợ ảo hóa GPU vẫn chưa đủ trưởng thành để chuyển đổi lệnh vector giữa các phần cứng khác nhau
  • Docker đang hợp tác với cộng đồng container và các nhà sản xuất GPU để phát triển cách linh hoạt và an toàn hơn trong quản lý phụ thuộc liên quan đến GPU
  • Kỳ vọng sáng kiến giao diện di động (portable interface) sẽ đạt được đồng thuận

Kết luận

  • Docker khởi đầu vào năm 2013 với mục tiêu giúp nhà phát triển dễ dàng build, chia sẻ và chạy ứng dụng hơn
  • Hiện nay, nó đã được tích hợp sâu vào quy trình phát triển chuẩn trên cloud và desktop, được hàng triệu nhà phát triển trên toàn thế giới sử dụng mỗi ngày, xử lý hàng tỷ yêu cầu mỗi tháng
  • Một mục tiêu xuyên suốt là duy trì cộng đồng mã nguồn mở năng động và đa dạng nhằm xây dựng các tiêu chuẩn cho khả năng tương tác
    • CNCF (Cloud Native Computing Foundation) đóng vai trò quản trị nhiều thành phần cốt lõi
    • Open Container Initiative (thuộc Linux Foundation) quản lý định dạng image
  • Ngày nay có nhiều triển khai của các thành phần này đang hoạt động tích cực, và việc triển khai đang gia tăng ở cloud, desktop và các môi trường edge như ô tô, thiết bị di động, tàu vũ trụ
  • Tính đến năm 2025, quy trình làm việc điển hình của nhà phát triển đã tích hợp kiểm thử và triển khai liên tục, IDE language server, cùng hỗ trợ AI thông qua agentic coding
  • Từ góc nhìn của Docker, workflow cốt lõi "build and run" vẫn rất giống 10 năm trước, nhưng hỗ trợ hệ thống nhằm giảm ma sát trong nhiều môi trường khác nhau đã được tăng cường đáng kể
  • Mục tiêu là biến Docker thành người bạn đồng hành vô hình giúp nhà phát triển triển khai mã nhanh hơn, đồng thời được thiết kế để có thể mở rộng phù hợp với workflow lập trình AI hiện đại

1 bình luận

 
GN⁺ 2026-03-08
Ý kiến trên Hacker News
  • Khi Docker mới ra mắt, tôi đã chán ngấy với việc cứ thứ gì cũng bị gọi là “cách mạng”
    Tôi không thích những thứ như NoSQL nửa vời, microservices bị áp dụng một cách máy móc, hay xu hướng biến mọi lời gọi hàm thành RPC
    Nhưng giờ thì tôi dùng nó khá thường xuyên vì sự đơn giản của nó
    Chỉ là container của người khác thì vẫn như địa ngục. Ít nhất tôi cố giữ mọi thứ đơn giản, nhưng có người nhét vào quá nhiều thứ đến mức có cảm giác chính họ cũng không biết quy trình deploy hoạt động ra sao
    Giờ có vẻ chúng ta đã bước vào thời đại mà code do LLM tạo ra được đổ ra ào ạt, đến mức chính lập trình viên cũng chưa từng xem qua

    • Mỗi sáng sớm nhìn đội DevOps mở những cuộc gọi Zoom bất tận để xử lý sự cố container, tôi càng chắc rằng chẳng ai thực sự biết chuyện gì đang diễn ra
  • Dù đã có vô số thử nghiệm, lý do Dockerfile còn sống sót đến giờ rốt cuộc vẫn là vì tính linh hoạt
    Cấu trúc copy file rồi chạy lệnh giống cách vận hành trước đây nên ai cũng thấy quen thuộc
    Nhìn thì có vẻ thô, nhưng kiểu linh hoạt đơn giản này có lẽ vẫn sẽ là dòng chủ đạo trong tương lai

    • Vì không có công cụ build trung lập với ngôn ngữ, cuối cùng người ta vẫn phải chạy các lệnh tùy ý để gọi package manager theo từng ngôn ngữ
      Nếu ai cũng dùng Nix hay Bazel thì có lẽ docker build đã trở thành trò cười rồi
    • Có những rào cản ngăn cản reproducible build
      Nếu hash khác nhau giữa các lần build thì không thể tin cậy được, nên chừng nào những yếu tố như thời gian sửa file vẫn còn được đưa vào hash thì rất khó đạt được sự nhất quán hoàn toàn
    • Điểm nghẽn của các giải pháp thay thế là thiếu một kho lưu trữ trung tâm như Docker registry
      Cá nhân tôi thích mkosi, nhưng không phải ai cũng muốn bắt đầu từ một OS template trống
    • Nix rất xuất sắc trong việc tạo Docker container
    • Tôi ước gì sự gắn kết với registry mạnh hơn một chút
      Trong đa số trường hợp, người ta chỉ pull từ public registry rồi push sang private registry, nên image local hầu như không được dùng đến
      Hơi kém hiệu quả, nhưng có vẻ vẫn chưa đủ bất tiện để buộc phải thay đổi
  • Tôi nhớ Docker lần đầu được công bố tại PyCon US Santa Clara năm 2013
    Xem video bài phát biểu trên YouTube thời đó thì đúng là một khoảnh khắc lịch sử
    Có vẻ đã có chút nhầm lẫn vì thời điểm công bố bài báo và thời điểm trình bày thực tế khác nhau, nhưng đại khái là chuyện từ khoảng 13 năm trước

    • Tiêu đề chỉ đơn giản mang ý nghĩa “nhìn ngược về quá khứ”
      “A decade of Docker” nghe tự nhiên hơn “Twelve years of Docker containers”
    • Thực ra là năm 2014 mới đúng
      Tôi nhớ bài đăng công bố ban đầu trên HN
      Khi đó tôi đã quá mệt mỏi với những lựa chọn thay thế như LXC hay Vagrant, và Docker thực sự giống như một vị cứu tinh
  • Điều thú vị là Docker đã tái sử dụng công cụ quay số SLIRP từ thập niên 1990 để vượt tường lửa

    • Podman cũng từng dùng slirp4netns, nhưng gần đây đã chuyển sang Pasta
    • SLIRP không phải dành cho Palm Pilot, mà là một tiện ích được tạo ra để người dùng shell account có thể giả lập kết nối Internet khi họ không dùng được SLIP/PPP
      Nó không hỗ trợ kết nối đi vào, nhưng là một ý tưởng giống như tiền thân của NAT
    • Việc lấy công cụ cho Palm Pilot để vượt tường lửa là một ý tưởng điên rồ, nhưng chính kiểu tuyệt vọng đó lại tạo ra những cú hack hạ tầng tốt nhất
    • SLIRP là dành cho network namespace kiểu ‘rootless’, tức là cách gắn container vào mạng host mà không cần quyền root
  • Tôi từng muốn dùng Docker, nhưng mỗi lần thử thì nó lại thiếu đúng tính năng tôi cần
    Chắc là vì tôi dùng một stack kỹ thuật khá hiếm

  • Sự vĩ đại của Docker là nó đã biến câu “chạy được trên máy tôi” thành tiêu chuẩn công nghiệp
    Giờ thì chúng ta sống trong thời đại có thể “giao nguyên cái máy đó” lên production

    • Với tư cách là đồng tác giả, trước Docker tôi làm việc với Xen, và Docker đúng là một biến cố làm thay đổi cả văn hóa IT
      Ngày trước deploy là một quy trình khổng lồ, còn bây giờ có thể deploy thẳng cả filesystem
      Cuộc cách mạng coding agent hiện nay cũng cho tôi cảm giác giống một bước chuyển văn hóa như vậy
    • Điểm cốt lõi của Docker là nó buộc người ta phải ghi lại quá trình build thành một quy trình có thể lặp lại
      Nếu có thể tái tạo môi trường bằng một script 10 dòng thì việc “deploy cả cái máy” cũng chẳng phải ý tưởng tệ
    • Docker là một dạng liên kết tĩnh cực đoan
      Có lẽ chúng ta nên tự hỏi vì sao cách tiếp cận này lại hấp dẫn đến thế
    • “Chạy ngon trên laptop” giờ dường như đã biến thành “hãy biến cái laptop thành container rồi nhét vào pipeline”
      Lý do abstraction luôn thắng là vì sửa tận gốc vấn đề quá khó
    • Thật nản khi thấy những container tệ hại cố dùng Dockerfile để quản lý cả service thay vì có một hệ thống đóng gói tử tế
  • Tôi không rành networking lắm, nhưng trên Mac tôi muốn container có một địa chỉ IP riêng
    Tôi muốn truy cập bằng container_ip:80 mà không cần port mapping
    Trên Linux thì làm được, nhưng trên Mac phải đi qua VM nên khá phức tạp
    Tôi đã thử cách làm dựa trên WireGuard, nhưng cứ mỗi lần Docker update là lại hỏng
    Giá mà có một cách được hỗ trợ chính thức thì tốt

    • Với tư cách kỹ sư Docker, tôi khuyên bạn thử Tailscale extension
      Tailscale Docker Extension sẽ tự xử lý phần cấu hình
      Nếu lý do bạn muốn tránh port mapping là vì port động, hãy thử tùy chọn --net=host và bật thiết lập Host Networking
    • Tôi không có máy Mac, nhưng có thể gợi ý phương án thay thế mã nguồn mở là dự án Colima
  • Năm 2013 đúng là một mùa bội thu của packaging, khi Docker, Guix và NixOS đều xuất hiện
    Tôi phát hiện ra điều này khi viết bài báo liên quan
    Từ đó tôi cũng tò mò không biết đã từng có năm nào khác mà nhiều dự án xuất sắc như vậy lại cùng ra đời hay chưa

    • hg và git ra mắt chỉ cách nhau vài tuần, rồi fossil cũng xuất hiện ngay sau đó
    • Nói thật thì tôi thấy chỉ có Docker là thực sự thành công ở quy mô đại chúng
      Guix và Nix vẫn chủ yếu chỉ nằm trong một nhóm người dùng thiểu số
  • Khi ML và AI xuất hiện ở khắp nơi, kích thước image đã phình to theo cấp số nhân
    Chỉ riêng torch thôi cũng đã ngốn vài GB
    Tôi nhớ những image 30MB ngày xưa

    • Tôi còn từng thấy image cài TensorFlow hai lần
      Không thể chia sẻ file giữa các layer nên mức độ lãng phí rất lớn
      Vì thế tôi đang tự xây một registry thay thế hỗ trợ dedupe ở cấp độ file
    • Tôi hiện đang chạy vài container Ruby và PHP trên nền Alpine Linux bất biến dựa trên ISO, và toàn bộ chỉ khoảng 750MB
  • Tôi thấy chuyện Docker đã ngụy trang như VPN để đánh lừa phần mềm bảo mật doanh nghiệp thật sự rất thú vị
    Xét như một câu chuyện lịch sử kỹ thuật thì đây cũng là một ví dụ rất hay