docker 埠對映 及外部無法訪問問題【轉】
十年河東,十年河西,莫欺少年窮
學無止境,精益求精
docker容器內提供服務並監聽8888埠,要使外部能夠訪問,需要做埠對映。
docker run -it --rm -p 8888:8888 server:v1
此時出現問題,在虛機A上部署後,在A內能夠訪問8888埠服務,但是在B卻不能訪問。
這應該是由於請求被攔截。
一、檢視firewall-cmd --state
如果輸出的是“not running”則FirewallD沒有在執行,且所有的防護策略都沒有啟動,那麼可以排除防火牆阻斷連線的情況了。
如果輸出的是“running”,表示當前FirewallD正在執行,需要再輸入下面的命令檢視現在開放了哪些埠和服務:
firewall-cmd --list-ports firewall-cmd --list-services
解決方案有兩種:
1.關閉FirewallD服務:
如果您不需要防火牆,那直接關掉FirewallD服務就好了
systemctl stop firewalld.service --關閉
systemctl start firewalld.service --開啟
2.新增策略對外開啟指定的埠:
比如我們現在要開啟對外5000/tcp埠,可以使用下面的命令:
firewall-cmd --add-port=5000/tcp --permanent firewall-cmd --reload
如果只是臨時開啟埠,去掉第一行命令中的“--permanent”引數,那麼當再次重啟FirewallD服務時,本策略將失效。
二、ip轉發沒有開啟
sysctl net.ipv4.ip_forward
顯示net.ipv4.ip_forward=0則表示未開啟。
三、service iptables開啟並攔截了
可關閉service iptables
service iptables stop
若docker run時出現錯誤:
iptables: No chain/target/match by that name.
則只需重啟docker服務即可
service docker restart
或者:
#設定iptables防火牆為開機啟動項
systemctl enable iptables.service
#啟動防火牆使配置檔案生效
systemctl start iptables.service
#停止防火牆
systemctl stop iptables.service
#重啟防火牆使配置檔案生效
systemctl restart iptables.service
最終版本:
啟動docker並進行埠對映後,docker會在iptables中新增DNAT規則,將收到的對應埠的包轉換ip並進行轉發,同時新增規則將所有來自docker網域的ip進行轉換。
但是在Centos7上出現docker可以正常訪問外網,但是外網發出的請求在經過eth1接收轉發後送達不到docker0,或者送到卻出現(oui Unknown)的狀況。暫時不清楚這到底是為什麼經過DNAT後無法送達docker0.
最終解決辦法是在啟動docker後,重啟iptables
service iptables restart
清空docker新增的所有規則,而後新增規則
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
將所有來自docker的包172.17.0.0/16的ip替換為本機ip併發送,以達到docker訪問外網的目的。
docker容器內提供服務並監聽8888埠,要使外部能夠訪問,需要做埠對映。
docker run -it --rm -p 8888:8888 server:v1
此時出現問題,在虛機A上部署後,在A內能夠訪問8888埠服務,但是在B卻不能訪問。
這應該是由於請求被攔截。
一、檢視firewall-cmd --state
如果輸出的是“not running”則FirewallD沒有在執行,且所有的防護策略都沒有啟動,那麼可以排除防火牆阻斷連線的情況了。
如果輸出的是“running”,表示當前FirewallD正在執行,需要再輸入下面的命令檢視現在開放了哪些埠和服務:
firewall-cmd --list-ports firewall-cmd --list-services
解決方案有兩種:
1.關閉FirewallD服務:
如果您不需要防火牆,那直接關掉FirewallD服務就好了
systemctl stop firewalld.service --關閉
systemctl start firewalld.service --開啟
2.新增策略對外開啟指定的埠:
比如我們現在要開啟對外5000/tcp埠,可以使用下面的命令:
firewall-cmd --add-port=5000/tcp --permanent firewall-cmd --reload
如果只是臨時開啟埠,去掉第一行命令中的“--permanent”引數,那麼當再次重啟FirewallD服務時,本策略將失效。
二、ip轉發沒有開啟
sysctl net.ipv4.ip_forward
顯示net.ipv4.ip_forward=0則表示未開啟。
三、service iptables開啟並攔截了
可關閉service iptables
service iptables stop
若docker run時出現錯誤:
iptables: No chain/target/match by that name.
則只需重啟docker服務即可
service docker restart
或者:
#設定iptables防火牆為開機啟動項
systemctl enable iptables.service
#啟動防火牆使配置檔案生效
systemctl start iptables.service
#停止防火牆
systemctl stop iptables.service
#重啟防火牆使配置檔案生效
systemctl restart iptables.service
最終版本:
啟動docker並進行埠對映後,docker會在iptables中新增DNAT規則,將收到的對應埠的包轉換ip並進行轉發,同時新增規則將所有來自docker網域的ip進行轉換。
但是在Centos7上出現docker可以正常訪問外網,但是外網發出的請求在經過eth1接收轉發後送達不到docker0,或者送到卻出現(oui Unknown)的狀況。暫時不清楚這到底是為什麼經過DNAT後無法送達docker0.
最終解決辦法是在啟動docker後,重啟iptables
service iptables restart
清空docker新增的所有規則,而後新增規則
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
將所有來自docker的包172.17.0.0/16的ip替換為本機ip併發送,以達到docker訪問外網的目的。