kiến thức DevOps thực tế và chi tiết

Triển khai dự án trên AWS

Để xây dựng hạ tầng phục vụ hàng triệu người dùng trên AWS cần rất nhiều yếu tố. Trong bài đầu tiên này mình sẽ xây dựng hạ tầng phục vụ hàng chục ngàn người dùng trên AWS hướng dẫn vô cùng chi tiết từng bước một (chi tiết đến từng câu lệnh).

Tóm tắt hạ tầng

Trong bài này mình sẽ không chú trọng đến phần code và tập chung vào xây dựng hạ tầng, code rất quan trọng đến performance dù có tối ưu hạ tầng tốt đến đâu nhưng code chậm thì vẫn ảnh hưởng rất lớn nên mình sử dụng WordPress coi là một website với code khá tối ưu.

Vậy để xây dựng hạ tầng phục vụ hàng chục ngàn người dùng thì chúng ta cần những gì? Tất nhiên hạ tầng đó phải phục vụ được hàng ngàn người dùng? vậy hạ tầng phục vụ hàng ngàn người dùng thì cần gì? Và dĩ nhiên hạ tầng đó phải phục vụ hàng trăm người dùng. bạn hãy xem sơ đồ kiến trúc của chúng ta sẽ đi qua từng phần.

Hạ tầng phục vụ hàng trăm người dùng

 

Thông thường bạn triển khai website sẽ lưu hết mọi thứ tại 1 server (AWS là EC2) nhưng chúng ta đang triển khai hệ thống có thể mở rộng nên chúng ta xây dựng riêng các thành phần

  • EC2 để chạy website
  • RDS để làm database lưu dữ liệu
  • S3 để lưu ảnh và video

Hạ tầng phục vụ hàng ngàn người dùng

Để website của chúng ta có thể phục vụ hàng ngàn người dùng thì việc nâng cấp mở rộng hệ thống là điều tất yếu. Có 3 cách để hạ tầng chúng ta đáp ứng được là nâng cấp tài nguyên của máy chủ, mở rộng các máy chủ (có nhiều máy chủ để chịu tải bao gồm cả database), và kết hợp cả 2 cách trên. Tuy nhiên việc nâng cấp tài nguyên của 1 máy chủ sẽ rất tốn kém. nên mình sẽ tiến hành sử dụng nhiều EC2 instance (nhiều server chạy web) để làm như vậy ngoài những service ở trên chúng ta sẽ sử dụng

  • Auto scaling group (có nhiệm vụ check lưu lượng truy cập người dùng nếu như vượt quá tài nguyên của 1 server sẽ tiến hành tạo ra các server khác để chịu tải và tương ứng cũng sẽ xóa những server khi dư tài nguyên – giúp tiết kiệm chi phí)
  • Load balancing (Khi có nhiều server mà người dùng chỉ biết đến 1 domain vậy lúc này load balancing có nhiệm vụ như một người dẫn đường cân bằng tải các truy cập phân phối đến các server)

Hạ tầng phục vụ hàng chục ngàn người dùng

Để có thể phục vụ hàng chục ngàn người dùng thì 1 database thì không đủ, chúng ta sẽ tiến hành sử dụng DB Replica có tác dụng chỉ đọc giúp việc load dữ liệu được nhanh chóng tối ưu hơn và làm sao để kết nối DB ReplicaDB Master. Thay vào đó tối ưu hơn nữa sẽ là CloudFront, caching,…

Ngoài ra bạn phải biết đến VPC bạn có thể tham khảo bài viết Xây dựng hạ tầng mạng nội bộ doanh nghiệp trên AWS

Xây dựng hạ tầng trên AWS

Step đầu tiên mình sẽ xây dựng hệ thống phục vụ hàng trăm người dùng trước.

Truy cập EC2 console và chọn Launch instance

Thiết lập cấu hình:

  • Name
  • Quick Start: Amazon Linux
  • Instance type: t3.micro
  • Key pair (login): create new key pair
  • Network settings:
    • Firewall (security groups): create security group
    • Allow SSH, HTTP. HTTPS (trong bài này mình chỉ sử dụng HTTP nên có thể không cần enable HTTPS)

Chọn Launch instance

Instance được tạo thành công và có Public IP là: 54.178.118.190 nhấn chọn Connect

Chuyển qua tab SSH client copy chuỗi connect để tiến hành connect vào EC2

Nếu bạn đang sài windows bạn có thể thử cách này Connect To EC2 Instance In Windows 10 Via SSH hoặc xem bài viết Xây dựng hạ tầng mạng nội bộ doanh nghiệp trên AWS mình có để link một app hỗ trợ SSH EC2 cho windows

Login thành công sẽ được kết quả

Bây giờ mình tiến hành setup wordpress (Những commands dưới đây bạn hoàn toàn có thể cho vào script rồi chạy hoặc cùng lúc tạo EC2)

Đầu tiên, cài đặt PHP

sudo -i login tài khoản root

yum -y update cập nhật các gói package

amazon-linux-extras | grep phpyum -y update tìm kiếm package php

amazon-linux-extras enable php8.0 enable php8.0

yum clean metadata

yum install php php-{cli,fpm,pear,cgi,common,curl,mbstring,gd,mysqlnd,gettext,bcmath,json,xml,intl,zip,imap} cài đặt PHP

php --version kiểm tra version được kết quả

Tiếp đến, cài đặt Nginx

amazon-linux-extras enable nginx1 enable package nginx

yum clean metadata

yum -y install nginx cài đặt nginx

systemctl enable --now nginx khởi động nginx

nginx -v kiểm tra version và được kết quả

Sử dụng public IP của EC2 vừa tạo lên trình duyệt và thấy như vậy là thành công (mình đã enable HTTP từ bước setup EC2)

Sau khi web của chúng ta đã chạy, tiến hành cài đặt WordPress

cd /var/www/ di chuyển tới thư mục dùng làm lưu trữ source code

wget https://wordpress.org/latest.tar.gz tải source code wordpress về server

tar -xzf latest.tar.gz giải nén file .tar.gz vừa tải

rm -f latest.tar.gz xóa file vừa tải đi vì chúng ta cũng không dùng tới nữa (bạn để lại cũng được nếu có config nhầm thì có thể làm lại)

chmod -R 777 wordpress sửa quyền của thư mục (ở đây quyền này là dễ sử dụng nhất và nguy hiểm vì bạn có thể hiểu đơn giản là user nào trên hệ thống cũng có thể tác động lên)

vi /etc/nginx/conf.d/wordpress.conf tạo file config với web server nginx với nội dung file như sau và lưu lại

server {
  listen 80;
  server_name _;
  root /var/www/wordpress;
  access_log /var/log/nginx/wordpress.log;
  error_log /var/log/nginx/wordpress.log; 

  location / {
        index index.php index.html;
        try_files $uri $uri/ /index.php?$args;
  }
  charset utf-8;
  gzip  on;
  location ~ /\. {
        access_log                      off;
        log_not_found                   off;
        deny                            all;
  }
 
  location = /robots.txt {
               allow all;
               log_not_found off;
               access_log off;
  }
  location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
  }
  location ~ \.php$ {
        try_files                       $uri =404;
        include                         /etc/nginx/fastcgi_params;
        fastcgi_read_timeout            3600s;
        fastcgi_buffer_size             128k;
        fastcgi_buffers                 4 128k;
        fastcgi_param                   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass                    unix:/run/php-fpm/www.sock;
        fastcgi_index                   index.php;
  }
}

Những phần lưu ý:

  • listen 80; tức port 80 chính là port sẽ chạy web của chúng ta (mặc định localhost và IP Public sẽ nhận port 80 hiển thị)
  • root /var/www/wordpress; là thư mục chứa source web của chúng ta vừa thao tác
  • error_log /var/log/nginx/wordpress.log; khi có lỗi bạn có thể vào đây để xem log

nginx -t test nginx

systemctl restart nginx restart lại nginx để nhận cấu hình mới

Bây giờ chúng ta quay lại web nhấn F5 sẽ thấy web của chúng ta đã lên

Tiếp đến chúng ta sẽ setup database RDS

Truy cập Amazon RDS Management Console và chọn Create database

Thiết lập cấu hình:

  • Choose a database creation method: standard create
  • Engine options:
    • Engine type: Amazon Aurora
    • Edition: Amazon Aurora MySQL-Compatible Edittion
  • Teamplates: Dev/test
  • Settings:
    • DB cluster identifier
    • Credentials Settings (ở đây là tài khoản master của database – lưu lại để config với wordpress)
  • Instance configuration: t3.small
  • Connectivity:
    • VPC: default
    • Public access: yes
    • VPC security group: create new
      • Tên của security group ta phải config lại để EC2 có thể truy cập được database
  • Database authentication: password authentication
  • Additional configuration (tên database – lưu lại để config với wordpress)

Chọn Create database

Trong lúc đợi database được tạo chỉnh sửa security groups để cho phép EC2 truy cập được database

Truy cập EC2 console và chọn Security Groups qua phần Inbound rules nhấn Edit inbound rules

Chỉnh sửa cấu hình mục Source chọn Anywhere nhấn Save rules

Database tạo thành công được kết quả như sau

Nhấn chọn vào database phần Connectivity & security copy link này chính là hostname của database mà sẽ config trong WordPress

Quay lại EC2 terminal để cấu hình database vào WordPress

cd /var/www/wordpress/ di chuyển đến thư mục WordPress

cp wp-config-sample.php wp-config.php copy file config sample thành file config

vi wp-config.php chỉnh sửa file config cấu hình database như config đã tạo ở bước tạo RDS

Kéo xuống một chút sẽ thấy đoạn AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT

Bạn lấy thông tin từ API secret Key WordPress và patse vào file

Dưới đó bạn thêm defire('FS_METHOD, 'direct'); để có thể install plugin trên WordPress để tiếp theo chúng ta setup S3 với WordPress

Quay lại web và nhấn F5 lại tiếp tục setup thông tin website

Tiếp hành đăng nhập sau khi setup

Đăng nhập thành công, vậy là chúng ta đã setup được wordpress connect tới RDS database

Và giao diện web của chúng ta bạn có thể thêm các Theme khác các bước này mình sẽ không đi chi tiết.

 

Tiếp theo mình sẽ setup, khi xây dựng hạ tầng có thể mở rộng thì cũng như database thì những ảnh và video cũng sẽ được lưu riêng mà không lưu trên Server WordPress và đó chính là mục đích sử dụng S3.

Truy cập Amazon S3 console và chọn Create bucket

Thiết lập cấu hình:

  • General configuration:
    • Bucket name
  • Block Public Access settings for this bucket:
    • Block all public access: disbale

Chọn Create bucket

Tạo thành công bucket

Truy cập Plugin nhấn Add New và Tìm kiếm WP Ofload Media Lite và tiến hành cài đặt plugin này

Active plugin và tiến hành Setup connect với S3

Setup connect với S3

Thiết lập cấu hình:

  • 1. Select Provider: Amazon S3
  • 3. Add Creadentials: copy đoạn config
    • access-key-id và secret-access-key bạn thay thế bằng key của bạn nếu bạn chưa biết tạo có thể tham khảo Create an AWS access key

Truy cập lại EC2 terminal

vi wp-config.php patse đoạn vừa copy như dưới đây và lưu lại file

Quay lại web nhấn F5 thấy WordPress của chúng ta đã được kết nối với S3

Thiết lập cấu hình:

  • 1. New or Existing Bucket: Use Existing Bucket
  • 2. Select Bucket nhập tên bucket mà ta đã tạo ở S3

Nhấn Save Bucket Settings

Tại mục media, thử upload file

Kiểm tra trên S3 đã thấy file được upload vậy là đã thành công

Đến đây chúng ta đã setup thành công hạ tầng web phục vụ hàng trăm người sử dụng và có thể mở rộng sau này sử dụng EC2 instance, RDS database, S3.

Tiếp đến chúng ta sẽ mở rộng hạ tầng để phục vụ hàng ngàn người dùng

Truy cập lại EC2 instance, nhấn tạo image (giống như việc tạo image của docker vậy image sẽ được tạo ra giống hệt với EC2 instance đó và ta sẽ sử dụng để tạo auto scaling)

Nhập tên image và nhấn chọn Create image

Tạo thành công truy cập mục AMIs sẽ thấy image của chúng ta

Truy cập EC2 console ở menu Instance chọn Launch Templates và chọn Create launch template

Thiết lập cấu hình:

  • Launch template name
  • Launch template contents
    • My AMIs
      • Owned by me và chọn AMI vừa tạo (image)

Chọn Create launch template

Tại menu EC2 kéo xuống thấy Auto Sacling Groups nhấn Create Auto Scaling group

Thiết lập cấu hình step 1:

  • Name: tên của auto scaling group
  • Launch template: template chúng ta vừa tạo

Nhấn Next

Thiết lập cấu hình step 2:

  • Chọn VPC default
  • Avalibility Zone and Subnets chọn hết các Subnets

Nhấn Next

Thiết lập cấu hình step 3:

  • Load balancing: No load balancer (chút nữa chúng ta config lại)
  • Health check grace period: thời gian check instance đó có hoạt động tốt

Nhấn Next

Thiết lập cấu hình step 4:

  • Group size: Desired capacity – 1, Minimum capacity – 1, Maximum capacity – 4 (Tối thiểu sẽ có 1 EC2 instance chạy và tối đa là 4 EC2 instance)
  • Scaling policies: Target tracking scaling policy
  • Target value: tương ứng khi 50% CPU thì sẽ tạo ra EC2 mới

Nhấn Next

Nhấn Skip to review

Tạo thành công Auto Scaling Group

Quay lại Instances Sẽ thấy có một instance được tạo ra

Tiến hành thêm luôn instance chúng ta tạo hồi ban đầu vào Auto Scaling Group

Thiết lập cấu hình và nhấn Attach

Vậy là chúng ta đã setup thành công được auto scaling, khi web của chúng ta có nhiều người truy cập 1 server khi chạy quá 50% sẽ tự động tạo ra server mới và tối đa là 4 instance.

Tuy nhiên như bạn thấy thì mỗi instance sẽ có những IP khác nhau mà người dùng chỉ truy cập duy nhất 1 địa chỉ, chính lúc đó chúng ta sẽ sử dụng đến load balancing phần rất quan trọng đã nói ở phần lý thuyết hạ tầng

Truy cập EC2 và phần auto scaling group chọn group chúng ta vừa tạo kéo xuống thấy phần Load balancing nhấn Edit

Cập nhật cấu hình:

  • Load balancer type: Application Load Balancer
  • Load balancer name
  • Load balancer scheme: Internet-facing
  • Default routing: Create a target group

Nhấn Update

Sau đó tại EC2 console nhấn chọn Load balancers và chọn vào load balance vừa tạo copy DNS name (chính là địa chỉ website)

Tuy nhiên như vậy chưa được vì theo như config wordpress thì database chúng ta đã lưu thành địa chỉ IP của EC2 instance trước đó tạo nên chúng ta phải connect vào database để sửa config

Mình sử dụng CloudBeaver docker bạn có thể tham khảo CloudBeaver Documentation hoặc bất cứ tool nào cũng được.

Truy cập table wp_options sửa siteurlhome thành DNS name ở trên vừa copy từ load balancer

Truy cập DNS name và thấy như vậy là website của chúng ta đã được mở rộng thành công phục vụ hàng ngàn người truy cập đồng thời.

Tuy nhiên để có thể phục vụ hàng chục ngàn người sử dụng thì 1 database là chưa đủ mình sẽ tiến hành tạo database replica (database chỉ đọc dữ liệu) giúp cho tăng khả năng chịu tải của website

Truy cập Amazon RDS Management Console và chọn database chọn vào database vừa tạo nhấn Action chọn Add reader

Thiết lập cấu hình:

  • Instance configuration: t3.large

Nhấn Add reader

Thấy database Reader được tạo

Tiếp theo đó bạn làm theo hướng dẫn của Scale WordPress Sites with MySQL Replicas and HyperDB | MariaDB and MySQL on Pantheon | Pantheon Docs để setup database replica với wordpress.

 

Vậy là chúng ta hoàn thành xây dựng hạ tầng thành công ở bài viết này. Bạn có thể mua thêm domain (route 53 service) hoặc bất cứ nhà cung cấp nào để phát triển website của mình. Tuy nhiên nếu chỉ muốn thực hành bạn hãy xóa những Service đã tạo khỏi mất phí nhé (phí được tính theo giờ).

Mình sẽ làm nhiều hướng dẫn hơn về các kỹ năng, các tool khác để giúp bạn tối ưu được những tác vụ cũng như tiết kiệm những chi phí khi phát triển phần mềm. Thanks.

 

Mọi thắc mắc bạn có thể liên hệ:

Email: [email protected]