[PowerDNS] – Phần 2 – Đồng bộ DNS zone Master-Slave với MySQL Replication

powerdns mysql replication

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:

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!!!

Tài liệu tham khảo:

5/5 - (1 vote)

Để lại bình luận

Địa chỉ email của bạn sẽ được giữ riêng tư. Các trường bắt buộc được đánh dấu *