Giới thiệu
Chào các bạn đam mê công nghệ và những người làm DevOps! Thế giới DevOps rất rộng lớn, nhưng nền tảng của nó được xây dựng trên một vài nguyên tắc cốt lõi: container hóa, điều phối và bảo mật. Trong bài viết này, tôi sẽ dẫn các bạn qua một hành trình thực tế để củng cố hiểu biết của mình về những trụ cột này. Chúng ta sẽ bắt đầu với một container đơn và thách thức về việc lưu trữ dữ liệu, sau đó mở rộng thành một ứng dụng đa dịch vụ, và cuối cùng, nhìn rộng hơn để bảo mật chính máy chủ mà các container của chúng ta chạy trên đó.
Đây không chỉ là danh sách các lệnh; mà là một hướng dẫn từng bước với giải thích về tại sao chúng ta làm những gì chúng ta làm. Hãy cùng khám phá!
Mục Lục
- Giải Quyết Vấn Đề — Tại Sao Docker Volumes Là Cần Thiết
- Xây Dựng Ứng Dụng Thực Tế với Docker Compose
- Bảo Mật Nền Tảng — Kỹ Năng Cốt Lõi của SysAdmin
- Thực Hành Tốt Nhất
- Cạm Bẫy Thường Gặp
- Mẹo Tối Ưu Hiệu Suất
- Khắc Phục Sự Cố
- Câu Hỏi Thường Gặp
LAB 1: Giải Quyết Vấn Đề — Tại Sao Docker Volumes Là Cần Thiết {#lab-1}
Theo bản chất, các container Docker là tạm thời. Hãy nghĩ về chúng như những không gian làm việc tạm thời. Nếu bạn xóa một container, tất cả các tệp và dữ liệu được tạo bên trong nó sẽ biến mất mãi mãi. Điều này không vấn đề gì đối với các ứng dụng không có trạng thái, nhưng với một cơ sở dữ liệu hoặc một máy chủ web lưu trữ nội dung của người dùng thì sao? Chúng ta cần những dữ liệu đó tồn tại.
Đây là vấn đề mà Docker Volumes giải quyết. Một volume giống như một ổ cứng ngoài mà bạn cắm vào container của mình. Nó được Docker quản lý nhưng tồn tại ngoài vòng đời của bất kỳ container nào.
Tình Huống Thực Tế Của Tôi: Chứng Minh Dữ Liệu Tồn Tại
Mục tiêu của tôi là xem điều này diễn ra như thế nào: liệu tôi có thể làm cho dữ liệu tồn tại ngay cả sau khi container gốc của nó bị xóa?
Bước 1: Tạo "Két An Toàn" (Volume của Chúng Ta)
Đầu tiên, tôi yêu cầu Docker tạo một không gian lưu trữ quản lý, bền vững có tên là test.
docker volume create test
Bạn có thể xem tất cả các volume của mình bằng lệnh docker volume ls. Tại thời điểm này, test chỉ là một nơi trống nhưng an toàn cho dữ liệu.
Bước 2: Khởi Động Máy Chủ Web và Kết Nối Volume
Tiếp theo, tôi khởi động một máy chủ web Nginx. Phần quan trọng của lệnh này là cờ -v, kết nối volume test với thư mục /usr/share/nginx/html bên trong container. Đây là thư mục mà Nginx tìm kiếm các tệp trang web của nó.
sudo docker container run --name mywebserver -d -p 80:80 -v test:/usr/share/nginx/html nginx
Điều gì xảy ra ở đây là tinh tế nhưng quan trọng: vì volume test của chúng ta trống, container Nginx tự động sao chép tệp index.html mặc định của nó vào volume. Volume bây giờ là nguồn của sự thật cho nội dung của trang web.
Bước 3: Thay Đổi Dữ Liệu Từ Bên Trong
Để chứng minh rằng chúng tôi đang làm việc với volume, tôi đã vào container đang chạy và thay đổi tệp index.html.
# để vào bên trong container 'mywebserver'
docker exec -it mywebserver sh
# Khi vào bên trong, ghi đè nội dung trang web chính
echo '<h1>Dữ Liệu Tồn Tại Qua Container!</h1>' > /usr/share/nginx/html/index.html
# Thoát khỏi shell container
exit
Khi tôi làm mới trình duyệt của mình tại http://localhost:80, tôi thấy thông điệp mới của mình. Điều này xác nhận rằng tôi đã thành công trong việc thay đổi dữ liệu bên trong volume bền vững.
Bước 4: Bài Kiểm Tra Cuối Cùng — Phá Hủy Container
Bây giờ là lúc để kiểm tra thực sự. Tôi đã hoàn toàn dừng và xóa container mywebserver.
docker rm -f mywebserver
Container đã biến mất. Một không gian làm việc truyền thống sẽ bị xóa sạch.
Bước 5: Khôi Phục Dữ Liệu Với Một Container Mới
Tôi đã khởi động một container Nginx hoàn toàn mới với tên là mywebserver3. Tuy nhiên, tôi đã kết nối nó với cùng một volume test.
sudo docker run --name mywebserver3 -d -p 80:80 -v test:/usr/share/nginx/html nginx
Khi tôi truy cập http://localhost:80 một lần nữa... Thành công! Thông điệp "Dữ Liệu Tồn Tại Qua Container!" đã ở đó. Chúng tôi đã chứng minh rằng volume giữ dữ liệu của chúng tôi an toàn, hoàn toàn độc lập với vòng đời của container. Khái niệm này rất quan trọng cho việc chạy cơ sở dữ liệu, CMS hoặc bất kỳ ứng dụng có trạng thái nào trong Docker.
LAB 2: Xây Dựng Ứng Dụng Thực Tế với Docker Compose {#lab-2}
Chạy một container là hữu ích, nhưng các ứng dụng hiện đại hiếm khi đơn giản như vậy. Chúng thường bao gồm nhiều dịch vụ hoạt động cùng nhau—một máy chủ web, một cơ sở dữ liệu, một dịch vụ bộ nhớ đệm, v.v. Quản lý vòng đời và mạng của tất cả các container này bằng các lệnh docker riêng lẻ sẽ là một cơn ác mộng.
Giới thiệu Docker Compose. Đây là một công cụ để định nghĩa và chạy các ứng dụng đa container bằng cách sử dụng một tệp cấu hình đơn giản: docker-compose.yml.
Tình Huống Thực Tế Của Tôi: Triển Khai Một Trang WordPress
Tôi đã thiết lập một ngăn xếp ứng dụng web cổ điển: một frontend WordPress phụ thuộc vào backend cơ sở dữ liệu MySQL.
Bản Thiết Kế: docker-compose.yml
Tệp này là nguồn thông tin duy nhất cho toàn bộ ứng dụng của tôi.
version: "3.8"
services:
# Dịch vụ đầu tiên: Cơ sở Dữ liệu MySQL của chúng ta
mydatabase:
image: mysql:5.7
restart: always
volumes:
- mydata:/var/lib/mysql # Gắn volume vào thư mục dữ liệu của DB!
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
networks:
- mynet
# Dịch vụ thứ hai: Frontend WordPress của chúng ta
mywordpress:
image: wordpress:latest
depends_on:
- mydatabase # Hướng dẫn: Không khởi động WordPress cho đến khi cơ sở dữ liệu sẵn sàng!
restart: always
ports:
- "80:80" # Mở máy chủ web trên cổng 80 của máy tính của tôi
environment:
WORDPRESS_DB_HOST: mydatabase:3306 # Phép thuật của mạng Docker!
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
networks:
- mynet
# Định nghĩa toàn cầu cho các tài nguyên được sử dụng bởi các dịch vụ
volumes:
mydata: {} # Tạo chính thức volume cho cơ sở dữ liệu của chúng ta
networks:
mynet: # Tạo chính thức một mạng riêng cho các container của chúng ta
driver: bridge
Với tệp này, việc khởi động toàn bộ ngăn xếp chỉ đơn giản là chạy docker-compose up -d.
Những Điều Tôi Đã Học:
- Hạ Tầng Khai Báo: Tôi không cần phải bảo Docker làm mọi thứ. Tôi chỉ cần khai báo trạng thái mong muốn trong tệp YAML, và Compose sẽ tìm ra cách thực hiện.
- Khám Phá Dịch Vụ: Tính năng mạnh mẽ nhất ở đây là mạng. Container WordPress tìm thấy cơ sở dữ liệu bằng cách sử dụng tên dịch vụ của nó,
mydatabase, như tên máy chủ (WORDPRESS_DB_HOST: mydatabase:3306). Docker Compose tạo ra một mạng ảo riêng tư (mynet) nơi các container có thể tìm nhau bằng tên. Không còn phải mã hóa địa chỉ IP nữa! - Quản Lý Phụ Thuộc: Khóa
depends_onlà một cứu tinh. Nó đảm bảo rằng containermydatabaseđược khởi động và khỏe mạnh trước khi containermywordpressbắt đầu khởi động, ngăn ngừa lỗi kết nối.
LAB 3: Bảo Mật Nền Tảng — Kỹ Năng Cốt Lõi của SysAdmin {#lab-3}
Containers rất tuyệt, nhưng chúng vẫn chạy trên một hệ điều hành chủ—thường là Linux. Bảo mật máy chủ này cũng quan trọng như bảo mật ứng dụng. Một trong những bước bảo mật cơ bản nhất là vô hiệu hóa đăng nhập root trực tiếp qua SSH.
Tại sao? Bởi vì nó buộc trách nhiệm. Nó buộc mọi quản trị viên phải đăng nhập bằng tài khoản người dùng cá nhân của họ trước, và sau đó sử dụng sudo để thực hiện các tác vụ quản trị. Điều này tạo ra một dấu vết rõ ràng (user 'bob' ran command 'xyz') thay vì một nhật ký bí ẩn của các hành động được thực hiện bởi root quyền lực.
Tình Huống Thực Tế Của Tôi: Thách Thức Bảo Mật KodeKloud
Nhiệm vụ là áp dụng biện pháp bảo mật này trên ba máy chủ ứng dụng khác nhau.
Quy Trình 5 Bước Chung:
- SSH với Tài Khoản Người Dùng Thông Thường: Đầu tiên, tôi kết nối với máy chủ bằng tài khoản không phải root.
ssh tony@stapp01
- Tăng Quyền Đúng Cách: Tôi trở thành người dùng root bằng cách sử dụng lệnh
sudo, điều này yêu cầu mật khẩu cá nhân của tôi và ghi lại hành động.
sudo su -
- Chỉnh Sửa Tệp Cấu Hình SSH: Sử dụng một trình soạn thảo văn bản như
vi, tôi đã mở tệp cấu hình của daemon SSH.
vi /etc/ssh/sshd_config
- Thay Đổi Chỉ Thị Bảo Mật: Bên trong tệp, tôi tìm thấy dòng
PermitRootLoginvà thay đổi giá trị của nó thànhno. (Nó thường được chú thích với một #, điều này phải được xóa).
PermitRootLogin no
- Áp Dụng Thay Đổi: Một thay đổi cấu hình là vô nghĩa cho đến khi dịch vụ được khởi động lại.
systemctl restart sshd
Tôi đã lặp lại quy trình đơn giản nhưng quan trọng này trên tất cả các máy chủ cần thiết, đảm bảo một cơ sở an toàn và đồng nhất trên toàn bộ hạ tầng.
Thực Hành Tốt Nhất {#best-practices}
- Luôn sử dụng Docker Volumes cho dữ liệu quan trọng để đảm bảo chúng không bị mất khi container bị xóa.
- Sử dụng Docker Compose để quản lý nhiều dịch vụ một cách hiệu quả và dễ dàng.
- Thực hiện bảo mật cho máy chủ của bạn bằng cách vô hiệu hóa đăng nhập root qua SSH và sử dụng tài khoản người dùng cá nhân.
Cạm Bẫy Thường Gặp {#common-pitfalls}
- Không sử dụng volume có thể dẫn đến mất dữ liệu.
- Quản lý vòng đời container không đúng cách có thể làm cho ứng dụng không ổn định.
- Thiếu bảo mật cho máy chủ có thể dẫn đến rủi ro an ninh lớn.
Mẹo Tối Ưu Hiệu Suất {#performance-tips}
- Sử dụng các image nhẹ để giảm thời gian khởi động container.
- Tối ưu hóa cấu hình mạng giữa các container để tăng tốc độ kết nối.
Khắc Phục Sự Cố {#troubleshooting}
- Nếu volume không được nhận diện, kiểm tra lại lệnh tạo volume và đảm bảo không có lỗi cú pháp.
- Đối với lỗi khởi động container, xem log của container bằng lệnh
docker logs <container_id>để tìm hiểu nguyên nhân.
Câu Hỏi Thường Gặp {#faq}
1. Docker Volume là gì?
Docker Volume là một phương pháp lưu trữ dữ liệu bên ngoài vòng đời của container, giúp dữ liệu vẫn tồn tại ngay cả khi container bị xóa.
2. Làm thế nào để bảo mật máy chủ chạy Docker?
Bằng cách vô hiệu hóa đăng nhập root qua SSH và sử dụng tài khoản người dùng cá nhân để thực hiện các tác vụ quản trị.
3. Tôi có thể sử dụng Docker cho ứng dụng nào?
Docker có thể được sử dụng cho nhiều loại ứng dụng, từ web server, cơ sở dữ liệu đến microservices.
Hy vọng rằng bài viết chi tiết này sẽ hữu ích cho bạn trong việc hiểu và triển khai Docker cũng như bảo mật máy chủ của bạn. Hãy bắt đầu ngay hôm nay!