IPFS的配置記錄


IPFS

分布式文件系統, 原理類似於bt, 通過文件分塊, 每個塊對應CID以及各級Hash做存儲和校驗, 通過DHT(Distributed Hash Table)做查找和路由.

IPFS文檔

https://docs.ipfs.io/ 主要看 Concepts 和 How-tos 部分
IPFS對應每個Content會產生不同的CID, 對於需要固定鏈接的需求, 可以通過IPNS實現, 但是IPNS不適合於快速變化的內容, IPNS的更新間隔是以分鍾記的

使用IPFS做的一些服務

網關

官方有一個可用的網關列表: https://ipfs.github.io/public-gateway-checker/ 下面是測試過的一些可用網關

go-ipfs

IPFS的Go語言項目是其主要的開源實現: https://github.com/ipfs/go-ipfs/

go-ipfs的配置說明

詳細的配置說明在 https://github.com/ipfs/go-ipfs/blob/master/docs/config.md 這個比手冊寫的詳細

編譯go-ipfs

參考 https://github.com/ipfs/go-ipfs#download-and-compile-ipfs

Github 項目源代碼有30多MB, clone的時間會比較長, 如果太慢並且出錯, 需要加個代理. 編譯使用 make build 命令, 說是編譯, 其實大部分時間是花在下載依賴庫上,
在執行前設置一下GOPROXY避免下載超時

# 檢查go版本, 要1.13以上
go version
# 設置代理
git config --global https.proxy 'socks5://127.0.0.1:10080'
# 檢查
git config -l
#
git clone https://github.com/ipfs/go-ipfs.git
cd go-ipfs/
# 設置GOPROXY
export GOPROXY=https://goproxy.cn
# 檢查
echo $GOPROXY
# 編譯
make build
# 檢查編譯結果
./cmd/ipfs/ipfs version

在Amlogic S905L的Armbian上運行IPFS

從GO IPFS Github項目下載 Arm64版本, Armbian 版本為 5.99, 內核 5.30.

# 下載
wget https://github.com/ipfs/go-ipfs/releases/download/v0.5.1/go-ipfs_v0.5.1_linux-arm64.tar.gz
# 解壓
tar xvf go-ipfs_v0.5.1_linux-amd64.tar.gz
# 直接運行 install.sh 安裝, 這個腳本會將ipfs目錄復制到 /usr/local/bin 下
cd go-ipfs
./install.sh

初始化后, 使用普通用戶啟動

#  查看版本
ipfs --version
# 初始化節點
ipfs init
# 查看說明
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
 
# 這個命令不會后台運行, 建議先建一個screen session, 在screen session里執行
ipfs daemon

如果IPFS不是運行在當前電腦, 那么配置需要做兩處改動后才能訪問webui

一處是Addresses.API 和 Addresses.Gateway

"Addresses": {
  ...
  "API": "/ip4/127.0.0.1/tcp/5001",
  "Gateway": "/ip4/127.0.0.1/tcp/8080"
}

將API的地址改為 /ip4/0.0.0.0/tcp/5001 這樣會監聽所有網口, 如果你的服務器有公網IP, 這樣會有安全問題, 可以將這個IP設為內網網口地址.
將Gateway的地址改為內網地址或公網地址, 如果IPFS處於內網, 外網可以通過NAT訪問, 這個可以配成內網地址.

另一處是 API.HTTPHeaders, 避免從當前電腦訪問IPFS的webui時, 出現cross site 錯誤.

"API": {
    "HTTPHeaders": {}
},

在HTTPHeaders里增加兩項, 可以參考 Gateway.HTTPHeaders

"Access-Control-Allow-Methods": [
  "GET","PUT","POST"
],
"Access-Control-Allow-Origin": [
  "*"
]

修改完配置, 重啟IPFS后就可以訪問 http://IP:5001/webui/ 可以圖形化的查看當前節點狀態, 存儲的塊數量和大小, 連接的節點明細, 以及查看當前的配置. 這個界面甚至提供了一些演示用的文件瀏覽.

通過Gateway, 可以訪問IPFS上的文件以及遠程可以查詢到CID的文件. 任何訪問過的文件塊都會被緩存, 再次訪問時, 相應的塊會直接走緩存, 不會再從遠程下載.

選擇文件上傳后, 會在頁面后台進行傳輸(尚未確認是否可以關閉標簽頁), 在狀態頁能看到總存儲在增長. 對於不同大小的文件, 其發布可見的延遲是不一樣的, 對於10MB以內的文件, 通過遠程gateway很快就能發現, 對於接近500MB的文件, 大概需要半個小時到一小時. 這和節點發布自身的內容CID到其他節點的機制有關, 因為單個文件塊為256KB(262144Byte), 對於500MB大小的文件, 會產生2,000多個CID, 發布需要的時間會長得多.

在webui上添加文件, 需要等文件上傳完整后, 才能做pin操作, 如果是通過CID上傳文件, 在提交CID后並不會觸發文件同步, 對這個CID進行pin操作后, 會觸發ipfs開始從其他節點同步, 等文件從其他節點同步完成后, 會出現在pin列表.

安裝到服務

創建文件 /etc/systemd/system/ipfs.service 寫入

[Unit]
Description=IPFS Daemon
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
ExecStart=/usr/local/bin/ipfs daemon --enable-namesys-pubsub
User=milton
[Install]
WantedBy=multi-user.target

然后通過systemctl 添加

配置說明

IPFS對外提供的端口主要是3個: API, Gateway和Swarm, 其中

  • API: 默認使用端口5001, 在上面提供了webui, 用於管理控制IPFS. 設置監聽網口時應當注意不要開放到公網
  • Gateway: 默認使用端口8080, 在上面提供ipfs/CID的內容查找下載服務
  • Swarm: 默認使用端口4001, 這個端口用於監聽其他IPFS節點的請求
  • Addresses.NoAnnounce 添加需要排除的內網IP, 這些IP不會發布, 但是注意不要排除127.0.0.1和::1, 這兩個貌似被用於其他節點檢測當前節點是否支持ipv4或ipv6, 如果排除掉, 會無法與其他節點保持連接(能ping能connect, 但是swarm peers里查不到)
  • Swarm.AddrFilters 添加需要忽略的內網IP, 對於在ID上announce內網IP的peer, 這些內網IP的地址會被過濾掉
  • Discovery.MDNS.Enabled 將這個選項改為false, 就不會在內網發起節點搜索
  • Peering.Peers 添加需要保持連接的節點

固定節點

對於自建的網絡, 需要讓自己的節點之間保持連接, 但是IPFS默認的機制下, 即使將自建節點設置為bootstrap, 在啟動一段時間后, 在連接的節點不斷增加后, 依然會將與其他自建節點之間的連接關閉. 要保持連接, 需要使用配置文件中的Peering部分, 格式如下, 第二個為ipfs.runfission.com的接入地址

{
  "Peering": {
    "Peers": [
      {
        "ID": "QmPeerID1",
        "Addrs": ["/ip4/18.1.1.1/tcp/4001"]
      },
      {
        "ID": "QmVLEz2SxoNiFnuyLpbXsH6SvjPTrHNMU88vCQZyhgBzgw",
        "Addrs": ["/ip4/3.215.160.238/tcp/4001", "/ip4/3.215.160.238/udp/4001/quic"]
      }
    ]
  }
  ...
}

使用Peering配置的節點:

  1. 在連接管理中會保護與這個節點之間的連接, IPFS永遠不會主動(自動)關閉這個連接, 在連接數達到上限時也不會關閉這個連接.
  2. 在啟動時就會建立連接
  3. 如果因為網絡原因或對方節點掉線等原因導致連接丟失, IPFS會不斷嘗試重新連接, 嘗試的間隔長度在5秒至10分鍾之間隨機.

在公網NAT下運行IPFS

運行環境

公網IP的服務器是Centos7, 公網IP為118.119.120.121, 內網IP為192.168.13.10
內網服務器Ubuntu18.04, 內網IP為192.168.13.25

在公網服務器上設置端口轉發

配置一下全局轉發開關

firewall-cmd --permanent --zone=public --add-masquerade

將公網IP端口4002轉發至內網服務器的4001端口

# TCP端口轉發
firewall-cmd --permanent --zone=public --add-forward-port=port=4002:proto=tcp:toaddr=192.168.13.25:toport=4001
# UDP端口轉發
firewall-cmd --permanent --zone=public --add-forward-port=port=4002:proto=udp:toaddr=192.168.13.25:toport=4001
# 設置生效
firewall-cmd --reload
# 檢查
firewall-cmd --zone=public --list-all

如果網關是OpenWRT路由, 則直接在防火牆->端口轉發中添加轉發規則即可. 注意在添加完轉發規則后, 還需要在通信規則中允許WAN到此設備此端口的訪問.

限制連接的節點數量

需要通過Swarm/ConnMgr/HighWater 這個參數,在0.6.0時這個設置並不能很好地工作,長時間運行服務器后節點數量會遠超設置的限制,在0.7.0上是有效的

"Swarm": {
    ...
    "ConnMgr": {
        "GracePeriod": "30s",
        "HighWater": 500,
        "LowWater": 100,
        "Type": "basic"
    },
    ...
}

在內網服務器上配置IPFS服務

# 安裝過程略
 
# 初始化為服務器模式
ipfs init --profile=server
 
# 修改配置, 看下面具體說明
vi .ipfs/config
 
# 啟動
ipfs daemon

服務器模式和普通模式相比, 有幾點變化

  1. Addresses.NoAnnounce 服務器模式會列出所有的內網IP, 這些IP不會發布
  2. Swarm.AddrFilters 服務器模式會列出所有內網IP, 對於使用內網IP來連接的peer, 都會被過濾掉
  3. Discovery.MDNS.Enabled 服務器模式時這個選項為false, 避免在內網發起節點搜索

需要配置的地方除了普通節點的API, Gateway和API HTTPHeaders, 還需要配置 Addresses.Announce , 需要添加本節點的公網IP和端口

"Announce": [
  "/ip4/118.119.120.121/tcp/4002",
  "/ip4/118.119.120.121/udp/4002/quic"
],

遇到的問題

使用OpenWRT配置的網關不存在這個問題, 但是使用Centos做網關時似乎不能將外網IP正確傳入, 導致大量第三方節點的顯示IP為網關IP, 對本節點連接可以成功, 但是ping失敗. 所以對於 Swarm.AddrFilters 里面的列表要刪除同網段的部分.

具體原因可以通過本節點的swarm peers看到, 從本節點主動連接的節點, 記錄的是公網IP, 但是本節點被動連接(即通過網關118.119.120.121連接)的節點, 記錄的都是網關的內網IP, 按照AddrFilters的規則, 這些節點會被丟棄. 就會出現ipfs swarm connect 成功, 但是 ipfs ping 失敗的問題.

$ ipfs swarm peers
/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
/ip4/111.231.85.77/tcp/4001/p2p/QmWv1eLMNHPpwYKzREQBEpDfYjW6YXCrVpVyBZVjAuSd2i
...
/ip4/192.168.13.10/tcp/10041/p2p/QmXUZth5Pr2u1cW65F7gUeFwjkZFfduE1dwqiysNnrTwXd
/ip4/192.168.13.10/tcp/10053/p2p/QmPM3bepMUKpYTza67coD1Ar3efL7FPBFbGRMc42QLf4q9
/ip4/192.168.13.10/tcp/10202/p2p/QmVBzjW2MyNrSuR48GjcqB6SAJTnw8Y9zaFbgbegh4bRx4
/ip4/192.168.13.10/tcp/1024/p2p/QmbBEfFfw59Vya9CJuzgt4qj9f57sPZGiyK7fup8iKqkTr
/ip4/192.168.13.10/tcp/1025/p2p/QmcmhwCeLkBJvcq6KJzN58BRZg1B1N8m3uA3JyQKpVn64E
...
/ip4/192.168.13.10/udp/6681/quic/p2p/QmcSCBpek4YF5aAsY7bUMxiL7tacoYMeXUJUpU4wctqX4w
/ip4/192.168.13.10/udp/8050/quic/p2p/QmWeuXCNKAHfbineKMqo3U3dvVSz2em1w67pj5Up6tkUXo
/ip4/206.189.69.143/tcp/31071/p2p/12D3KooWHDr5W3Tse17mr4HSzuQm44dVQYp8Bb638mQknsyeHXSP
/ip4/206.189.69.250/tcp/30511/p2p/12D3KooWRd1BNPd8PMfxpCT7TNCFY4XSZsy8v8Cmm36H136yxzub
...

再進一步檢查是否可以從本節點訪問被動連接的節點, 取其中一個Peer ID做ping測試

ipfs ping QmXUZth5Pr2u1cW65F7gUeFwjkZFfduE1dwqiysNnrTwXd
PING QmXUZth5Pr2u1cW65F7gUeFwjkZFfduE1dwqiysNnrTwXd.
Pong received: time=26.43 ms
Pong received: time=25.70 ms
Pong received: time=26.31 ms
...

說明這些記錄為網關內網IP的節點是可用的, 應當保留

這些通過網關連接的節點, 可以分為兩類: 無公網IP的節點和有公網IP的節點:

  • 對於有公網IP的節點, 尚不清楚是否會在初次連接后使用對方Announce的地址回ping, 如果會並且會根據此結果更新節點的地址, 那么這些節點會在這個顯示為內網IP的列表中短暫停留后, 更新為公網IP地址, 這樣在其他節點接入后, 共享節點信息時, 其他節點可以通過其公網IP地址進行連接.
  • 對於無公網IP的節點, 服務器節點根據對方Announce的地址回ping是無法連接的, 只能通過本方網關的內網IP進行連接, 所以會一直停留在這個顯示為內網IP的列表中. 這些節點是無法共享給其他節點的.

優化下載速度

如果是希望通過CID讀取文件, 首先要選擇速度較快的網關, 通過ipfs.io網關獲取文件是最可靠的, 但是因為連接問題, 速度可能會很慢.

如果是希望通過CID發送文件, 要務必保證對方使用的網關在當前存放文件的實例的連接列表中, 所以維護一個速度較快的網關列表很重要, 將這些網關加入自己的Peering.Peers, 將極大提升自己的文件發布速度.

升級IPFS

大版本的升級, 需要使用fs-repo-migrations 工具, 參考Doc里的說明, 就是兩步, 備份.ipfs目錄, 運行 fs-repo-migrations 命令, 在這之前需要把ipfs服務停掉.

IPFS Desktop

在Windows10下安裝IPFS Desktop, 默認安裝到用戶目錄下 C:\Users\Milton\AppData\Local\Programs\IPFS Desktop, 安裝完成后程序目錄265M,
數據目錄在 C:\Users\Milton.ipfs, 格式和內容與go-ipfs無異. 后台有兩個IPFS Desktop進程, 兩個ipfs進程, 共占用內存約500M.

狀態窗口實際上是一個webview, 展示了webui的內容.

配置只是在默認的配置上將水位線改為50, 300, 其他是一樣的.

資源如果存在(緩存)於直接連接的節點則可以訪問, 否則無法訪問.

IPFS私有網絡和集群

參考 https://labs.eleks.com/2019/03/ipfs-network-data-replication.html

將IPFS運行為服務, 開機自啟動

# 創建服務文件
sudo vi /etc/systemd/system/ipfs.service
 
# 文件內容
[Unit]
Description=IPFS Daemon
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
ExecStart=/usr/local/bin/ipfs daemon --enable-namesys-pubsub
User=root
[Install]
WantedBy=multi-user.target
# 文件內容結束
 
# 添加服務
sudo systemctl daemon-reload
sudo systemctl enable ipfs
sudo systemctl start ipfs
sudo systemctl status ipfs

將IPFS Cluster添加為服務

# 創建服務
sudo nano /etc/systemd/system/ipfs-cluster.service
 
# 文件內容開始, 注意After里有ipfs服務, 以此保證啟動順序
[Unit]
Description=IPFS-Cluster Daemon
Requires=ipfs
After=syslog.target network.target remote-fs.target nss-lookup.target ipfs
[Service]
Type=simple
ExecStart=/home/ubuntu/gopath/bin/ipfs-cluster-service daemon
User=root
[Install]
WantedBy=multi-user.target
# 文件內容結束
 
# 添加到系統服務
sudo systemctl daemon-reload
sudo systemctl enable ipfs-cluster
sudo systemctl start ipfs-cluster
sudo systemctl status ipfs-cluster

IPFS的應用場景

經過實際測試, 對於在公眾網絡中的IPFS節點, 一旦建立了連接進行CID的發布和讀取速度是很快的, 除去網絡本身的延遲, 從請求到開始傳輸基本上在2秒內, 傳輸速度取決於兩點間的帶寬.

文件共享

IPFS對內容的索引形式很適合做團隊間的文件共享, 因為每一次改動都會產生索引變化, 可以做版本化控制. 分布式的文件接入點和下載點方便集群伸縮擴展, 帶緩存的特性能降低熱點數據對帶寬資源的影響.

音視頻分發

用於取代現有的PT下載網絡. 因為PT傳播的單個文件很大, 需要對整個PT群中的節點做統一的pin管理, 一方面確保各終端節點對熱點內容的訪問速度, 另一方面確保長尾內容有足夠的備份, 不會丟失.

流媒體和下載加速

IPFS的特性, 天然地可以用於取代CDN服務. 靜態文件例如圖片, CSS, JS, 以及壓縮包, 甚至一些時效性要求不高的直播業務. 現在運營商寬帶已經普及IPv6, 這些有公網IPv6地址的家庭帶寬資源可以充分利用起來做區域內容加速.

libp2p

libp2p是從IPFS中獨立出來的一個封裝好的p2p模塊, 模塊中已經內置了PeerId, MultiAddress, Protocol Handler這些機制, 可以很方便擴展出自己的應用.

Go語言的實現 https://github.com/libp2p/go-libp2p, 樣例代碼 https://github.com/libp2p/go-libp2p-examples

在代碼里的使用, 一般是以下步驟:

  1. 創建Host
  2. 對指定的協議, 在Host上SetStreamHandler
  3. 如果本地還有端口提供服務, 則創建對應服務並監聽端口
  4. 指定目標節點和協議, 創建Stream
  5. 往Stream寫數據
  6. 從Stream讀數據, 根據業務需求關閉或不關閉Stream

在Host啟動后如果需要保持運行, 可以使用以下方式

# 方法1, 使用select
select {} // hang forever
 
# 方法2, 使用內置服務的ListenAndServe
http.ListenAndServe(serveArgs, p)
 
# 方法3, 使用channel
<-make(chan struct{}) // hang forever


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM