docker 連接宿主機的 MySQL
在實際生產過程中,docker 內的服務有時需要連接宿主機的 MySQL,在這裏記錄一下踩過的坑。
0. 本文環境
Name | Version |
---|---|
Docker | 19.03.4, build 9013bf583a |
OS | Debian GNU/Linux 9 |
1. 宿主機的 IP
在容器內執行 ip route
命令,default via
後面跟着的 IP 就是宿主機的 IP。
root@debian: docker run --rm busybox ip route
default via 172.18.0.1 dev eth0
172.18.0.0/16 dev eth0 scope link src 172.18.0.2
可以看到,此容器的本機 IP 爲 172.18.0.2
,宿主機的 IP 是 172.18.0.1
。
1.1 docker network 對 IP 的影響
在宿主機中運行 docker run --rm busybox ip route
獲得的宿主機 IP 爲 172.18.0.1
,在指定了 network
的容器內 ping
不通。後來發現在不同的 network
下,容器的 IP 段是不一樣的,在這裏復現一下。
root@debian: docker network create test # 創建新的 network
d5c1f383ee4c397112660b18087c42fe8f3e000ced2949778b4adb4925e6882d
root@debian: docker run --rm --network test busybox ip route
default via 192.168.192.1 dev eth0
192.168.192.0/20 dev eth0 scope link src 192.168.192.2
可以看到,在指定了 network
後,IP 段就從 172.18.0.0/16
變成了 192.168.192.0/20
。
2. 宿主機的防火牆
在能 ping
通宿主機的前提下,嘗試通過 mysql -h 192.168.192.1 -u root -p
命令登錄宿主機的 MySQL,結果 Timeout 了。
但是在容器內執行 curl 192.168.192.1
是有 response
的,證明是宿主機的 3306
端口沒有放開,放開 3306
端口即可。
一般雲服務器廠商自身還有一個防火牆,只要雲服務器控制面板裏的防火牆不放開
3306
端口的話,外界依然訪問不了服務器的3306
端口,所以可以大膽在服務器內放開3306
端口,不必擔心安全問題。
3. MySQL 的白名單
解決了防火牆的問題之後,在容器內再次嘗試通過 mysql -h 192.168.192.1 -u root -p
連接宿主機的 MySQL,收到了來自 MySQL 的報錯 Host '192.168.192.2' is not allowed to connect to this MySQL server
,直接在 MySQL 中將 192.168.192.2
加入白名單即可。
如果是多個容器都需要連接宿主機的 MySQL 的話,可以參考 MySQL IP 白名單使用通配符 將 B 類子網 192.168.0.0
全都加入白名單,這樣一來就一勞永逸了。