让我们来试着将分布式分类账Hyperledger/fabric在docker swarm上进行分布式部署(3/3)〜分布式环境解释版
本文是关于使用开源软件(OSS)分布式账本技术Hyperledger/fabric创建简单的存取款处理,并尝试在Docker Swarm模式下进行分布式处理的系列文章的第三篇。
本次的最终回,我们将尝试在Docker Swarm集群上实现Hyperledger/fabric的分布式运行。
-
- 尝试使用Docker Swarm在OSS的分布式账本Hyperledger/fabric上进行分布式部署(1/3)-验证运行篇
-
- 尝试使用Docker Swarm在OSS的分布式账本Hyperledger/fabric上进行分布式部署(2/3)-智能合约解释篇
- 尝试使用Docker Swarm在OSS的分布式账本Hyperledger/fabric上进行分布式部署(3/3)-分布式环境解释篇
Docker 集群模式和 docker-compose.yaml
通过使用自2016年7月发布的1.12版本中加入的swarm mode功能,我们现在可以仅使用Docker来构建由多个节点组成的Docker集群。另外,从2017年1月发布的1.13版本开始,我们还可以从Docker Compose的yaml定义文件中将一组服务一起构建成为一个叫做”stack”的群组在swarm上运行。
最近出现了不仅仅是GKE和AKS,还有EKS的情况,作为容器编排平台似乎不仅限于kubernetes。但是,暂且可以复用docker-compose的yaml定义,无需安装其他软件即可在多个节点上分散部署容器并进行协同操作,这种情况下,docker swarm mode是很有用的。因此,本次决定使用docker swarm mode来实现Hyperledger/fabric的分布式运行(结束辩解)。
在使用Docker Swarm模式执行docker-compose的yaml定义时需要注意的事项。
○ 容器名称 ɡ qì ɡ)
如果使用docker-compose在单独的docker上启动服务,可以在yaml定义文件的service名称中使用大写字母、小写字母、数字、句点、连字符和下划线([a-zA-Z0-9\._\-])。
如果在yaml定义文件中定义了container_name,容器将以该名称启动;如果没有指定,则容器名称将以<<项目名称>>_<<服务名称>>_<<序号>>的形式附加。
事实上,在Hyperledger/fabric的官方示例docker-compose.yaml文件中,定义了一个称为ca.example.com的认证机构服务。
在docker swarm模式中,如果您尝试将在docker-compose中有效的yaml定义部署,则可能导致容器启动失败。例如,当尝试使用上述的服务名ca.example.com启动认证机构容器时,将会出现以下错误。
failed to create service fabric-payment_ca.example.com: Error response from daemon: rpc error: code = InvalidArgument desc = name must be valid as a DNS name component
在Docker Swarm模式下,即使在yaml定义文件中定义了container_name,也会被忽略,并以<<堆栈名称>>_<<服务名称>>.<<序号>>.<<任务ID>>的格式生成容器名称。看起来,这个容器名称必须符合正确的DNS名称才可以。
为了拥有一个正确的 DNS 名称,最好避免使用下划线或句点,仅限使用小写字母(或大写字母)和数字以及连字符,并选择一个尽可能简短的服务名称。
被句点(.)分隔的部分被称为“标签”。一个标签的长度必须小于63个字符,整个域名的长度(包括句点)必须小于253个字符。在标签中,可以使用英文字母(A~Z)、数字(0~9)和连字符(-),但标签的首尾字符不能是连字符。在标签中,不区分大小写,认为相同的字符是相等的。
○ 主机名称
如果在单独的Docker上使用docker-compose启动Hyperledger/Fabric网络,将会自动生成桥接网络(也可以手动创建),并通过内部DNS以服务名解析。因此,即使不进行任何特殊配置,容器之间也可以通过服务名进行通信。
如果要在分散环境下使用Swarm模式启动Hyperledger/fabric网络,您可以使用覆盖网络(overlay network)来布置虚拟网络,而不是通过桥接网络跨越多个节点。
根据docker-compose的yaml定义启动容器时不会发生任何问题。但正如第一次讲解的那样,Hyperledger/fabric会直接从peer容器内启动chaicode容器并连接到docker network。在此过程中,peer似乎正在查找docker的内部dns,但在docker swarm模式下,由于自动生成的主机名,查找会超时(详细信息没有追踪。。。)。
通过在docker-compose的yaml定义中明确指定与服务名称相同的主机名,可以避免此问题。
○ 覆盖网络名称
如果在docker-compose的yaml定义中指定了overlay driver的networks条目,那么在使用docker swarm模式部署时,将自动创建该堆栈所需的overlay网络。在启动yaml定义中定义的容器并在overlay网络上进行连接方面不会遇到任何问题,并且在删除堆栈时,该overlay网络也将被自动删除,这非常方便。但是,需要注意以下两点才能在Hyperledger/fabric中使用。
-
- overlay networkはattachableでなければならない
peerコンテナが起動したchaicodeコンテナをoverlay networkに接続するため、overlay networkには後からコンテナを接続できなければなりません。driverを指定しただけでは自動作成されたoverlay networkはattachableになりませんので、networksエントリで明示的にattachable: trueを指定する必要があります(attachable指定は、yaml定義ファイルのversionは3.3から導入)
peerコンテナに設定するCORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE環境変数の値
この環境変数には、chaincodeを接続するdocker networkの名前を設定します。docker swarm modeへのdeploy時に自動起動したoverlay networkは、<<スタック名>>_<<yaml定義中で設定したnetwork名>>という名前になりますので、network名をそのまま指定するとchaincodeコンテナが立ち上がりません。
在本次的示例中,由于将zookeeper和kafka的堆栈进行了分割,因此最终决定采用了引用预先创建的可附加的覆盖网络的方式(即使删除了堆栈,覆盖网络仍然保留,所以最后必须手动删除覆盖网络)。
指定要启动容器的节点。
由于Hyperledger/Fabric中的orderer、peer、couchdb等密切合作,协同的容器需要在适当的节点上运行(如果orderer全部在同一节点上运行,则缺乏容错性;如果peer使用的couchdb在不同的节点上运行,则在延迟和网络负载方面都不合适)。
因此,通过使用引入于version3及以后的yaml定义中的deploy指定,可以将协同的容器集合部署到适当的节点上。
version: '3'
networks:
fabric-sample-nw:
external: true
services:
...
peer0:
hostname: peer0
image: localhost:5000/fabric-payment-swarm/fabric-peer
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer0.org1.example.com
- CORE_LOGGING_PEER=debug
- CORE_CHAINCODE_LOGGING_LEVEL=DEBUG
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/
- CORE_PEER_ADDRESS=peer0:7051
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric-sample-nw
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
working_dir: /etc/hyperledger
command: peer node start
ports:
- 7051
- 7053
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
networks:
- fabric-sample-nw
deploy:
replicas: 1
placement:
constraints:
- node.labels.type == node0
...
让我们尝试使用Docker Swarm集群在分布式环境中运行。
让我们在由4台VM上的node0~node3组成的docker swarm集群上分布式运行Hyperledger/fabric,考虑到上述的注意事项。我们将使用以下容器组来构建Hyperledger/fabric网络。

动物园管理员与卡夫卡
为了在分散环境下协调orderer的操作,至少需要四个kafka节点和三个或更多奇数个zookeeper节点。(创建基于Kafka的订购服务)
在同一节点上运行两个kafka是没有容错意义的,所以在分布式环境下运行Hyperledger/fabric至少需要4个以上的节点。
CA的可用性
这次的Hyperledger/fabric网络中,认证机构(ca)成为了单点故障(SPOF)。与可以通过kafka和zookeeper进行分布式协作的orderer不同,认证机构需要自行建立高可靠性的RDBMS(PostgreSQL或MySQL)或LDAP作为后台,以实现负载均衡和故障转移。

由于我已经筋疲力尽,所以我想将认证机构的可用性放到另一个机会。
启动Docker Swarm模式集群。
-
- 移动到node0的swarm模式目录。
ubuntu@node0:~/fabric-payment-sample-docker/dev-solo$ cd ../swarm-kafka/
在node0上启动swarm集群。
由于我们在本次验证的VirtualboxVM上安装了2个虚拟网卡,所以要使用–advertise-addr指定docker swarm使用的虚拟网卡的IP地址。
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker swarm init –advertise-addr 192.168.100.10
执行docker swarm init时会显示用于将其他节点添加为worker的TOKEN,但本次不使用。
显示用于加入swarm集群作为master的TOKEN。
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker swarm join-token manager
将显示类似于以下命令字符串:
docker swarm join –token SWMTKN-1-….. 192.168.100.10:2377
在node1、node2和node3上分别执行3中显示的命令,将它们作为manager加入swarm集群。
ubuntu@node1:~$ docker swarm join –token SWMTKN-1-…… 192.168.100.10:2377
ubuntu@node2:~$ docker swarm join –token SWMTKN-1-…… 192.168.100.10:2377
ubuntu@node3:~$ docker swarm join –token SWMTKN-1-…… 192.168.100.10:2377
给每个节点添加标签。
为了能够在yaml定义中指定要在哪个节点上启动容器,我们需要为每个节点添加标签。
由于也可以通过主机名指定约束条件,所以在本次验证中即使不添加标签也可以运行。
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
n8aex03epr54vk0js3i968j7e * node0 Ready Active Leader
klg2t4ho5v47osx7mckb2ngyt node1 Ready Active Reachable
krwzoozg3l86l6ahvbhye5s8h node2 Ready Active Reachable
q31j94lguqvox13o5u84tsvvk node3 Ready Active Reachable
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker node update –label-add type=node0 n8aex03epr54vk0js3i968j7e
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker node update –label-add type=node1 klg2t4ho5v47osx7mckb2ngyt
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker node update –label-add type=node2 krwzoozg3l86l6ahvbhye5s8h
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker node update –label-add type=node3 q31j94lguqvox13o5u84tsvvk
在swarm集群中启动本地注册表
-
- 在swarm集群中启动本地注册表,以便在分布式环境的各个节点间共享构建的Docker映像。
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker service create –name registry –publish 5000:5000 registry:2
为了生成包含Hyperledger/fabric网络管理者以外的人不应知道的信息(如peer对交易进行签名的加密密钥)的Docker映像,我们将其注册到本地注册表中,而不是使用DockerHub等公共注册表。如果已经存在私有的Docker注册表服务,也可以使用该服务。
设置NFS
-
- 将node0上搭建NFS服务器。
在分布式环境下,由于REST API容器需要在多个节点上启动,所以需要在每个REST API容器上共享用于连接Hyperledger/fabric网络认证机构的密钥文件。此外,在将peer加入到channel时,还需要使用在创建channel时生成的genesis文件,所以如果由于节点故障等原因丢失了genesis文件,将会导致新的peer无法加入。由于上述文件不需要一直进行读写操作,因此决定使用NFS进行共享。
例如,如果将node0(192.168.100.10)上的/opt/nfs/fabric-payment目录通过NFS进行共享:
在node0上执行以下命令安装nfs-kernel-server:
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ sudo apt-get install nfs-kernel-server -y
在node0上创建/opt/nfs/fabric-payment/key_store和/opt/nfs/fabric-payment/genesis_store目录:
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ sudo mkdir -p /opt/nfs/fabric-payment/key_store
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ sudo mkdir -p /opt/nfs/fabric-payment/genesis_store
在node0上执行以下命令将/opt/nfs/fabric-payment添加到/etc/exports文件中:
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ sudo su -c “echo ‘/opt/nfs/fabric-payment 192.168.100.0/24(rw,sync,no_subtree_check,no_root_squash)’ >> /etc/exports”
执行以下命令刷新NFS共享配置:
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ sudo exportfs -ra
执行以下命令重启nfs-kernel-server服务:
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ sudo systemctl restart nfs-kernel-server.service
虽然这次是在node0上快速搭建了NFS服务器,但如果已经有运行中的NFS服务,则可以考虑使用现有的服务。
在node1~node3上安装NFS客户端库:
在node1上执行以下命令安装nfs-common:
ubuntu@node1:~$ sudo apt-get install nfs-common -y
在node2上执行以下命令安装nfs-common:
ubuntu@node2:~$ sudo apt-get install nfs-common -y
在node3上执行以下命令安装nfs-common:
ubuntu@node3:~$ sudo apt-get install nfs-common -y
在swarm集群上启动Hyperledger/fabric网络
-
- 根据第一步的参考,执行以下步骤:
1. 安装Docker
2. 从GitHub上克隆fabric-payment-sample-docker和fabric-payment-sample-api
3. 使用go get克隆chaincode
4. 生成REST API应用的Bearer令牌并生成Docker镜像
在fabric-payment-sample-docker/swarm-kafka中获取Hyperledger/fabric 1.1.0-rc1的二进制文件和Docker镜像
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0-rc1
设置环境变量后,生成Hyperledger/fabric所需的密钥和fabric网络配置等的artifact
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ source .env
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ export CA_ADMIN_PASSWORD=<<任意的字符串>>
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ ./generate_artifact.sh ${CA_ADMIN_PASSWORD} <<NFS服务器的IP>> <<共享目录>>
与单独的Docker不同,需要提供NFS的设置参数。
generate_artifact.sh会生成一个包含了针对每个环境不同变量的docker-compose.yaml文件,该文件也定义了使用NFS共享卷的设置。
生成的docker image包含了自动生成的每个容器所需的用于签名的密钥、chaincode和REST API的源代码,并注册到本地仓库中。详细内容请查看Dockerfile。
在分布式环境中启动Hyperledger/fabric网络
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ ./start_fabric.sh
与单独的Docker不同,要在swarm环境中将容器分布到多个节点上启动,可能需要一些时间。
因此,在start_fabric.sh中已包含等待容器启动的操作。请确认所有容器都已启动(CURRENT STATE为Running)。
特别是第一次,由于每个节点都需要从本地仓库拉取docker image,所以在zookeeper和kafka不存在的情况下尝试启动orderer时可能会失败。
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker stack ps zookeeper
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jjn0hqts9w3t zookeeper_zookeeper2.1 localhost:5000/hyperledger/fabric-zookeeper:latest node2 Running Running about a minute ago
wwtfc54krest zookeeper_zookeeper1.1 localhost:5000/hyperledger/fabric-zookeeper:latest node1 Running Running about a minute ago
6pl9wohamgfl zookeeper_zookeeper0.1 localhost:5000/hyperledger/fabric-zookeeper:latest node0 Running Running about a minute ago
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker stack ps kafka
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ab0y5b66esy4 kafka_kafka1.1 localhost:5000/hyperledger/fabric-kafka:latest node1 Running Running about a minute ago
f65rcxrzou10 kafka_kafka0.1 localhost:5000/hyperledger/fabric-kafka:latest node0 Running Running about a minute ago
355ff4e4j0rf kafka_kafka3.1 localhost:5000/hyperledger/fabric-kafka:latest node3 Running Running about a minute ago
123u0483b4lh kafka_kafka2.1 localhost:5000/hyperledger/fabric-kafka:latest node2 Running Running about a minute ago
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ docker stack ps ${STACK_NAME}
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
krfhlqfh3vvz fabric-payment_cli.krwzoozg3l86l6ahvbhye5s8h localhost:5000/fabric-payment-swarm/fabric-tools:latest node2 Running Running 38 seconds ago
1ctlrvha8ecv fabric-payment_cli.q31j94lguqvox13o5u84tsvvk localhost:5000/fabric-payment-swarm/fabric-tools:latest node3 Running Running 36 seconds ago
wcww4fuohsdi fabric-payment_cli.klg2t4ho5v47osx7mckb2ngyt localhost:5000/fabric-payment-swarm/fabric-tools:latest node1 Running Running 3 minutes ago
l9wp44p2mfub fabric-payment_cli.n8aex03epr54vk0js3i968j7e localhost:5000/fabric-payment-swarm/fabric-tools:latest node0 Running Running 3 minutes ago
tu1jc0fb1
注意
chaincodeの初期化を行ったpeer(今回のスクリプトではpeer0)以外のREST APIは、初回呼び出しに時間がかかります。これはJustInTimeで新たにコンパイル用コンテナを立ち上げてpeerにインストールされているchaincodeをコンパイルし、その後chaincode用のコンテナを立ち上げるためです。
初回呼び出しの前後で docker ps でコンテナリストを確認すると、 dev-peer1.org1.example.com-fabric-payment-0.1-….. のような名前のchaincode用コンテナが増えていることがわかります。
确认Hyperledger/fabric的分布式处理
-
- 在其他节点上验证注册的账户。
对于单独的docker情况,可使用相同的REST API。
运行在node0上的REST API的端口是3000。同样,node1是3001,node2是3002,node3是3003。
由于使用了docker的overlay网络,虚拟网络得以扩展,因此可以使用其他节点的REST API。
例如,从node0启动连接到node1上的REST API(端口3001)。
示例)在node0上注册账户
ubuntu@node0:~$ cat ${API_PATH}/api/.config/token.json | jq .token -r
4302E85F23783F132740B8A701B93534
ubuntu@node0:~$ curl -H “Content-Type: application/json” -H “Authorization: Bearer 4302E85F23783F132740B8A701B93534” http://localhost:3000/fabric-payment/accounts/ -X POST -d ‘{“name”:”ほげ”}’ | jq .
{
“model_type”: “account”,
“no”: “6107511000263813”,
“name”: “ほげ”,
“balance”: 0
}
示例)在node1上获取账户列表
ubuntu@node1:~$ curl -H “Content-Type: application/json” -H “Authorization: Bearer 4302E85F23783F132740B8A701B93534” http://localhost:3001/fabric-payment/accounts/ | jq .
[
{
“model_type”: “account”,
“no”: “6107511000263813”,
“name”: “ほげ”,
“balance”: 0
}
]
通过一个API节点注册或更新的信息将被传递给Hyperledger/fabric网络中的所有对等节点。因此,在提交成功后,可以随时从另一个节点的REST API中查询到实时数据。
确认Hyperledger/fabric的故障恢复。
-
- 节点0发生故障,与Hyperledger/fabric网络断开连接。
停止节点0的docker进程后,节点0将被从集群中排除。新的Leader节点将被选出,集群将在节点1至节点3上继续运行。
ubuntu@node0:~$ sudo systemctl stop docker.service
ubuntu@node1:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
n8aex03epr54vk0js3i968j7e node0 Down Active Unreachable
klg2t4ho5v47osx7mckb2ngyt * node1 Ready Active Reachable
krwzoozg3l86l6ahvbhye5s8h node2 Ready Active Leader
q31j94lguqvox13o5u84tsvvk node3 Ready Active Reachable
添加账户。
即使出现一个节点宕机,Hyperledger/fabric网络仍然在运行。我们尝试在节点3上添加另一个账户。
ubuntu@node3:~$ curl -H “Content-Type: application/json” -H “Authorization: Bearer 4302E85F23783F132740B8A701B93534” http://localhost:3003/fabric-payment/accounts/ -X POST -d ‘{“name”:”ふが”}’ | jq .
{
“model_type”: “account”,
“no”: “9962914372253968”,
“name”: “ふが”,
“balance”: 0
}
ubuntu@node3:~$ curl -H “Content-Type: application/json” -H “Authorization: Bearer 4302E85F23783F132740B8A701B93534” http://localhost:3003/fabric-payment/accounts/ | jq .
[
{
“model_type”: “account”,
“no”: “6107511000263813”,
“name”: “ほげ”,
“balance”: 0
},
{
“model_type”: “account”,
“no”: “9962914372253968”,
“name”: “ふが”,
“balance”: 0
}
]
恢复节点0的故障。
当节点0恢复故障时,swarm集群将检测到并自动加入swarm集群。之前降级的stack也会恢复,并且所需的容器将自动在节点0上启动。
故障恢复后:
ubuntu@node0:~$ sudo systemctl start docker.service
ubuntu@node0:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
自动回归到swarm集群之后:
ubuntu@node0:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
6k32ss9rdtfe6c0e0m6xf979y * node0 Ready Active Reachable
62retjrvcwkeky1q0mqveojvj node1 Ready Active Reachable
izk1hvipbfuhoedhdx6dmh5ri node2 Ready Active Leader
09w52jcgw2u4g5mjt0t1qe39b node3 Ready Active Reachable
ubuntu@node0:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ec086151a3f localhost:5000/fabric-payment-swarm/api:latest “npm start” 49 seconds ago Up 35 seconds fabric-payment_api0.1.swhbo2iqrwgphku8mcson7nbq
b566619f22e0 localhost:5000/fabric-payment-swarm/fabric-ca:latest “sh -c ‘fabric-ca-se…” 49 seconds ago Up 33 seconds 7054/tcp fabric-payment_ca.1.p29wism0liy4b0iuud8qkamfs
313356c1b5a9 localhost:5000/hyperledger/fabric-zookeeper:latest “/docker-entrypoint.…” 49 seconds ago Up 33 seconds 2181/tcp, 2888/tcp, 3888/tcp zookeeper_zookeeper0.1.390um287fl0eywo1gdeu0v4wp
88f896299029 localhost:5000/fabric-payment-swarm/fabric-orderer:latest “orderer” 49 seconds ago Up 32 seconds 7050/tcp fabric-payment_orderer0.1.ogyc9a76hkwntx18vr6qgyhix
e916f36bc41e localhost:5000/fabric-payment-swarm/fabric-peer:latest “peer node start” 49 seconds ago Up 36 seconds fabric-payment_peer0.1.huz6q7x4763ky3jjtdlnqcohc
4e6a18cce499 localhost:5000/hyperledger/fabric-kafka:latest “/docker-entrypoint.…” 50 seconds ago Up 32 seconds 9092-9093/tcp kafka_kafka0.1.vqvd3el46ce23l87jauhu0sbf
eef8f7db4258 localhost:5000/fabric-payment-swarm/fabric-tools:latest “/bin/bash” 50 seconds ago Up 37 seconds fabric-payment_cli.yufr9amrmtml1b1owsvmnkb2z.k5p5vub6k3y8vtkh0jhp4msok
b56170b724e6 localhost:5000/hyperledger/fabric-couchdb:latest “tini — /docker-ent…” 51 seconds ago Up 29 seconds 4369/tcp, 5984/tcp, 9100/tcp fabric-payment_couchdb0.1.tu2qy3xbiads9bez5yhqt1ecu
节点0的容器加入Hyperledger/fabric网络。
遗憾的是,无法自动恢复到Hyperledger/fabric网络。必须加入正在运行的通道并安装chaincode。
1)定义变量
ubuntu@node0:~$ ORDERER_ADDRESS=”orderer0:7050″
ubuntu@node0:~$ PEER_ADDRESS=”peer0:7051″
ubuntu@node0:~$ LOCALMSPID=”Org1MSP”
ubuntu@node0:~$ PEER_MSPCONFIGPATH=”/etc/hyperledger/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp”
ubuntu@node0:~$ CHANNEL_NAME=”fabric-sample”
ubuntu@node0:~$ CHAINCODE_SRC=”github.com/nmatsui/fabric-payment-sample-chaincode”
ubuntu@node0:~$ CHAINCODE_VERSION=”0.1″
ubuntu@node0:~$ CLI=$(docker ps -f name=fabric-payment_cli -q)
2)从nfs中
结束Hyperledger/Fabric的网络。
-
- 关闭Hyperledger/fabric网络。
ubuntu@node0:~/fabric-payment-sample-docker/swarm-kafka$ ./terminate.sh <<NFS服务器的IP>> <<共享目录>>
与单独使用Docker不同,需要在参数中提供NFS设置。
在本次脚本和配置文件中,hyperledger/fabric的认证机构信息会在容器删除时一同消失。因此,如果认证密钥文件仍然存在,当再次启动Hyperledger/fabric网络时会发生认证错误。为了防止这种情况发生,在terminate.sh中删除了存储在NFS中的密钥文件。
在node1的docker中,可能会残留一些已停止但未删除的容器。这是因为未受swarm stack管理的容器,如chaincode容器等,在删除stack后无法删除。
最后
我在docker swarm集群上成功地分散运行了Hyperledger/fabric网络,一切顺利。如果有时间,我也想在kubernetes上尝试一下!