Khi cài đặt và triển khi DNS Server trong mô hình thực tế cụ thể là các nhà cung cấp Hosting Provider tại Việt Nam đều được Trung tâm Internet Việt Nam (VNNIC) yêu cầu phải có ít nhất 2 server đặt tại hai data center khác nhau để làm nameserver và chạy song song với nhau. Mục đích nhầm để nâng cao tính sẵn sàng (high availability) đề phòng sự cố khi một trong 2 server không thể hoạt động.
Do đó trong bài viết này mình sẽ hướng dẫn các bạn chi tiết cách cài đặt và cấu hình đồng bộ zone (replicate) giữa hai server PowerDNS một cách tối ưu nhất.
1. Chuẩn bị môi trường
- NameServer 1:
- CPU: 2 core; Ram 2 GB; Disk: 20 GB
- IP: 10.10.10.1
- Domain: ns1.nin.id.vn
- Master
- NameServer 2:
- CPU: 2 core; Ram 2 GB; Disk: 20 GB
- IP: 10.10.20.1
- Domain: ns2.nin.id.vn
- Slave
Hai server đều đã cài đặt thành công PowerDNS và MySQL. Nếu các bạn chưa thực hiện cài đặt, có thể xem lại bài viết sau:
- [PowerDNS] – Phần 1 – Hướng dẫn cài đặt PowerDNS trên Debian 12
- Hướng dẫn cài đặt MySQL trên Debian 12
Sau khi thực hiện xong, các bạn hãy quay trở lại bài viết này để thực hiện các bước tiếp theo nhé!
2. Cấu hình MySQL Replication Master - Slave
MySQL Replication là một công nghệ trong hệ quản trị cơ sở dữ liệu MySQL cho phép sao chép và đồng bộ dữ liệu giữa các máy chủ. Khi một thay đổi dữ liệu xảy ra trên máy chủ master, nó sẽ được ghi vào log nhị phân và các máy chủ slave sẽ đọc log này để áp dụng các thay đổi tương ứng lên dữ liệu của mình. MySQL Replication có nhiều ứng dụng từ việc tạo bản sao dự phòng, phân tải tải trọng cho hệ thống, cho đến việc phân tích dữ liệu hoặc cung cấp dữ liệu cho các ứng dụng khác.
Hướng dẫn này sẽ trình bày cách cấu hình MySQL Replication với mô hình đơn giản một Master và một Slave.
2.1 Cấu hình Master
Đầu tiên chúng ta sẽ sao chép file chứng chỉ SSL từ Master sang Slave. Các bạn có thể sử dụng lệnh openssh để tạo chứng chỉ ssl tự kí, tuy nhiên mình sẽ dùng file ssl có sẵn của MySQL cho tiện.
Các file SSL sẽ được đặt tròng đường dẫn /var/lib/mysql/
ssh-copy-id root@10.10.20.1
scp /var/lib/mysql/ca.pem root@10.10.20.1:/var/lib/mysql/
scp /var/lib/mysql/client-cert.pem root@10.10.20.1:/var/lib/mysql/
scp /var/lib/mysql/client-key.pem root@10.10.20.1:/var/lib/mysql/
Tiếp theo, hãy chỉnh sửa lại file cấu hình của MySQL, thường sẽ nằm trong file /etc/mysql/my.cnf
Thêm vào file my.cnf với nội dung bên dưới:
[mysqld]
# lắng nghe kết nối từ bất kỳ địa chỉ IP nào
bind-address = 0.0.0.0
# Port lắng nghe của MySql
port = 3306
#chỉ định file tiến trình
pid-file = /var/run/mysqld/mysqld.pid
# Thư mục chứa dữ liệu của Mysql
datadir = /var/lib/mysql
# Chỉ định file Log lỗi
log-error = /var/log/mysql/error.log
#Khai báo ID server-id cho Master, phải khác với Slave
server-id = 1
#Khai báo database sẽ Replication
binlog_do_db = powerdns
#Chỉ định tạo ra file log
general_log_file = /var/log/mysql/mysql.log
#Chỉ định file log bin
log-bin = /var/log/mysql/mysql-bin.log
tmpdir = /tmp
binlog_format = ROW
max_binlog_size = 1024M
sync_binlog = 1
expire-logs-days = 14
slow_query_log = 1
#Khai báo file SSL
ssl
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/client-cert.pem
ssl-key=/var/lib/mysql/client-key.pem
Sau đó hãy restart lại service MySQL và kiểm tra trạng thái.
systemctl restart mysql.service
systemctl status mysql.service
Tiếp theo chúng ta cần tạo một User mysql để dùng cho việc truy cập đồng bộ.
Hãy thay thể địa chỉ IP 10.10.20.1 (SLAVE) cho phù hợp với địa chỉ IP server của bạn và thay đổi mật khẩu ‘Strongpassword‘ thành một mật khẩu mạnh mẽ hơn.
mysql -u root -p
Enter password:
CREATE USER 'replication'@'10.10.20.1' IDENTIFIED BY 'Strongpassword' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'10.10.20.1';
FLUSH PRIVILEGES;
Kiểm tra Status Master và lưu các thông tin sau:
SHOW MASTER STATUS;
#Kết quả
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000008 | 157 | powerdns | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
Hãy lưu lại giá trị ‘mysql-bin.000008’ trong cột File và ‘157’ trong cột Position.
Sau cùng, chúng ta sẽ dump database trên Master để import vào Slave.
Để quá trình đồng bộ được giữa Master và Slave thì Database ban đầu phải giống nhau, nếu không sẽ dẫn đến sai sót dữ liệu không nhất quán, hoặc sẽ xảy ra lỗi khoá chính, xung đột dữ liệu.
mysqldump -u root -p --skip-lock-tables --single-transaction \
--flush-logs --hex-blob --master-data=2 -A | gzip -c > dump_db_master.sql.gz
scp dump_db_master.sql.gz root@10.10.20.1:/root/
2.2 Cấu hình Slave
Đầu tiên chúng ta sẽ chỉnh sửa lại file cấu hình của MySQL, thường sẽ nằm trong file /etc/mysql/my.cnf
Thêm vào file my.cnf với nội dung bên dưới:
[mysqld]
log_bin = /var/log/mysql/mysql-bin.log
general_log_file = /var/log/mysql/mysql.log
binlog_do_db = powerdns
server_id = 2
read_only = 1
tmpdir = /tmp
binlog_format = ROW
max_binlog_size = 1024M
sync_binlog = 1
expire-logs-days = 14
slow_query_log = 1
Lưu ý: thông số server-id phải khác so với Master và thông số read_only = 1 cho phép Slave chỉ có quyền đọc mà không có quyền ghi dữ liệu.
Sau đó hãy restart lại service MySQL và kiểm tra trạng thái.
systemctl restart mysql.service
systemctl status mysql.service
Tiếp theo, import database từ Master vào Slave
gunzip dump_db_master.sql.gz
mysql -u root -p < dump_db_master.sql.gz
Khởi động quá trình Replication
mysql -u root -p
Enter password:
CHANGE MASTER TO MASTER_HOST='10.10.10.1',MASTER_USER='replication',
MASTER_PASSWORD='Strongpassword',
MASTER_SSL_CA='/var/lib/mysql/ca.pem',
MASTER_SSL_CERT='/var/lib/mysql/client-cert.pem',
MASTER_SSL_KEY='/var/lib/mysql/client-key.pem',
MASTER_SSL=1,
MASTER_LOG_FILE='mysql-bin.000008',
MASTER_LOG_POS=157;
Hãy thay thế giá trị ‘MASTER_HOST’ và giá trị ‘MASTER_LOG_FILE‘ , ‘MASTER_LOG_POS‘ mà các bạn đã lưu lúc nãy.
Sau cùng hãy khởi động quá trình Replication và kiểm tra trạng thái của SLAVE bằng lệnh sau:
START SLAVE;
SHOW SLAVE STATUS \G;
Nếu kết quả hiển thị tương tự như bên dưới tức là đã cấu hình thành công MySQL Replication.
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 10.10.10.1
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000008
Read_Master_Log_Pos: 157
Relay_Log_File: debian12-relay-bin.000004
Relay_Log_Pos: 373
Relay_Master_Log_File: mysql-bin.000008
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 157
Relay_Log_Space: 755
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Yes
Master_SSL_CA_File: /var/lib/mysql/ca.pem
Master_SSL_CA_Path:
Master_SSL_Cert: /var/lib/mysql/client-cert.pem
Master_SSL_Cipher:
Master_SSL_Key: /var/lib/mysql/client-key.pem
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 20f9105c-e9b3-11ee-9242-020092c44101
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
3. Kiểm tra quá trình đồng bộ DNS zone
Tạo một Zone mới trên Master với domain là nintech.vn và địa chỉ IP: 123.123.123.123
pdnsutil create-zone nintech.vn
pdnsutil list-all-zones
Tiếp theo chúng ta sẽ tạo thêm một Record A
pdnsutil add-record nintech.vn @ A 123.123.123.123
pdnsutil add-record nintech.vn www A 123.123.123.123
Trên Master và Slave hãy sử dụng lệnh sau để kiểm tra zone và record đã thêm:
pdnsutil list-zone nintech.vn
$ORIGIN .
nintech.vn 3600 IN A 123.123.123.123
nintech.vn 3600 IN SOA a.misconfigured.dns.server.invalid hostmaster.nintech.vn 0 10800 3600 604800 3600
www.nintech.vn 3600 IN A 123.123.123.123
Kiểm tra trong MySQL bằng lệnh sau
mysql -u root -p powerdns -e 'SELECT * FROM records;'
Enter password:
+----+-----------+----------------+------+-----------------------------------------------------------------------------------+------+------+----------+-----------+------+
| id | domain_id | name | type | content | ttl | prio | disabled | ordername | auth |
+----+-----------+----------------+------+-----------------------------------------------------------------------------------+------+------+----------+-----------+------+
| 1 | 1 | nintech.vn | SOA | a.misconfigured.dns.server.invalid hostmaster.nin.id.vn 0 10800 3600 604800 3600 | 3600 | 0 | 0 | NULL | 1 |
| 2 | 1 | nintech.vn | A | 123.123.123.123 | 3600 | 0 | 0 | NULL | 1 |
| 3 | 1 | www.nintech.vn | A | 123.123.123.123 | 3600 | 0 | 0 | NULL | 1 |
+----+-----------+----------------+------+-----------------------------------------------------------------------------------+------+------+----------+-----------+------+
Kiểm tra phân giải bằng lệnh dig
dig +short -t A nin.id.vn @10.10.10.1
dig +short -t A nin.id.vn @10.10.20.1
Nếu kiểm tra trên cả Master và Slave đều cho ra kết quả giống nhau thì tức đã cấu hình thành công.
4. Kết luận
Thực ra trong PowerDNS vẫn hỗ trợ đồng bộ zone giữa nhiều server bằng tính năng dnsupdate thông qua cơ chế AXFR (Zone Transfer). Tuy nhiên theo mình đánh giá thì tính năng này cập nhật không ổn định và khá chậm.
Mình đã thử nhiều cách và thấy cách đồng bộ zone bằng MySQL Replication là giải pháp OK nhất, DNS cập nhật và phân giải cực nhanh. Hiện tại công ty của mình cũng đang sử dụng theo mô hình này.
Chúc các bạn thực hiện thành công!!!