Giai đoạn 7 - Bộ chứa và Ảo hóa
Xin chào quý vị. Đây sẽ là giai đoạn 7 - giai đoạn tiếp theo của hành trình 90 ngày cùng DevOps. Trong giai đoạn này, chúng ta sẽ tìm hiểu về bộ chứa và ảo hóa (Containers/Virtualization), cụ thể nhất chính là Docker. Nhưng trước khi đi vào Docker thì câu hỏi đặt ra sẽ là:** Tại sao lại phải ảo hóa, tại sao lại phải sử dụng Docker trong phát triển ứng dụng?**
Hãy cùng đi vào phần tiếp theo của hành trình để tìm hiểu câu trả lời nhé! 🏕
Nguồn: Pro Landscaper
Ngày 36 - Một bức tranh toàn cảnh về Containers 🚚
Section titled “Ngày 36 - Một bức tranh toàn cảnh về Containers 🚚”Tại sao phải sử dụng Containers hay Máy ảo?
Section titled “Tại sao phải sử dụng Containers hay Máy ảo?”Một ngày bình thường như bao ngày. Bạn nhận được yêu cầu phải mang ứng dụng của công ty chuyển sang vận hành trên một máy khác có cấu hình khác biệt với cấu hình trên máy hiện thời. Bạn sẽ phải làm gì?
Bạn âm thầm đi dọn dẹp, chuẩn bị môi trường, cài đặt các thư viện, cấu hình môi trường, và cuối cùng là chạy ứng dụng. Tất nhiên, nó tiêu hao rất nhiều thời gian của bạn. Và rồi, khi nó báo lỗi “Không tương thích môi trường”, bạn quay lại chỗ của sếp và bảo rằng:
- Chúng ta cần một chiếc máy khác tương tự máy cũ để chạy ứng dụng.
Thật là điên rồ nếu bạn mỗi lần phải di chuyển giữa các máy, vì đó là ngân sách bị tiêu pha không hợp lý chút nào cả. Và tất nhiên, bạn muốn đóng gói toàn bộ môi trường vận hành của ứng dụng vào một nơi, và chuyển nó đi đâu cũng được, mà không cần phải lo lắng về cấu hình môi trường. Đây là lúc mà máy ảo và containers ra đời.
Máy ảo
Section titled “Máy ảo”Máy ảo là máy tính ảo, nó y chang máy tính thật nhưng chạy trên môi trường ảo hóa thôi. Nó cũng được cô lập với máy thật, và tất nhiên là vẫn có cách để máy ảo kết nối với Internet.
Bạn có thể có một máy thật, nhưng sẽ có nhiều hơn một máy ảo chạy trên máy thật. Mỗi máy ảo sẽ chứa một hệ điều hành và môi trường khác nhau.
Containers
Section titled “Containers”Đây là containers.
Dưới đây cũng là containers.
Hãy nhìn xem sự giống nhau của nó là gì? Đúng rồi, chúng đều đựng hàng hóa bên trong, và chúng ta có thể chuyển chúng đi đâu cũng được. Containers giống như một chiếc hộp chứa toàn bộ môi trường vận hành của ứng dụng, bao gồm cả mã nguồn ứng dụng và các thư viện cần thiết. Khi chúng ta cần chạy ứng dụng, chúng ta chỉ cần chạy container, và mọi thứ sẽ hoạt động như chúng ta đã mong muốn.
Về mặt cấu trúc, chiếc thuyền sẽ đóng vai trò là máy tính vật lý, còn container sẽ đóng vai trò là một máy ảo. Điều này giúp cô lập giữa máy thật và máy ảo. Tính mở rộng được nâng cao hơn khi bạn có thể triển khai bao nhiêu containers trên máy thật cũng được, không phải mỗi máy một ứng dụng, vấn đề duy nhất là dung lượng máy thật.
Mỗi ứng dụng sẽ tương ứng với một container, và trên máy tính sẽ có một engine - giúp chúng ta quản lý các container một cách tiện lợi hơn.
Ưu diểm của Containers
Section titled “Ưu diểm của Containers”- Container giúp đóng gói tất cả các gói phụ trợ bên trong và cô lập nó.
- Dễ dàng quản lý, mở rộng, di chuyển từ hệ thống này qua hệ thống khác các container.
Sử dụng các container, bạn có thể mở rộng các container và sử dụng bộ cân bằng tải hoặc một dịch vụ để phân chia lưu lượng và có thể mở rộng ứng dụng theo chiều ngang. Container cung cấp tính linh hoạt và dễ dàng trong việc quản lý các ứng dụng của mình.
Về nguyên tắc vận hành, containers như một máy ảo độc lập, nghĩa là nó sẽ không thay đổi bất kể bạn chạy nó ở máy tính nào. Tính phân ly mạnh này là điểm mấu chốt giúp containers trở nên khác biệt so với rất nhiều những phương pháp vận hành ứng dụng khác, dễ dàng và đơn giản hơn.
Image - Bản ảnh của Containers
Section titled “Image - Bản ảnh của Containers”Bản ảnh của Container chứa gì? Nó chứa tất cả mọi thứ. Từ mã nguồn ứng dụng, các thư viện cần thiết, cấu hình môi trường, … Hãy xem bản ảnh như một gói mầm/bộ khung nào đó. Khi bản ảnh được tải xuống và chạy, một container sẽ được tạo ra.
Nhìn cảnh này, chắc hẳn nếu ai mà là dân Công nghệ thông tin sẽ nghe loáng thoáng thuật ngữ tập tin ISO để cài hệ điều hành - Docker Image chính là một ISO đặc biệt như vậy đó.
Nếu bạn đã tò mò về cách Docker hoạt động - hãy trở lại trong bài viết tiếp theo nhé!
Ngày 37 - Docker & câu chuyện đầu tiên 📚
Section titled “Ngày 37 - Docker & câu chuyện đầu tiên 📚”Xin chào, đây là bài viết đầu tiên sau khoảng thời gian nghỉ lễ kéo dài, và đây sẽ là chuyến hành trình tiếp theo của chúng ta. Ngày hôm nay, chúng ta nhắc đến Docker và bản ảnh của nó, tìm hiểu cách biến một bản ảnh thành một hệ thống ứng dụng vận hành hoàn chỉnh.
Không tấu hài nữa, bắt đầu hành trình thôi! 🚋
Docker
Section titled “Docker”Docker, CRI-O, Podman, Containerd đều là những sản phẩm của tiêu chuẩn OCI - Open Container Initiative. Docker là một bộ khung dựa trên những tập tin cấu hình, được gọi là Dockerfile, giúp chúng ta tạo ra một bản ảnh của ứng dụng hoàn chỉnh. Ngoài Docker image ra, chúng ta cũng sẽ nhắc đến lớp nền chạy container, được gọi là Docker Engine.
Sử dụng Docker cũng khá đơn giản, việc cài đặt phiên bản giao diện (Desktop) chỉ cần thực hiện theo hướng dẫn tại dây. Lưu ý một số yêu cầu về thiết bị và hệ điều hành trước khi cài đặt.
À mà khoan, Docker Desktop là gì đây, và Docker còn có những gì, cùng tìm hiểu nhé.
Từ khóa Engine có nghĩa là động cơ, và Docker Engine chính là động cơ của Docker. Nó giúp chúng ta quản lý các container và hoạt động theo mô hình chủ - khách, bao gồm: Docker Daemon (máy chủ), API giao tiếp và Docker CLI (máy khách).
Docker Desktop
Section titled “Docker Desktop”Đây chẳng khác gì một IDE thực thụ cả - giúp chúng ta tạo ra các container, quản lý và chạy chúng. Docker Desktop có sẵn trên Windows và MacOS. Trên Windows còn có cả WSL2 (Windows Subsystem for Linux) và Hyper-V, và tất nhiên với WSL2, chúng ta có thể tương tác hẳn với Linux.
Sau khi tải xong Docker Desktop, hãy kiểm tra bằng lệnh sau để biết Docker có tồn tại trên máy hay chưa.
docker
Docker Compose
Section titled “Docker Compose”Compose trong tiếng Anh có nghĩa là sáng tạo, và Docker Compose chính là công cụ giúp chúng ta tạo ra một tập hợp các containers hình thành một ứng dụng phức tạp. Chỉ với một tập tin YAML đơn giản, chúng ta có thể làm được những điều vô cùng phi thường.
Hub là nơi chứa, và Dockerhub chính là nơi chứa các Docker image. Chúng ta có thể tìm kiếm, tải về và chia sẻ các bản ảnh để làm được gần như mọi thứ.
Tạo một tài khoản trên Dockerhub giúp bạn khám phá được rất nhiều bản ảnh dùng cho tất tần tật mọi ứng dụng từ lớn đến nhỏ.
Dockerfile
Section titled “Dockerfile”Xương sống của Docker image, Dockerfile chứa các hướng dẫn cần thiết để tạo ra một bản ảnh hoàn chỉnh. Hệ thống sẽ đọc các tập tin cấu hình này và thực hiện theo hướng dẫn.
Và tất nhiên, sẽ còn rất nhiều điều nữa sẽ được cập nhật, ngay trong bài viết này, hãy cùng chờ đón nhé!
Ngày 38 - Dáng hình của Docker 🖼
Section titled “Ngày 38 - Dáng hình của Docker 🖼”Xin chào, cuối cùng thì chúng ta cũng đã sẵn sàng cho ngày tiếp theo của hành trình đầy chông gai này. Hôm nay chúng ta sẽ tìm hiểu về Docker image, bản ảnh của Docker, và cách tạo ra một bản ảnh từ một Dockerfile.
Nếu bạn đã đóng gói đầy đủ tư trang, hãy cùng nhau bắt đầu hành trình mới này nhé! 🚋
Khởi động
Section titled “Khởi động”Sau khi cài đặt Docker, chúng ta sẽ bắt đầu bằng việc chạy câu lệnh sau.
docker run -d -p 80:80 docker/getting-started
Khi các bạn chạy lệnh này, những việc sau đây sẽ xảy ra.
- Docker sẽ tìm kiếm image
docker/getting-started
trên máy tính của bạn. Nếu không tìm thấy, Docker sẽ tải image này từ DockerHub hoặc bất kỳ registry lưu trữ nào có bản ảnh này. Việc này cũng sẽ diễn ra tương tự với các bản ảnh khác. - Docker sẽ tạo một container từ image này. Trong trường hợp này, container sẽ chạy một ứng dụng web trên cổng 80.
- Docker sẽ chuyển tiếp cổng 80 của máy tính của bạn tới cổng 80 của container (
-p
- port). - Việc chạy container này sẽ diễn ra ở chế độ nền (background mode) (
-d
- detach). - Kết quả cuối cùng, bạn sẽ có một ứng dụng hoàn chỉnh, khi truy cập vào
http://localhost/tutorial
trên trình duyệt.
Đối với các bản ảnh, chúng ta có thể phân loại làm ba nhóm như sau.
- Official Image: Là những bản ảnh được Docker cung cấp, chúng ta có thể tìm thấy trên DockerHub.
- Verified Publisher: Là những bản ảnh được xác thực bởi Docker, cung cấp bởi các nhà cung cấp phần mềm.
- User-defined images: Là những bản ảnh được tạo ra bởi người dùng và đăng tải trên DockerHub hoặc các registry khác.
Để dừng container đang chạy, cần phải xác định container ID
hoặc container name
và chạy lệnh sau.
docker psdocker stop <container ID or container name>
Tham vọng to lớn với cả một hệ điều hành…
Section titled “Tham vọng to lớn với cả một hệ điều hành…”docker run -it ubuntu bash
Khi bạn chạy lệnh này, ngay lập tức bạn có một bản ảnh của Ubuntu trên Docker với Bash.
Bạn có tin được không, nhưng đó là sự thật. Khi bạn chạy xong lệnh trên, bạn sẽ thấy một dấu nhắc mới, đó chính là một cửa sổ dòng lệnh của Ubuntu. Tất nhiên Ubuntu trên Docker chỉ cỡ đâu đó 30MB thôi, nhưng tất nhiên là bạn có thể thêm các gói phần mềm khác vào bản ảnh này.
Tìm hiểu về Dockerfile
Section titled “Tìm hiểu về Dockerfile”Dockerfile là một tập tin văn bản chứa một loạt các hướng dẫn để tạo ra một bản ảnh. Mỗi hướng dẫn trong Dockerfile thường được tổ chức theo dạng một “lớp” (layer) và mỗi lớp sẽ tạo ra một image mới.
Cấu trúc của các lớp, sẽ đi theo phương thức xếp chồng (stacked) và mỗi lớp sẽ kế thừa lớp trước đó.
Theo thứ tự, chúng ta sẽ có Dockerfile dựng thành image, và container thì chạy từ image đó. Mỗi bản ảnh sẽ còn có manifest. Manifest trong tiếng Anh có nghĩa là “bản thể”, và nó chứa thông tin về các lớp, cấu trúc, và metadata của bản ảnh.
Ví dụ về Dockerfile
Section titled “Ví dụ về Dockerfile”FROM node:18-alpineWORKDIR /app/COPY ./sources/ .RUN npm installEXPOSE 3000CMD ["npm", "start"]
Dưới đây là một số từ khóa hiệu lệnh của Dockerfile mà bạn sẽ thường xuyên gặp.
Lệnh | Mục đích |
---|---|
FROM | Để chỉ định bản ảnh gốc. |
WORKDIR | Để đặt thư mục làm việc cho bất kỳ lệnh nào phía sau trong Dockerfile. |
RUN | Để chạy lệnh giúp cài đặt bất kỳ ứng dụng và gói phụ trợ cần thiết cho container. |
COPY | Để sao chép các tệp hoặc thư mục từ một vị trí cụ thể. |
ADD | Là COPY, nhưng cũng có thể xử lý các URL và giải nén các tệp nén. |
ENTRYPOINT | Lệnh sẽ thực thi khi container khởi động. Mặc định là /bin/sh -c |
CMD | Các đối số truyền vào. Nếu ENTRYPOINT mặc định, CMD là lệnh thực thi. |
EXPOSE | Để xác định cổng truy cập ứng dụng container. |
LABEL | Để thêm metadata vào bản ảnh. |
Dựa trên Dockerfile phía trên ta sẽ có những bước sau.
- Lấy bản ảnh gốc (base image) từ
node:18-alpine
, tức là một bản ảnh của Node.js trên Alpine Linux. - Đặt thư mục làm việc cho container là
/app/
. - Sao chép tất cả các tệp từ thư mục
./sources/
vào thư mục làm việc của container. - Cài đặt các gói phụ trợ cần thiết cho ứng dụng Node.js.
- Mở cổng 3000 để truy cập ứng dụng.
- Chạy ứng dụng Node.js bằng lệnh
npm start
.
Lúc này, ta có thể truy cập ứng dụng Node.js thông qua cổng 3000 của máy tính
(đúng hơn là http://localhost:3000
).
Dựng Dockerfile
Section titled “Dựng Dockerfile”Chạy câu lệnh sau để dựng Dockerfile này thành bản ảnh mới.
docker build -t my-node-app:1.0 .# -t: tag cho bản ảnh# .: thư mục chứa Dockerfile
Và đó là cách bạn có một bản ảnh mới toanh, tự dựng từ một Dockerfile. 🎉
Compose - Sức mạnh của sự đoàn kết
Section titled “Compose - Sức mạnh của sự đoàn kết”Trường hợp khó hơn là đây - về mặt nguyên tắc, một ứng dụng không nên chỉ tập trung trên một container mà còn phải phân tán trên nhiều container để ngăn tình trạng Điểm chết duy nhất - Single Point of Failure. Điều này đặt ra một thách thức lớn với việc quản lý nhiều container cùng một lúc.
Docker Compose giúp chúng ta giải quyết vấn đề này bằng cách cho phép chúng ta định nghĩa và chạy nhiều container cùng một thời điểm. Sử dụng Compose cũng cực kỳ đơn giản, bởi chúng ta có thể tải xuống tại đây. Trong nội dung của bài viết này, chúng ta sẽ tạo một website đơn giản sử dụng WordPress và MySQL, và chúng ta sẽ dựa trên bài viết này dể bắt đầu. Okay, thử nghiệm thôi.
Gọi Compose
Section titled “Gọi Compose”docker-compose
Lệnh này, sau khi cài đặt Compose và chạy lên, sẽ giúp ta kiểm tra xem ứng dụng đã được cài đặt chuẩn xác hay chưa.
Tập tin Compose
Section titled “Tập tin Compose”version: "3.9"
services: DB: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress
wordpress: depends_on: - db image: wordpress:latest volumes: - wordpress_data:/var/www/html ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpressvolumes: db_data: {} wordpress_data: {}
YAML - YAML Ain’t Markup Language (YAML chả phải ngôn ngữ đánh dấu) là một ngôn ngữ tuần tự hóa dữ liệu dùng để biểu diễn dữ liệu dưới dạng cấu trúc dữ liệu (chả hiểu sao đã lấy tên YAML, mà nó lại còn có tên đầy đủ có chữ YAML ở trong đó nữa). Nếu mọi người đã quen với các tập tin XML để biểu diễn cấu hình, thì YAML là một cách đơn giản hơn.
YAML trong những năm gần đây đang có xu hướng thay thế JSON - JavaScript Object Notation, vì nó dễ đọc hơn, dễ viết hơn, và dễ hiểu hơn.
Phía trên ta có thể thấy, cấu trúc tập tin YAML này chứa hai dịch vụ: DB
và wordpress
. Mỗi dịch vụ sẽ chứa các thông
số cấu hình như image
- bản ảnh, volumes
, ports
- cổng, environment
- biến môi trường, và restart
- tái khởi
động. Sau khi chạy lệnh sau, chúng ta sẽ có một website WordPress chạy trên cổng 8000.
docker-compose up -d # -d: chạy ở chế độ nền
Làm theo hướng dẫn, chúng ta sẽ có một website hoàn chỉnh. Dọn dẹp tất cả container bằng lệnh sau.
docker-compose downdocker-compose down --volumes # xóa cả volumes
Vì các bản ảnh đã có sẵn trên máy, chúng ta khi chạy lại lệnh docker-compose up -d
sẽ không cần phải tải lại bản ảnh
nữa, mà chỉ cần chạy container từ bản ảnh đã có sẵn.
Có một nguồn tài nguyên rất đỉnh cho Compose mà mọi người có thể khám phá tại dây.
Website nàynày cũng sẽ cập nhật một dạng thức khác của Docker Compose - đó là việc xây dựng ELK Stack (Elasticsearch, Logstash, Kibana) trong một bài viết khác. Để biết thêm thông tin, mọi người hãy theo dõi trên website nhé! 🚀
Ngày 39 - Mạng và Bảo mật trong Docker
Section titled “Ngày 39 - Mạng và Bảo mật trong Docker”Một trong những vấn đề được đề cập rất nhiều trong chặng hành trình của chúng ta chính là Mạng và Bảo mật. Hôm nay, chúng ta sẽ nói về hai chủ đề này trong Docker.
Hãy sẵn sàng để bắt đầu ngày mới với Docker nhé! 🏕
Cấu hình mạng
Section titled “Cấu hình mạng”docker networkdocker network ls # Liệt kê các card mạng
Lệnh docker network
là lệnh giúp chúng ta có thể thao tác với các card mạng trong Docker.
Mỗi card mạng có một cái tên và mã định danh duy nhất, cũng như được liên kết với một driver cụ thể.
docker network inspect bridge
Lệnh docker network inspect
giúp chúng ta xem thông tin chi tiết của một card mạng cụ thể. Trong ví dụ trên,
ta thấy được card mạng bridge có một số thông tin như: tên, mã định danh, driver, mạng con, cổng vào, … và nó đang
trỏ về driver bridge, có địa chỉ là 172.17.0.1
- địa chỉ nội bộ của máy chủ, đồng nghĩa với việc chỉ có thể truy
cập trong nội bộ máy chủ. Nếu bạn đứng ở trình duyệt mà gõ địa chỉ của container, bạn sẽ không thể truy cập được.
Kết nối mạng giữa container với Internet
Section titled “Kết nối mạng giữa container với Internet”Mặc định card bridge gắn cho các container mới - trừ khi chỉ định cụ thể. Ta có thể dùng cách sau để kết nối mạng từ container ra ngoài. Một thí dụ điển hình để giúp chúng ta thao tác về mạng cho container như phần dưới.
docker run -dt ubuntu sleep infinity # Tạo một container mớidocker network inspect bridge # Xem thông tin card mạng bridgedocker exec -it <container_id> bash # Truy cập vào container root@<container_id>:/# apt update && apt install iputils-ping -y ## Cài đặt gói ping root@<container_id>:/# ping -c4 google.com # Kiểm tra kết nối mạng root@<container_id>:/# exit # Thoát khỏi containerdocker stop <container_id> # Dừng containerdocker ps -a # Xem danh sách các container
Xuất cổng
Section titled “Xuất cổng”# Chạy một container nginx, mở cổng 8080 trên máy chủ và chuyển hướng vào cổng 80 của containerdocker run --name webapp1 -dt -p 8080:80 nginxdocker ps # Kiểm tra cổng đã được mở chưaip addr # Từ máy tính, mở WSL2, gõ lệnh này và tìm địa chỉ IP của container
Đứng ở trình duyệt, gõ địa chỉ IP của container và cổng 8080, bạn sẽ thấy trang web của nginx.
Bảo mật trong Docker
Section titled “Bảo mật trong Docker”Điểm mấu chốt trong bảo mật Docker chính là việc cấu hình mức công khai và phân quyền.
Phân quyền
Section titled “Phân quyền”Mỗi container đều được chạy ở quyền root, điều này có thể tạo ra một số vấn đề về bảo mật. Để bảo mật, trong tệp cấu hình Docker (Dockerfile), ta có thể thêm một số lệnh để giảm quyền root.
FROM ubuntu:latestRUN apt update && apt install upgrade -yRUN groupadd -g 1000 appuser && useradd -r -u 1000 -g appuser appuserUSER appuser
Mức công khai
Section titled “Mức công khai”Các kho lưu trữ bản ảnh công khai (Registry) như Docker Hub, GitHub, … đều có thể chứa các bản ảnh không an toàn. Để bảo mật, ta có thể tạo một bản ảnh riêng, hoặc kiểm tra bản ảnh trước khi sử dụng. Điều này giúp kiểm soát hoàn toàn các bản ảnh mà chúng ta sử dụng.
Cách mạng về tinh gọn bộ máy
Section titled “Cách mạng về tinh gọn bộ máy”Nếu chúng ta chạy câu lệnh sau, chúng ta có thể biết được kích thước của bản ảnh, từ đó có thể tối ưu hóa dung lượng lưu trữ của máy chủ.
docker images
Tất nhiên, sử dụng Docker tưởng là đơn giản nhưng thực chất không hề đơn giản như vậy. Chúng ta sẽ có rất nhiều lựa chọn khác nhau thay thế cho Docker trong phát triển container. Quý vị có thể theo dõi những lựa chọn trong bài viết này để có cái nhìn tổng quan nhất về container.
Tài liệu tham khảo 📚
Section titled “Tài liệu tham khảo 📚”Mời mọi người chuyển sang trang này để theo dõi tất cả tài liệu liên quan trong giai đoạn 7, để giúp bản thân có được những tài liệu hữu ích về Docker trong làm việc với DevOps.
Giai đoạn 7 - Tham khảoHẹn gặp mọi người ở những ngày tiếp theo. 🚀