通過 Keepalived 虛擬 IP (VIP) 連接 MySQL 時提示:
ERROR 1130 (HY000): Host 'nginx-vip' is not allowed to connect to this MySQL server
MySQL 權限系統基於 user@host 匹配。VIP 只是 IP 地址,客戶端發起連接時,MySQL 看到的來源主機名可能是解析出的主機名 (如 nginx-vip) 或 VIP IP 本身。若 mysql.user 表中沒有對應的 user@'nginx-vip' 或 user@'VIP_IP' 授權,連接即被拒絕。
mysql> USE mysql;
mysql> SELECT user, host FROM user;
+-------+---------------+
| user | host |
+-------+---------------+
| root | % |
| root | 127.0.0.1 |
| slave | 192.168.0.231 |
| slave | 192.168.0.232 |
| root | ::1 |
| | localhost |
| | nginx01 |
| root | nginx01 |
+-------+---------------+
可見:
root@'%' (允許任意 IP),但 VIP 連接解析為主機名 nginx-vip,不匹配 % (注意:% 匹配 IP,不匹配主機名,除非啟用 skip-name-resolve)。slave@'nginx-vip' 或 slave@'VIP_IP' 授權。GRANT ALL PRIVILEGES ON *.* TO 'slave'@'192.168.0.232' IDENTIFIED BY 'slave' WITH GRANT OPTION;
-- 或
GRANT ALL PRIVILEGES ON *.* TO 'slave'@'nginx-vip' IDENTIFIED BY 'slave' WITH GRANT OPTION;
FLUSH PRIVILEGES;
在 my.cnf [mysqld] 區添加 skip-name-resolve=1,MySQL 將不再解析主機名,直接用 IP 匹配,此時 root@'%' 即可匹配 VIP IP。但這會導致現有基於主機名的授權失效,需謹慎評估。
確保 VIP 正確漂移,且 MySQL 綁定在 0.0.0.0 或具體 VIP IP 上 (bind-address=0.0.0.0)。
user@'IP' 和 user@'hostname' 以兼容不同解析場景。skip-name-resolve 避免 DNS 故障導致連接風暴,但需提前清理基於主機名的授權。ProxySQL 或 HAProxy 作為中間層,將 VIP 綁定在代理層,後端 MySQL 僅授權代理 IP,架構更清晰。