Cấu hình remote database cho WordOps / EasyEngine

Trong thời gian sử dụng gói AWS Free Tier, mình băn khoăn nếu chúng ta có thể tận dụng càng nhiều càng tốt những dịch vụ miễn phí đi kèm thay vì chỉ sử dụng EC2 hay không. AWS có hàng tá các dịch vụ mà chúng ta hay bỏ qua nhưng cực kì hữu dụng, trong đó có RDS hay ElasticCache.

Tại sao phải sử dụng remote database

Kiến trúc một (hay nhiều) website sử dụng 2 máy chủ, một máy chủ để chạy webserver như Apache, Nginx và một máy chủ khác sử dụng làm MySQL, MariaDB server đã trở nên rất phổ biến và là một kiến trúc cơ bản các bạn cần xem qua nếu muốn có một ứng dụng hiệu suất cao. Việc phân tách thành hai server khác nhau giúp chúng ta đạt được hai yếu tố quan trọng, đó là bảo mậttốc độ.

ACwAAAAAAQABAAACADs=
Ảnh Digitalocean.com

Vì không còn MySQL server nặng nề chạy cùng nữa nên web server có nhiều tài nguyên để tận dụng hơn, nhất là bộ nhớ RAM. Đây cũng là một cách thông minh để giảm chi phí hàng tháng mà vẫn nhận được cấu hình tương đương, thậm chí hơn.

Ví dụ ở Vultr, 5$/tháng bạn sẽ có 1 CPU core và 1GB RAM, tuy nhiên, 10$/tháng bạn vẫn chỉ có 1 CPU core và 2GB RAM. Vì vậy việc chạy 2 máy chủ 5$ sẽ nhận được mức cấu hình tốt hơn việc bỏ ra 10$/tháng.

Ngoài ra, chúng ta có thể tăng cường thêm một chút bảo mật bằng việc giới hạn chỉ có web server mới được kết nối vào database server. Điều này một phần nào đó giúp database server nằm ngoài những con mắt tò mò của hacker.


Kết nối hai server cùng VPC với AWS

Thật ra với AWS mọi chuyện rất đơn giản, bạn chỉ việc tạo các instance cùng một VPC (và nên cùng một subnet) là đã có một mạng ảo sẵn rồi. Tương tự như vậy, khi tạo RDS instance, bạn cũng cho instance này cùng một VPC là được, sau đó kết nối từ EC2 bằng hostname được cung cấp.


Kết nối hai server cùng Private network với Vultr

Để kết nối hai máy chủ ở Vultr với nhau, chúng ta sẽ sử dụng tính năng Private network có chức năng tạo một mạng LAN ảo giữa các server với nhau. Việc này giúp tốc độ kết nối giữa các máy chủ luôn được cao nhất, latency thấp nhất và không phải expose (phơi bày) các kết nối giữa các server ra mạng public bên ngoài để đảm bảo bảo mật.

Lưu ý: Tính năng Private network yêu cầu tất cả các server muốn join network phải đặt ở cùng location để đảm bảo tốc độ tốt nhất.

Hiện tại tính năng Private network của Vultr đang miễn phí hoàn toàn và tính năng này cũng có trên rất nhiều nhà cung cấp khác như Digital Ocean, Linode,…

Tạo Private network trên Vultr

Bạn hãy truy cập vào trang quản trị Vultr và bấm vào tab Network, bấm vào nút Add network để thêm network mới. Vultr hiện tại đang miễn phí việc tạo và sử dụng Private network, tuy nhiên đang giới hạn 5 network ở mỗi location.

ACwAAAAAAQABAAACADs=
  • Location: bạn hãy chọn location mà dự định sẽ tạo server.
  • Description: điền gì cũng được, để bạn dễ phân biệt giữa các Private network khác nhau.
  • Network: nếu bạn không rành về mạng, bạn nên thay đổi thành 10.99.0.0/20 để giống với tài liệu chính thức của Vultr hoặc cứ để nguyên, cũng không có khó khăn gì ở phần sau đâu.

Sau đó nhấn Add network là bạn đã tạo thành công một Private network cho bạn rồi.

Kết nối Private network vào server của bạn

Hãy lần lượt nhấn vào từng server để tiếp tục kết nối vào Private network. Ở đây mình tạo sẵn 2 server là appserverdbserver ứng với từng chức năng của nó.

ACwAAAAAAQABAAACADs=

Chuyển sang tab Settings, trong danh sách Private network sẽ hiện ra network mà mình vừa tạo khi nãy, chọn vào và nhấn Attach network. Bạn phải làm bước này (attach) với tất cả server mà bạn dự định cho vào cùng Private network. Lưu ý khi nhấn Attach network thì server của bạn cũng sẽ tự động restart để nhận mạng mới.

ACwAAAAAAQABAAACADs=

Cấu hình Private network cho Ubuntu 18.x trở lên

Vì Ubuntu 18.x trở lên đã chuyển sang sử dụng netplan nên việc cấu hình có đôi chút yêu cầu hơn so với các phiên bản khác. Hãy kết nối vào cả hai server và thực hiện lần lượt trên từng server gõ lệnh sau:

vi /etc/netplan/10-ens7.yaml

Và chèn vào nội dung như bên dưới:

network:
 version: 2
 renderer: networkd
 ethernets:
 ens7:
 match:
 macaddress: 01:23:45:67:89:ab
 mtu: 1450
 dhcp4: no
 addresses: [10.99.0.200/16]

Lưu ý nhớ đổi 10.99.0 thành 10.40.96 như hình mình gửi nhé. Số 200 sau cùng là địa chỉ LAN IP của từng server của bạn. Ví dụ mình đặt cho database server là 10.40.96.200/16 và app server là 10.40.96.100/16 để dễ phân biệt.

Đối với Ubuntu 18.xx trở lên, bạn còn phải cung cấp địa chỉ MAC, có thể tìm thấy trong Server > Settings > Private network.

Sau khi đã thay đổi xong, bạn có thể nhập câu lệnh netplan apply để xác nhận cấu hình, vậy là xong.

Cấu hình Private network cho Ubuntu 16.xx

Với Ubuntu 16.xx, hãy gõ lệnh bên dưới và chèn vào nội dung tương ứng.

vi /etc/network/interfaces
auto ens7
 iface ens7 inet static
 address 10.99.0.200
 netmask 255.255.0.0
 mtu 1450

Chỉnh sửa địa chỉ IP tĩnh theo ý bạn muốn, sau đó lưu lại và nhấn ifup ens7 để xác nhận cấu hình mạng.

Cấu hình Private network cho CentOS 6/7

Hãy gõ lệnh bên dưới, chèn vào nội dung tương ứng và nhớ chỉnh sửa cho phù hợp.

vi /etc/sysconfig/network-scripts/ifcfg-eth1
 DEVICE=eth1
 ONBOOT=yes
 NM_CONTROLLED=no
 BOOTPROTO=static
 IPADDR=10.99.0.200
 NETMASK=255.255.0.0
 IPV6INIT=no
 MTU=1450

Chỉnh sửa địa chỉ IP tĩnh theo ý bạn muốn, sau đó lưu lại và nhấn ifup ens7 để xác nhận cấu hình mạng.

Kiểm tra thử kết nối giữa hai server

Sau khi đã kết nối 2 server với nhau, cách dễ nhất bạn có thể kiểm tra nó được kết nối chưa là ping địa chỉ IP của máy kia, vậy là xong. Mình cũng có thử dùng iperf để tính toán tốc độ truyền tải của 2 server nhau và cho kết quả khá ấn tượng trên Vultr. Đặc biệt là dung lượng truyền tải giữa Private network không bị tính vào tổng dung lượng tối đa trong tháng mà là unlimited nhé.

ACwAAAAAAQABAAACADs=
ACwAAAAAAQABAAACADs=

Cấu hình remote database với WordOps và EasyEngine

Hiện tại, để cấu hình WordOps có thể sử dụng remote database, chúng ta phải làm một số bước nhất định. Việc này tốt nhất nên được thực hiện ở server mới hoàn toàn và chưa cài đặt WordOps, như vậy sẽ tốt hơn. Nếu bạn đang có website đang chạy? Hãy backup và restore sau khi thực hiện xong bài viết này. Dưới đây là danh sách tóm tắt các bước mình sẽ hướng dẫn:

  1. Cài đặt WordOps.
  2. Cài đặt mysql-client và chuyển kết nối sang remote database.
  3. Chỉnh sửa mã nguồn WordOps (tùy chọn) và build lại WordOps.
  4. Xong.

Đầu tiên, hãy tiến hành cài đặt MySQL trên dbserver trước khi cài WordOps trên appserver bạn nhé.

Bước 1. Cấu hình dbserver

Bây giờ chúng ta bắt đầu bước cấu hình database server nha. Ở đây bạn có nhiều sự lựa chọn, sử dụng RDS của AWS, tự cài đặt MySQL trên server. Trên dbserver, bạn không cần cài đặt WordOps, chỉ cần cấu hình như một server database bình thường thôi.

AWS

Hãy chắc chắn rằng appserver của bạn có thể kết nối tới dbserver bằng cách gõ câu lệnh telnet trên appserver. Nếu không hãy kiểm tra lại security group của dbserver (RDS) và appserver (EC2) bạn vừa tạo. Lưu ý:

  • Nhớ thay dòng in đậm thành hostname/IP của dbserver của bạn.
  • Nên sử dụng private IP thay vì public IP.
  • Dùng web Port check để chắc chắn rằng MySQL không mở public từ public IP.
root@appserver:~$ apt update && apt install telnet
root@appserver:~$ telnet wordops-db.cgp414qdscum.ap-southeast-1.rds.amazonaws.com 3306
N
5.7.28-log7,g d���2-/'F3P-*)5mysql_native_password

Nếu trong phần kết quả trả về có phiên bản MySQL hoặc dòng chữ mysql_native_password có nghĩa là đã kết nối thành công rồi. Ngoài ra, bạn cũng có thể connect từ appserver với câu lệnh bên dưới, trong đó thay root bằng tài khoản admin của RDS và đoạn cuối cùng thành hostname server RDS của bạn.

root@appserver:~$ mysql -u root -p -h wordops-db.cgp414qdscum.ap-southeast-1.rds.amazonaws.com

MySQL / Server tự cài

Để cài đặt MySQL server cho máy chủ Ubuntu, bạn hãy gõ câu lệnh như bên dưới. Lưu ý WordOps chỉ hỗ trợ tới MySQL Server 5.7 thôi bạn nhé.

root@dbserver:~$ apt update && apt install mysql-server
root@dbserver:~$ sudo mysql_secure_installation

Sau khi gõ hai câu lệnh trên, trình cài đặt của MySQL sẽ hỏi một số câu hỏi. Bạn có thể đọc qua hoặc đơn giản là nhấn Y (đồng ý) rồi Enter là được đến khi thông báo cài đặt xong.

Đối với MySQL, hãy thực hiện 2 câu lệnh bên dưới để cho phép tài khoản root có thể được kết nối từ bên ngoài dbserver bạn nhé. Nhớ thay đổi thông tin tương ứng:

  • 10.0.0.10 thành private IP của dbserver
  • 10.0.20.10 thành private IP của appserver
  • password thành mật khẩu root mà bạn đã cài đặt ở trên.
root@dbserver:~$ mysql -u -p -h 10.0.0.10 -e "grant all privileges on *.* to 'root'@'10.0.20.10' IDENTIFIED BY 'password' with grant option;" 
root@dbserver:~$ mysql -u -p -h 10.0.0.10 -e "flush privileges;"

Tiếp tục mở tập tin /etc/mysql/my.cnf và chỉnh sửa dòng bind-address thành 0.0.0.0 và khởi động lại MySQL sau đó.

skip-name-resolve = 1
# Instead of skip-networking the default is now to listen only on localhost which is more compatible and is not less secure.
bind-address = 0.0.0.0
max_connections = 100

Khởi động lại MySQL server bằng câu lệnh:

root@dbserver:~$ service mysql restart

Cuối cùng thử kết nối tới dbserver bằng cách gõ câu lệnh telnet trên appserver. Lưu ý:

  • Nhớ thay dòng in đậm thành hostname/IP của dbserver của bạn.
  • Nên sử dụng private IP thay vì public IP.
  • Dùng web Port check để chắc chắn rằng MySQL không mở public từ public IP.
root@appserver:~$ apt update && apt install telnet
root@appserver:~$ telnet 10.0.0.10 3306
N
5.7.28-log7,g d���2-/'F3P-*)5mysql_native_password

Bước 2. Cài đặt WordOps

Bước này đơn giản và nhanh chóng, có lẽ đã thân thuộc với anh em rồi nên mình sẽ không nói nhiều. Hãy sử dụng câu lệnh bên dưới để cài đặt WordOps trên appserver trước bạn nhé:

wget -qO wo wops.cc && sudo bash wo

Trong quá trình cài đặt, script sẽ yêu cầu bạn nhập tên và địa chỉ email để dùng cho tài khoản admin mặc định sau này. Sau khi nhập xong hết thì script cũng tiến hành các bước còn lại tự động.

Bước 3. Cài đặt mysql-client

Tiếp theo, chúng ta tiến hành cài đặt mysql-client trên appserver để “mồi” một kết nối đến remote database đã cài đặt sẵn ở phần đầu. Nếu không làm bước này, WordOps sẽ tiến hành cài đặt MySQL server ở các bước sau gây ra lãng phí tài nguyên trên app server vì bạn không cần dùng tới nữa.

Hãy dùng câu lệnh bên dưới để cài đặt mysql-client trước trên appserver:

sudo apt-get install mysql-client

Sau đó, hãy tạo một tập tin mới với đường dẫn /etc/mysql/conf.d/my.cnf chứa thông tin remote database có nội dung như sau:

[client]
host = 172.20.44.2
user = root
password = aSecurePassword

Hãy thay đổi host thành địa chỉ IP hoặc hostname của database server, userpassword thành thông tin tương ứng như đã cài đặt tại bước 1 và lưu lại.

Bước 4. Clone mã nguồn của WordOps và build lại

Nếu bạn không sử dụng AWS RDS mà cài đặt một MySQL server riêng, có thể bỏ qua bước này.

Có một số vấn đề về việc phân chia quyền master của RDS nên chúng ta phải chỉnh sửa mã nguồn của WordOps để script có thể tạo database, tạo user, phân quyền trên RDS,… Bước này cũng thực hiện trên appserver bạn nhé.

Đầu tiên hãy clone mã nguồn WordOps về bằng câu lệnh:

git clone https://github.com/WordOps/WordOps.git

Sau đó mở tập tin WordOps/wo/cli/plugins/site_functions.py tìm đến dòng 219 và chỉnh sửa như sau hoặc xem commit này để dễ hình dung hơn.

"grant all privileges on `{0}`.* to `{1}`@`{2}`"

và sửa thành:

"grant SELECT,CREATE,INSERT,UPDATE,DELETE,DROP on `{0}`.* to `{1}`@`{2}`"

Sau đó tiến hành build lại WordOps bằng câu lệnh:

rm -rf /usr/local/lib/python3.6/dist-packages/wo-3*
cd WordOps/
python3 setup.py install

Nếu không có thông báo lỗi gì có nghĩa là bạn đã chỉnh sửa thành công, có thể tiếp tục chuyển sang bước tiếp theo.

Bước 5. Cấu hình WordOps sử dụng % thay vì localhost

Hãy chỉnh sửa tập tin /etc/wo/wo.conf, tìm dòng grant-host và chỉnh từ localhost thành % là xong. Bạn Thái Bảo góp ý các bạn cũng có thể dùng câu lệnh dưới đây thay cho việc mở file thủ công để chỉnh sửa cho nhanh nhé.

sed -i 's/grant-host = localhost/grant-host = \%/' /etc/wo/wo.conf

Bước 6. Tạo trang web đầu tiên

Sau khi thực hiện xong bước 4, bạn đã có thể tạo trang web đầu tiên và tiến hành kiểm tra các thông số của database server và web server như thế nào nhé. Lưu ý, khi cài đặt WordPress, thông số hostname của MySQL server sẽ là hostname của RDS hoặc private IP của database server, nếu không WordPress sẽ báo lỗi không tìm thấy MySQL server.

Kết luận

Vậy là xong, từ đây bạn đã có thể sử dụng một database server riêng nhưng vẫn không thay đổi gì chức năng của WordOps. Mọi thao tác thêm, sửa và xóa website trên WordOps vẫn hoạt động bình thường.

Theo mình đây là thay đổi khá đơn giản nhưng hiệu quả mang lại thì rất cao. Với một web server có cấu hình rất thấp (như t2.micro của AWS), việc tách ra và mang database server ra riêng giúp giảm CPU ultilization và giảm đáng kể lượng RAM sử dụng.

Ngoài ra, bài viết này cũng giúp bạn tận dụng gói AWS Free Tier để cho website một tốc độ nhanh nhất có thể chứ không chỉ gói gọn ở EC2.

20 bình luận
  1. Typhn

    Cảm ơn tuấn, bài viết rất hữu ích

  2. Dương

    Tuấn chia sẻ thêm một số thủ thuật như:
    + Tối ưu load time site (nén, gộp js,css…)
    + Cài monitor statping
    + Các plugin tối ưu site mà Tuấn đang sử dụng

    Cho anh em tham khảo nhé 🙂

    1. Anh Tuấn

      Vâng bạn, mình sẽ sắp xếp thời gian để viết.

    2. Anh Tuấn

      Mình có bài viết về danh sách plugin mình đang sử dụng tại đây, mời bạn xem qua: https://datuan.dev/2020/01/tuan-dev-blog-trong-nam-2020/

  3. Vinh

    Bạn có thể giải thích giúp mình khi nào dùng mysql-client vs mysql-server đc ko, Mình dùng mysql-server vẫn remote db đc đúng ko .

    1. Anh Tuấn

      Client là ứng dụng để giúp bạn kết nối đến database. Server là nơi xử lý thông tin và trả về dữ liệu. Server bạn đã có sẵn MySQL server thì nên tắt đi, chỉ dùng remote database cho tiết kiệm tài nguyên.

  4. Thanh

    Không đăng ký nick được nhỉ.

  5. thanh

    web mượt quá. Mong chỉ bảo

    1. Anh Tuấn

      Cảm ơn bạn nhiều nha 🙂

  6. Thanh

    Mình sử dụng plesk ubuntu, cài wp thủ công, mình làm cũng như này được ?

    1. Anh Tuấn

      Plesk cho phép bạn thêm nhiều database server, bao gồm remote database server đó bạn. Nên không cần làm những bước phức tạp này đâu.

  7. Thái Bảo

    Anh ơi cho e hỏi các bước trên thì chỉ thực hiện trên con app thôi phải không ạ? Con dbserver có cần cài wordops không hay để trống, em cảm ơn ạ!

  8. Thái Bảo

    Hình như hướng dẫn trên hơi thiếu, ở docs remote của wordops họ hiêu cầu gán quyền root cho mysql như sau:
    # allow root from any address with %
    mysql -e “grant all privileges on *.* to ‘root’@’%’ IDENTIFIED BY ‘your-very-strong-password’ with grant option;”

    # allow root access from a specific address (192.168.1.60)
    mysql -e “grant all privileges on *.* to ‘root’@’192.168.1.60’ IDENTIFIED BY ‘your-very-strong-password’ with grant option;”
    Nếu rảnh bạn có thể nghiên cứu viết lại phần remote này, các bài viết của bạn rất hay nên mình rất thích.
    Xin cảm ơn!

    1. Anh Tuấn

      Cảm ơn bạn nhiều. Mình đã cập nhật lại một số nội dung, bây giờ nó dài hơn và cũng chi tiết hơn rồi 🙂 Mong mọi người thông cảm, mình sẽ cố gắng ra video hướng dẫn cài đặt để hỗ trợ mọi người.

      1. Thái Bảo

        Cảm ơn bạn và chúc bạn may mắn và thành công trong cuộc sống nhé!

      2. Thái Bảo

        Mình có check dạo 1 vòng wordops thì có command này ở Bước 5. Cấu hình WordOps sử dụng % thay vì localhosthay hy vọng sẽ có ích cho nhiều người :

        sed -i ‘s/grant-host = localhost/grant-host = \%/’ /etc/wo/wo.conf

        1. Anh Tuấn

          Cảm ơn bạn nhiều nhiều nhé 😀 Mình cập nhật bài viết lần nữa rồi.

  9. Ngô Văn Cương

    Xài HocVPS thì dễ dàng đún không Tuấn

    1. Anh Tuấn

      Thật ra thì cái nào quen thuộc với bạn thì nó cũng sẽ dễ dùng hơn 😀

      1. Ngô Văn Cương

        Nếu tuần có thời gian nghiên cứu, build riêng 1 bash script, dự sẽ nổi tiếng lắm 😀

Để lại một trả lời

Địa chỉ email của bạn sẽ không được công bố.