原文鏈接:https://www.cnblogs.com/zzsdream/p/11199374.html
https://blog.snailr.cn/archives/536
一、概述
最近公司准備全面實施docker部署,解決每次項目實施安裝部署環境工作量大問題,mysql5.7、oracle12c很順利,在安裝fastdfs時碰到storage的IP地址映射問題。服務器采用的是CentOS7.6,關閉了firewall,啟動鏡像后在局域網其他機器無法通過fastdfs-java-client上傳文件,獲取的storage的IP地址為容器的IP地址,局域網其他機器無法訪問容器的IP地址,查找了很多資料包括:docker-proxy iptables 等最終解決問題,記錄下來方便。
二、fastdfs鏡像安裝和容器啟動
fastdfs鏡像是通過作者提供的dockerfile進行構建:https://github.com/happyfish100/fastdfs/tree/master/docker/dockerfile_network,構建比較簡單,下載作者提供的dockerfile_network目錄,里面包含了用最新的代碼構建fastdfs的鏡像,然后在目錄執行:
docker build -t fastdfs:V5.11 .
構建成功后,通過docker images查看鏡像
啟動鏡像,本機的IP地址為 192.168.1.98 執行以下命令啟動:
docker run -d -e FASTDFS_IPADDR=192.168.1.98 -p 8888:8888 -p 22122:22122 -p 23000:23000 -p 8011:80 --name test-fast fastdfs:V5.11
三、問題描述和分析
在另一台機器192.168.1.230使用fastdfs-client-java測試上傳圖片,總是報錯提示 connect time out ,調試代碼后發現連接到tracker server (192.168.1.98:22122)成功的,並且返回了storage信息,但是storage地址是:172.17.0.1:23000,192.168.1.230是無法連接到172.17.0.1的IP,這個IP是docker的一個虛擬網卡IP,用於橋接運行容器,如下圖:
查看了作者提供的fastdfs.sh文件,容器啟動時已經把storage.conf的配置文件里面的tracker_server地址替換為FASTDFS_IPADDR=192.168.1.98參數的地址,也就是說storage是連接到tracker server 的地址是192.168.1.98:22122,按道理storage注冊到tracker server的地址應該也是192.168.1.98,進入容器查看tracker server的信息:
[root@localhost ~]# docker exec -it test-fast /bin/bash [root@854ce848546a /]# /usr/bin/fdfs_monitor /etc/fdfs/storage.conf
到這里問題已經找到了,storage server在容器里面連接到192.168.1.98:22122 地址時,tracker server記錄到storage的地址是 docker0 虛擬網卡(172.17.0.1)的地址。
對centos下docker的網絡不熟悉,百度學習了很久的 docker網絡(Bridge模式、Host模式、Containner模式等)、iptables的知識后,大概知道storage server在容器里面連接192.168.1.98:22122 ,通過NAT表轉發到tracker server時,數據包里面的源地址為:172.17.0.1導致了tracker server默認認為storage的地址是172.17.0.1
四、解決問題的思路
在學習了iptables的知識后(主要看了 http://www.zsythink.net/archives/1199/ )后,已經明白在NAT表轉發過程中,數據達到172.17.0.2的22122端口記錄的源地址是 172.17.0.1,我們只需要修改iptables的NAT表規則,所有轉發到172.12.0.2:22122的數據,源地址修改為宿主主機的地址:192.168.1.98,這樣storage注冊到tracker server時,tracker server獲取到storage的ip地址為 192.168.1.88 而不是網關地址172.17.0.1
iptables -t nat -A POSTROUTING -p tcp -m tcp --dport 22122 -d 172.17.0.2 -j SNAT --to 192.168.1.98
使用iptables -L -t nat 查看nat表規則
重新執行fastdfs-client-java的工程,返回的storage的地址為 192.168.1.98,上傳成功:
五、總結
個人感覺采用docker部署后,網絡環境會比單機更加復雜,如果直接采用Host模式的網絡和單機一樣,如果采用Bridge模式的換會復雜很多,想學docker的話必須很好掌握docker的網絡的基礎知識。同時在liunx下如果使用了iptables的話,也需要了解docker和iptables的技術細節。我覺得這個思路也許能解決目前fastdfs的內網IP映射外網進行上傳的問題,找個時間試試看。
FastDFS
向使用者提供基本文件訪問接口,比如upload
、download
、append
、delete
等,以客戶端庫的方式提供給用戶使用。
客戶端使用流程由 Client
連接 Tracker
的IP和prot,Tracker
接收到Client
請求,告訴Client
Storage
的真實IP和port,Client
再去連接實際Storage
的IP和port;在Tracker
和Storge
之間,存在通信機制,這一機制,決定了Tracker
告訴Client
的IP和port。
- 問題一:
FastDFS
需要通過代理IP:port或公網地址訪問解決方案:(獲取storage外網ip的問題)- 第一步:
Client
連接Tracker
的地址配置成代理IP:port或公網地址 - 第二步:在
Storage.conf
配置文件中配置Tracker服務器的IP和port (代理IP:port或公網地址)
- 第一步:
- 問題二:
FastDFS
需通過代理地址訪問,由於某些機制原因Storage
無法訪問Tracker
的代理地址解決方案:(此方案適用於Client
可通過代理地址訪問Storage
)- 在
Client
通過Tracker
獲取到Storage
地址后將真實的IP和port 替換成代理的IP和port - 此方案可參考 fastdfs-client-java-storage-ip-mapping,需替換
Client
jar文件和在配置文件中添加fastdfs.storage_server.ip_mapping
配置
- 在
- 問題三:docker安裝fastdfs碰到storage的IP地址映射宿主地址問題解決方案:
- 啟動時用宿主地址啟動:(以下以
192.168.1.100
為宿主IP)docker run -d -e FASTDFS_IPADDR=192.168.1.100 -p 8888:8888 -p 22122:22122 -p 23000:23000 -p 8011:80 --name test-fast fastdfs:V5.11
- 源地址修改為宿主主機的地址:
- 在NAT表轉發過程中,數據達到172.17.0.2的22122端口記錄的源地址是 172.17.0.1,我們只需要修改iptables的NAT表規則,所有轉發到172.12.0.2:22122的數據,源地址修改為宿主主機的地址:192.168.1.100,這樣storage注冊到tracker server時,tracker server獲取到storage的ip地址為 192.168.1.100 而不是網關地址172.17.0.1
iptables -t nat -A POSTROUTING -p tcp -m tcp --dport 22122 -d 172.17.0.2 -j SNAT --to 192.168.1.100
- 啟動時用宿主地址啟動:(以下以