Ngày 28 tháng 5 năm 2023 - Máy tính Bài trước “Khám phá Docker” đã giới thiệu các khái niệm cơ bản và cách sử dụng Docker. Bài viết này sẽ tiếp tục trình bày một số thực hành tốt nhất khi làm việc với Docker.
1. Thực hành tối ưu kích thước hình ảnh (image)
Khi khởi chạy một container, một hình ảnh có kích thước nhỏ sẽ được tải qua mạng nhanh hơn và cũng dễ dàng được nạp vào bộ nhớ hơn.
Dưới đây là một số kinh nghiệm để giảm kích thước hình ảnh:
-
Chọn hình ảnh nền phù hợp: Sử dụng hình ảnh nền nhỏ nhất nhưng vẫn đáp ứng yêu cầu của ứng dụng. Ví dụ: Nếu ứng dụng cần JDK, bạn nên chọn hình ảnh nền chính thức
openjdk
thay vì sử dụng hình ảnhubuntu
rồi cài đặt thêmopenjdk
. -
Sử dụng xây dựng đa giai đoạn (multi-stage build): Ví dụ: Đối với ứng dụng Java được quản lý bởi Maven, bạn có thể tạo hai giai đoạn trong
Dockerfile
. Giai đoạn đầu tiên sử dụng hình ảnhmaven
để biên dịch mã nguồn Java thành góijar
hoặcwar
. Giai đoạn thứ hai sử dụng hình ảnhtomcat
, sao chép góijar
hoặcwar
từ giai đoạn đầu tiên vào vị trí thích hợp. Kết quả cuối cùng chỉ bao gồm phần của giai đoạntomcat
, không bao gồm môi trường biên dịch hay các thư viện phụ thuộc, mà chỉ giữ lại những gì cần thiết để chạy ứng dụng.
Tham khảo chi tiết về cách viết Dockerfile
cho phương pháp này trong bài viết trước iwin58 “Xây dựng hình ảnh hiệu quả bằng cách Tipgamebai Game Bài 247 sử dụng multi-stage builds”.
- Giảm số lớp của hình ảnh: Thử hợp nhất các lệnh
RUN
riêng lẻ trongDockerfile
để giảm số lớp của hình ảnh. Hai đoạn mã sau minh họa điều này: Đoạn mã đầu tiên tạo ra hai lớp trong hình ảnh, trong khi đoạn mã thứ hai chỉ tạo ra một lớp.
RUN apt-get -y update
RUN apt-get install -y python
RUN apt-get -y update && apt-get install -y python
- Tạo hình ảnh nền chung tùy chỉnh: Trong dự án của chúng ta, có thể nhiều hình ảnh có phần lớn nội dung giống nhau. Bạn có thể trích xuất phần chung để tạo hình ảnh nền chung tùy chỉnh, sau đó xây dựng các phần tùy chỉnh cụ thể dựa trên hình ảnh nền này. Điều này giúp Docker chỉ cần tải một lần lớp công cộng, sau đó lưu vào cache, giúp các hình ảnh phái sinh tải nhanh hơn.
2. Thực hành lưu trữ dữ liệu ứng dụng bền vững
-
Tránh lưu trữ dữ liệu trong lớp ghi của container: Không nên sử dụng trình điều khiển lưu trữ để lưu trữ dữ liệu ứng dụng trong lớp ghi của container. Điều này sẽ làm tăng kích thước container và hiệu suất I/O thấp hơn so với việc sử dụng tập tin卷 (Volume) hoặc gắn kết (Bind Mounts).
-
Tránh sử dụng gắn kết trong môi trường sản xuất: Mặc dù gắn kết (Bind Mounts) rất tiện lợi trong quá trình phát triển, chẳng hạn như gắn thư mục mã nguồn hoặc tệp nhị phân vào container, nhưng trong môi trường sản xuất, không nên sử dụng gắn kết mà thay vào đó hãy sử dụng tập tin卷 (Volume).
-
Lưu trữ dữ liệu nhạy cảm và không nhạy cảm riêng biệt: Trong môi trường sản xuất, nên lưu trữ dữ liệu nhạy cảm và không nhạy cảm riêng biệt. Ví dụ: Nếu bạn đang sử dụng nền tảng Kubernetes, bạn có thể sử dụng
Secret
để lưu trữ dữ liệu nhạy cảm vàConfigMap
để lưu trữ dữ liệu không nhạy cảm như các tệp cấu hình. Với Swarm, bạn có thể sử dụngSecret
cho dữ liệu nhạy cảm vàConfig
cho dữ liệu không nhạy cảm.
3. Thực hành đảm bảo sự ổn định và an toàn của hình ảnh
Sau khi sửa đổi mã nguồn ứng dụng và tạo yêu cầu kéo (Pull Request) trong hệ thống kiểm soát mã nguồn, bạn nên sử dụng quy trình CI/CD tự động để xây dựng hình ảnh, kiểm tra hình ảnh và đánh dấu hình ảnh.
Để đảm bảo sự ổn định và an toàn của hình ảnh trước khi triển khai vào môi trường sản xuất, nhóm phát triển, thử nghiệm và an ninh cần phải ký tên vào hình ảnh.
4. Thực hành xử lý sự khác biệt giữa môi trường phát triển và sản xuất
-
Sử dụng cách gắn kết khác nhau: Môi trường phát triển cục bộ có thể sử dụng gắn kết (Bind Mounts) để thuận tiện hơn (chẳng hạn như truy cập vào thư mục mã nguồn), trong khi môi trường sản xuất nên sử dụng tập tin卷 (Volume) thay vì gắn kết.
-
Cài đặt Docker khác nhau: Cài đặt Docker Desktop trong môi trường phát triển sẽ tiện lợi hơn; trong khi đó, trong môi trường sản xuất, bạn nên cài đặt Docker Engine và kết hợp với ánh xạ không gian người dùng để cách ly quy trình Docker khỏi quy trình máy chủ tốt hơn.
-
Xử lý khác biệt về thời gian đồng hồ: Trong môi trường phát triển cục bộ, bạn không cần lo lắng về vấn đề sai lệch thời gian; nhưng trong môi trường sản xuất, bạn nên cài đặt khách hàng NTP (Network Time Protocol) trên máy chủ Docker và mỗi quy trình container, và đồng bộ trạng thái của chúng với cùng một máy chủ NTP. Nếu bạn đang sử dụng nền tảng dàn xếp container (orchestration platform) như Kubernetes hoặc Swarm, bạn cũng cần đảm bảo rằng đồng hồ của Node và container được đồng bộ hóa với cùng một nguồn thời gian.
Tóm lại, bài viết này đã tóm tắt một số thực hành tốt nhất khi sử dụng Docker, bao gồm: thực hành tối ưu kích thước hình ảnh, thực hành lưu trữ dữ liệu ứng dụng bền vững, thực hành đảm bảo sự ổn định và an toàn của hình ảnh, và thực hành xử lý sự khác biệt giữa môi trường phát triển và sản xuất. Hy vọng rằng khi làm việc với Docker trong công việc hàng ngày, chúng ta có thể tuân theo những thực hành này.
[1] Các thực hành tốt nhất trong phát triển Docker | Tài liệu Docker - docs.docker.com