Lưu trữ đối tượng AWS S3: Hướng dẫn thực chiến cho DevOps

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Cảnh báo lúc 2 giờ sáng: Ổ đĩa máy chủ của bạn đã đầy

Bây giờ là 2 giờ sáng và điện thoại của bạn rung lên. Ứng dụng đã sập. Sau một phiên SSH điên cuồng, bạn tìm ra thủ phạm: ổ đĩa của máy chủ đã đầy 100%, bị nghẹt thở bởi hàng nghìn hình ảnh do người dùng tải lên và hàng gigabyte tệp nhật ký hàng ngày.

Bạn không thể chỉ đơn giản là gắn thêm dung lượng đĩa. Đó là một bản vá tạm thời cho một vấn đề chắc chắn sẽ xảy ra lần nữa. Bạn cần chuyển các tệp này sang một dịch vụ lưu trữ chuyên dụng, có khả năng mở rộng và đáng tin cậy. Đây không phải là một kịch bản giả định; đó là một nghi thức thông hành cho bất kỳ ai quản lý một ứng dụng đang phát triển, và đó chính xác là vấn đề mà AWS S3 được xây dựng để giải quyết.

Bạn cần một nơi để lưu trữ các tệp—có thể lên đến hàng terabyte—mà không cần quản lý máy chủ hay hệ thống tệp. Bạn cần truy cập chúng từ bất cứ đâu, kiểm soát ai thấy gì và chỉ trả tiền cho những gì bạn sử dụng. Đó chính là Amazon S3 (Simple Storage Service).

Làm rõ các khái niệm cốt lõi của S3

Hãy bắt đầu với những gì S3 *không phải* là: nó không chỉ là một ổ cứng trên đám mây. S3 là một dịch vụ lưu trữ đối tượng. Hãy nghĩ về nó ít giống như một hệ thống tệp với các thư mục lồng nhau và更像 một cơ sở dữ liệu khóa-giá trị khổng lồ. Khóa (key) là tên của đối tượng (như images/avatars/user-123.jpg) và giá trị (value) là chính dữ liệu đó (tệp hình ảnh).

Bucket, Object, và Key

  • Bucket: Một nơi chứa các đối tượng của bạn. Tên bucket là duy nhất trên toàn cầu—không có hai tài khoản AWS nào có thể có một bucket cùng tên. Hãy coi nó như một tên miền cấp cao nhất cho bộ nhớ của bạn. Bạn chọn một Khu vực AWS (ví dụ: us-east-1) để tạo bucket của mình, điều này giúp giảm độ trễ cho người dùng trong khu vực địa lý đó.
  • Object: Tệp thực tế bạn đang lưu trữ, cho dù đó là ảnh 2MB, tệp nhật ký 5KB hay video 1GB. Một đối tượng bao gồm chính dữ liệu và siêu dữ liệu như loại nội dung và kích thước.
  • Key: Mã định danh duy nhất cho một đối tượng trong một bucket. Nếu bạn có một đối tượng với khóa reports/2024/january.pdf, phần ‘reports/2024/’ chỉ đơn giản là một tiền tố (prefix). Nó không phải là một thư mục thực sự, nhưng nó tạo ra ảo giác về một cấu trúc thư mục, điều này cực kỳ hữu ích cho việc tổ chức.

Bảo mật mặc định: Tuyến phòng thủ đầu tiên cho dữ liệu của bạn

Theo mặc định, tất cả các bucket S3 mới đều ở chế độ riêng tư. Đây là một tính năng bảo mật quan trọng. Bạn phải cấp quyền truy cập một cách tường minh cho bất kỳ ai hoặc bất cứ thứ gì. Bạn có thể làm điều này thông qua:

  • IAM Policies: Gắn các quyền chi tiết cho người dùng, nhóm hoặc vai trò (role). Một ví dụ phổ biến là cấp cho một phiên bản EC2 một vai trò chỉ cho phép nó ghi nhật ký vào một tiền tố bucket cụ thể.
  • Bucket Policies: Một tài liệu JSON được gắn trực tiếp vào một bucket để xác định ai có thể truy cập các đối tượng của nó. Điều này hoàn hảo cho các quy tắc rộng hơn, như cấp quyền chỉ đọc công khai cho các tệp CSS và hình ảnh của một trang web.

Thực hành: Chinh phục S3 với AWS CLI

Giao diện web của AWS dùng để xem nhanh thì ổn, nhưng Giao diện dòng lệnh AWS (CLI) mới là nơi diễn ra quá trình tự động hóa thực sự. Nó có thể viết kịch bản, nhanh chóng và là trung tâm chỉ huy cho bất kỳ công việc DevOps nghiêm túc nào. Hãy chắc chắn rằng bạn đã cài đặt và cấu hình nó với thông tin đăng nhập của bạn.

1. Tạo Bucket đầu tiên của bạn

Hãy tạo một bucket với lệnh mb (make bucket). Hãy nhớ rằng, tên phải là duy nhất trên toàn cầu, vì vậy chúng tôi sẽ thêm một hậu tố ngẫu nhiên để đảm bảo nó có sẵn.

# Cú pháp: aws s3 mb s3://your-bucket-name --region your-region
aws s3 mb s3://itfromzero-tutorial-bucket-98765 --region us-east-1

Nếu lệnh trả về tên bucket, bạn đã thành công. Nếu nó thất bại, có khả năng tên đã được sử dụng; chỉ cần thử một tên khác.

2. Tải lên và Quản lý Object

Tiếp theo, hãy sao chép một tệp cục bộ vào bucket mới của chúng ta bằng lệnh cp quen thuộc. Cú pháp đơn giản là aws s3 cp <LocalPath> <S3Uri>.

# Tạo một file giả
echo "server logs line 1" > server.log

# Tải file lên thư mục gốc của bucket
aws s3 cp server.log s3://itfromzero-tutorial-bucket-98765/

# Bạn cũng có thể đặt nó dưới một 'prefix' (thư mục) khi tải lên
aws s3 cp server.log s3://itfromzero-tutorial-bucket-98765/logs/

Sử dụng lệnh ls để xem có gì trong bucket của bạn.

# Liệt kê tất cả các đối tượng trong bucket, bao gồm cả trong các prefix
aws s3 ls s3://itfromzero-tutorial-bucket-98765/ --recursive

3. Sync: Cách tải lên thông minh

Tải tệp lên từng cái một rất chậm và dễ xảy ra lỗi. Lệnh sync là người bạn thân mới của bạn. Nó sao chép đệ quy chỉ các tệp mới và đã cập nhật từ một thư mục cục bộ đến một tiền tố bucket. Đây là lệnh không thể thiếu để triển khai các trang web tĩnh hoặc sao lưu các thư mục nhật ký. Đối với một trong các dự án của chúng tôi, việc chỉ đồng bộ hóa các tệp đã thay đổi đã cắt giảm thời gian triển khai tài sản tĩnh từ 5 phút xuống chỉ còn 30 giây.

# Tạo một thư mục cục bộ với một vài file
mkdir -p web_assets/css
touch web_assets/index.html
touch web_assets/css/style.css

# Đồng bộ toàn bộ thư mục với prefix 'website' của bucket
aws s3 sync ./web_assets s3://itfromzero-tutorial-bucket-98765/website/

4. Tạo URL được ký sẵn (Pre-signed URL) để truy cập tạm thời an toàn

Làm thế nào để bạn cho phép người dùng tải xuống một tệp riêng tư mà không cần tạo các chính sách IAM phức tạp hoặc, tệ hơn là chia sẻ khóa AWS của bạn? Câu trả lời là một URL được ký sẵn (pre-signed URL). Đây là một liên kết đặc biệt chứa thông tin xác thực bảo mật tạm thời được nhúng dưới dạng tham số truy vấn. Nó cấp quyền truy cập có giới hạn thời gian vào một đối tượng cụ thể.

Mặc dù có thể thực hiện với CLI, bạn thường sẽ tạo chúng theo chương trình từ ứng dụng của mình. Đây là một ví dụ bằng Python sử dụng thư viện boto3.

import boto3
from botocore.exceptions import NoCredentialsError

# Môi trường ứng dụng của bạn cần có thông tin xác thực (ví dụ: qua IAM role hoặc ~/.aws/credentials)
s3_client = boto3.client('s3')

bucket_name = 'itfromzero-tutorial-bucket-98765'
object_key = 'logs/server.log'
expiration_seconds = 3600  # URL hết hạn sau 1 giờ

try:
    url = s3_client.generate_presigned_url('get_object',
                                           Params={'Bucket': bucket_name,
                                                   'Key': object_key},
                                           ExpiresIn=expiration_seconds)
    print(f"URL đã tạo: {url}")
except NoCredentialsError:
    print("Thông tin xác thực không có sẵn. Hãy đảm bảo môi trường của bạn đã được cấu hình.")
except Exception as e:
    print(f"Đã xảy ra lỗi: {e}")

Bất kỳ ai có URL này đều có thể tải xuống tệp riêng tư cho đến khi nó hết hạn. Đây là cơ chế hoàn hảo cho các tính năng như nút ‘Tải xuống hóa đơn của bạn’ trong một ứng dụng web.

Từ bản vá khẩn cấp đến kiến trúc cốt lõi

Chúng ta bắt đầu với một ổ đĩa đầy vào lúc 2 giờ sáng. Bằng cách chuyển việc lưu trữ tệp sang S3, bạn đã biến một tình huống khẩn cấp đêm khuya thành một nâng cấp cơ sở hạ tầng chiến lược. Bây giờ bạn có một ngôi nhà trung tâm, có khả năng mở rộng cho các tệp của ứng dụng, hoàn toàn độc lập với các máy chủ tính toán của bạn. Bạn có thể quản lý nó hiệu quả từ dòng lệnh và cung cấp quyền truy cập tệp tạm thời, an toàn thông qua mã ứng dụng của mình.

S3 là một phần nền tảng của AWS. Việc thành thạo việc sử dụng nó qua dòng lệnh và theo chương trình sẽ cải thiện cơ bản kiến trúc của bạn. Lần tới khi một cảnh báo lưu trữ đánh thức bạn, đó sẽ không phải là về một ổ đĩa đầy—đó sẽ là một thông báo ngân sách cho bạn biết rằng bạn chỉ đang trả vài xu cho mỗi gigabyte cho một hệ thống có khả năng mở rộng gần như vô hạn.

Share: