本篇使用虚拟机搭建IPFS私有网络和集群,使用vagrant和virtualbox来快速搭建环境。

私有网络

下载二进制文件

如果使用go-ipfs源码编译,需要安装go环境,推荐下载二进制文件:

  1. https://dist.ipfs.io

  2. https://github.com/ipfs/go-ipfs/releases

使用1下载go-ipfs等其他组件

搭建虚拟机环境

安装vagrant和virtualbox

# mac
brew install vagrant
brew intall virtualbox

# ubuntu
sudo apt update
sudo apt install virtualbox

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install vagrant

创建虚拟机

使用ubuntu/focal64(vagrant boxes list),创建Vagrantfile如下:

mkdir ~/vagrant-project
cd /vagrant-project
vagrant init ubuntu/focal64  # 创建Vagrantfile

初始化的Vagrantfile配置很简单,使用4个虚拟机环境,简单修改如下:

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

	(1..4).each do |i|
		config.vm.define "node#{i}" do |node|
          
			node.vm.box = "ubuntu/focal64"
			node.vm.hostname = "node#{i}"
			node.vm.network "private_network", ip: "192.168.33.10#{i}"

			node.vm.provider "virtualbox" do |v|
				v.name = "node#{i}"
				v.memory = 2048
				v.cpus = 1
			end
		end
	end
end

安装IPFS和配置

将下载的二进制文件移动到项目目录下~/vagrant-project,默认该目录会挂载到虚拟机/vagrant

启动虚拟机

vagrant up

以下是对节点node1进行配置,其余节点类似配置

安装IPFS二进制文件

vagrant ssh node1   # 进入node1
cd /vagrant         # 进入挂载目录
tar -C /usr/local -zxvf go-ipfs_v0.10.0_linux-amd64.tar.gz # 解压
cd /usr/local/go-ipfs
sudo ./install.sh  # 复制到/usr/local/bin

ipfs节点初始化:

ipfs init

生成私有网络的共享密钥

生成共享密钥文件swarm.key,对等节点只有在其内容相同时才会互相建立连接,需要安装go环境安装步骤

  1. 下载生成工具
go get -u github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen

生成文件swarm.key,复制到~/.ipfs仓库目录

ipfs-swarm-key-gen > ~/.ipfs/swarm.key
  1. 复制该文件到其余节点上的~/.ipfs目录
  • 复制该文件到节点共享的文件中
  • 或者cat ~/.ipfs/swarm.key复制文件内容,在其他节点重新创建

删除节点的默认引导节点

 ipfs bootstrap rm all

(添加默认的引导节点: ipfs bootstrap add default)

启动多个节点

注意,上面的操作在所有的节点中都要进行;启动多个节点,节点按照上述配置好后,需要连接到本地的引导节点,例如将节点node1设置为引导节点,启动其他节点(例如node2)连接即可:

首先需要启动ipfs daemon节点node1

查看node1的地址

ipfs id
# /ip4/192.168.33.101/tcp/4001/p2p/12D3KooWPqPuHFePb6WKsiu1eqkHipYQLNV8t6ZX3SZGhiAonqJG

添加node1

ipfs bootstrap add /ip4/192.168.33.101/tcp/4001/p2p/12D3KooWPqPuHFePb6WKsiu1eqkHipYQLNV8t6ZX3SZGhiAonqJG

启动其他节点

ipfs daemon

查看对等节点

ipfs swarm peers

说明:

可以使用配置文件中 "Peering": { "Peers": null }中添加需要保护的连接,启动时也会自动连接

问题:节点启动后announce地址可能没有指定的地址,可以在配置文件中announce中添加发布的地址(也可以直接连接)

至此,多个节点组成的私有网络搭建完毕,外部的节点不能连接,也不能访问该网络中的文件;对于管理多个IPFS节点和保证数据的安全和可靠性,可以搭建IPFS Cluster集群

IPFS Cluster搭建

IPFS-Cluster节点和IPFS是一一对应的关系,先搭建上述的IPFS多节点网络,继续搭建IPFS-Cluster。官方文档

简单介绍两者的关系:

ipfs-cluster-service启动一个cluster peer节点,它依赖于一个ipfs daemon节点;cluster节点会加入一个独立于IPFS网络的另一个swarm网络

cluster peer会参与集群的共识,遵循一个关于固定pin和解除固定unpin请求的分布式日志,并且对配置的IPFS daemon管理相关的pin操作

cluster peer提供用于集群管理的API,和一个IPFS Proxy API将请求转发给IPFS daemon,以及内部通信的组件

             +------------------+
             | ipfs-cluster-ctl |
             +---------+--------+
                       |
                       | HTTP(s)
ipfs-cluster-service   |                           HTTP
+----------+--------+--v--+----------------------+      +-------------+
| RPC      | Peer 1 | API | IPFS Connector/Proxy +------> IPFS daemon |
+----^-----+--------+-----+----------------------+      +-------------+
     | libp2p
     |
+----v-----+--------+-----+----------------------+      +-------------+
| RPC      | Peer 2 | API | IPFS Connector/Proxy +------> IPFS daemon |
+----^-----+--------+-----+----------------------+      +-------------+
     |
     |
+----v-----+--------+-----+----------------------+      +-------------+
| RPC      | Peer 3 | API | IPFS Connector/Proxy +------> IPFS daemon |
+----------+--------+-----+----------------------+      +-------------+

默认情况下,集群使用:

  • 9096/tcp 作为集群 swarm 端点,它应该是开放的并且可以被其他集群对等点拨叫。
  • 9094/tcp 作为 HTTP API 端点
  • 9095/tcp 作为代理 API 端点

下载

按照上述地址下载相关组件

  • ipfs-cluster-service(每个节点安装) —用于启动一个cluster对等节点
  • ipfs-cluster-ctl(一个节点安装即可) —用于和ipfs-cluster-service进行交互
  • ipfs-cluster-follower(可选,运行一个follower peer没有写权限,用于加入协作集群)

下载后,直接解压其,将对应的二进制文件移动到/usr/local/bin下即可

配置

所有的cluster peer需要使用相同的secret以及共识组件,先在node1节点进行初始化(默认使用CRDT):

需要先启动本节点的IPFS daemon

ipfs-cluster-service init

会在~/ipfs-cluster/下生成3个文件:

  • identity: cluster peer的id和私钥
  • peerstore: 存储已知的对等节点地址
  • service.json: 配置文件

可以查看service.json当前节点的secret密钥;其他节点设置成与节点node1相同:

ipfs-cluster-service init --secrect <node1-secret>

设置密钥也可以使用相同的环境变量CLUSTER-SECRETs

另外,可以使用远程的配置文件,也可是使用存储在IPFS中的配置文件ipfs-cluster-service init http://localhost:8080/ipns/config.mydomain.com

先启动节点node1对应的cluster peer:

ipfs-cluster-service daemon

启动其他节点

其他节点设置完相同的secret后,直接添加节点node1启动对应的cluster peer

查看节点node1的id:

ipfs-cluster-ctl id
#  /ip4/192.168.33.101/tcp/9096/p2p/12D3KooWAPR46HGRohMM1xLcrL2FUgLkWm1qtv6W4YHdLYue6hMW

如果没有显示私有地址,可以直接使用该地址

启动其余节点时使用–bootstrap选项:

ipfs-cluster-service daemon --bootstrap /ip4/192.168.33.101/tcp/9096/p2p/12D3KooWAPR46HGRohMM1xLcrL2FUgLkWm1qtv6W4YHdLYue6hMW

多个节点的IPFS Cluster搭建完成

其他配置

对于生产环境,配置文件提供了很多配置,详细查阅文档

IPFS-Cluster配置参考文档

Cluster集群的交互

对等节点

ipfs-cluster-ctl peers list

添加文件

集群默认的Pinset计划分配策略是每个节点固定一次,对应的配置文件中service.json:

"cluster":{
    ...
    "replication_factor_min": -1,
    "replication_factor_max": -1,
    ...
}

在节点node1添加一个haha.gif文件:【可以显示指定复制因子】

ipfs-cluster-ctl add haha.gif
# added QmRZ1eBKEvgFx38o1gGB8K2KKsno1dzzunG9cCYuhZLzwp haha.gif

可以添加的选项:

  • 指定最小和最大复制因子--replication-min 2 --replication-max 3,尽量达到max数量副本
  • 指定复制因子--replication 2
  • 设置与引脚关联的名称,例如--name website

说明:使用ipfs-cluster-ctl add <file>添加的文件才会使用集群的管理,遵循分配策略;直接使用ipfs add <file>只是添加到该节点本地存储

将已经添加到IPFS节点中的CID(或者可以访问的CID)固定到Cluster:

ipfs-cluster-ctl pin add <CID> 

ipfs-cluster-ctl add相当于先将文件添加到 ipfs网络然后将其pin固定到cluster

详细的添加过程和操作可以查阅官方文档

文件状态

注意的地方:

  • ipfs-cluster-ctl pin ls显示来自集群共享状态全局 pinset 的信息,这些信息在每个对等点中都完全可用。它显示了Pin的分配节点以及Pin的相关配置
  • ipfs-cluster-ctl status请求有关每个集群对等体上每个 pin 状态信息,包括该 CID 是否在 IPFS 上被 PINNED,或者仍然是 PINNING,或者由于某种原因出错(实际存储),支持这些情况的过滤结果

查看cluster跟踪的CID和pin的分配策略:【cluter集群节点共享的只有CID】

ipfs-cluster-ctl pin ls # all pins
ipfs-cluster-ctl pin ls QmRZ1eBKEvgFx38o1gGB8K2KKsno1dzzunG9cCYuhZLzwp

查看pins/CID实际的固定状态:status命令

ipfs-cluster-ctl status # 所有跟踪的all cids的状态
ipfs-cluster-ctl status QmRZ1eBKEvgFx38o1gGB8K2KKsno1dzzunG9cCYuhZLzwp

删除pin(ipfs会自动解除固定)

ipfs-cluster-ctl pin rm <CID>

访问文件

所有的IPFS节点组成私有网络,可以直接使用IPFS节点访问文件:

ipfs get -o haha.gif QmRZ1eBKEvgFx38o1gGB8K2KKsno1dzzunG9cCYuhZLzwp

API

ipfs cluster的restful API

说明和总结

  • IPFS节点在本篇使用的是私有网络,但是也可以是公共节点;IPFS Cluster节点组成私有网络即可;两个网络是独立的。如果是公共网络,公共网关可以访问集群中的内容

  • 集群Cluster固定pin可以看作两个过程,一个是cluster节点维护跟踪的所有的pin集合—共识组件,另一个是对应的IPFS节点固定pin所对应的文件内容

链接Links

  1. ipfs cluster的restful API
  2. https://cluster.ipfs.io/documentation/reference/configuration/