搭建过程应该是这样的:
Fabric在开始之前,一般会根据项目的需求,把整个项目中可能涉及的参与方(组织)和参与方大概的规模(节点和用户账号数)罗列出来,不过后期也可以动态加入用户和组织,但是前期考虑得越周全,后期相对工作量会少一些。
罗列组织、节点、用户数目的意义在于前期为其生成组织、节点、用户的证书,这在创建容器的时候是需要列入到环境变量中的env
。
在生成证书前(前期),需要搭建Fabric-tools容器框架,其yaml文件我将会放在github上。
首先需要创建文件挂载的目录:
root@kexin228-lab:~/fabric# tree -L 4 tools/
tools/
├── chaincode
├── channel-artifacts
├── configtx.yaml
├── crypto-config
├── crypto-config.yaml
├── docker-sock
└── scripts
接着按照yaml创建容器,按照惯例一般命名为cli。注意启动参数中的CORE_PEER_ADDRESS
之流,我们其实还没有创建这些Peer,CLI启动的时候默认连接的是peer0.org1.example.com,并且关闭了TLS。默认是以[email protected]这个身份连接到Peer的。不过为了之后的方便,早先设置了而已。
CLI启动的时候,可以去执行/scripts/script.sh里面的脚本,这个脚本完成了Fabric环境的初始化和ChainCode的安装及运行。由于我们这里是从零开始搭建,所以脚本会在以后的过程中一步一步完善。
在容器外编写crypto-config.yaml文件,这里我们设定有3个组织,其中第三个组织有2个节点3个用户,其他是1个节点2个用户。同样,可以在我的github上看到。
在容器内执行:
root@kexin228-lab:~/fabric/tools# kubectl exec -it cli-7b8b4f667b-v8jrn -n fabric bash
root@cli-7b8b4f667b-v8jrn:/opt/gopath/src/github.com/hyperledger/fabric/peer# cryptogen generate --config /etc/hyperledger/fabric/crypto-config.yaml --output /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
org1.example.com
org2.example.com
org3.example.com
在容器外查看结构:
root@kexin228-lab:~/fabric/tools/crypto-config# tree -L 4
.
├── ordererOrganizations
│ └── example.com
│ ├── ca
│ │ ├── a271118376f9037e9c392c188f9ca98c4e7ee7a497d3113407a9a8a3cf58c1cb_sk
│ │ └── ca.example.com-cert.pem
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ └── tlscacerts
│ ├── orderers
│ │ └── orderer.example.com
│ ├── tlsca
│ │ ├── 2e31c2fb58e5209822cac7d7a54c93aa98def6aeac8e8adfa13da7707c7de5a9_sk
│ │ └── tlsca.example.com-cert.pem
│ └── users
│ └── [email protected]
└── peerOrganizations
├── org1.example.com
│ ├── ca
│ │ ├── b864f4b2f37f5026f9f1e188f1b401dea7b7548c8bcf094ce6f7909f3ac9de52_sk
│ │ └── ca.org1.example.com-cert.pem
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ └── tlscacerts
│ ├── peers
│ │ └── peer0.org1.example.com
│ ├── tlsca
│ │ ├── 4cc9f95ecbc8bbd82f232fddcc0dbed8a4b1105f6d89739b4a25efc363677430_sk
│ │ └── tlsca.org1.example.com-cert.pem
│ └── users
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
......省略
现在证书就生成了。
在Orderer模块启动之前需要生成一个创始块文件和Orderer模块所需的配置文件。
在容器fabric-tools中:
创始块的创建需要通过configtxgen模块根据配置文件configtx.yaml来生成。
生成Orderer创世块orderer.genisis.block:
root@cli-7b8b4f667b-mtnzw:/# configtxgen -profile OrgsOrdererGenesis -outputBlock /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/orderer.genisis.block -configPath /etc/hyperledger/fabric
...
2019-11-19 09:02:57.019 UTC [common.tools.configtxgen] doOutputBlock -> INFO 00d Generating genesis block
2019-11-19 09:02:57.020 UTC [common.tools.configtxgen] doOutputBlock -> INFO 00e Writing genesis block
由于我们没有在之前的configtx.yaml文件中配置背书的policy,所以会有许多的WARN,不用在意。
系统创始块完成后,就可以启动Orderer了,并标注orderer的启动文件之一是orderer.genisis.block。
- name: ORDERER_GENERAL_GENESISFILE
value: "/etc/hyperledger/configtx/orderer.genisis.block"
启动Orderer节点后,暴露端口7050即可,这里只需要其提供排序服务。
Peer节点要配置的env
比较多,重点是下面这几个:
- name: CORE_PEER_MSPCONFIGPATH
value: /etc/hyperledger/msp/peerOrganizations/org1.example.com/users/[email protected]/msp
- name: CORE_PEER_GOSSIP_EXTERNALENDPOINT
value: "peer0.org1.example.com:7051"
- name: CORE_PEER_GOSSIP_BOOTSTRAP
value: "peer0.org1.example.com:7051"
- name: CORE_PEER_CHAINCODELISTENADDRESS
value: "peer0.org1.example.com:8000"
暴露链码端口和gossip协议端口,明确权限Admin(后面通知锚节点需要)。
启动命令是peer node start。
回到cli容器内,使用下面的代码创建一个channel提案文件:
root@cli-7fdd76c644-vmttb:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts# configtxgen -profile TwoOrgsChannel -outputCreateChannelTx /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/fabricchannel.tx -channelID fabricchannel
2019-11-20 12:01:19.353 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2019-11-20 12:01:19.357 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /etc/hyperledger/fabric/configtx.yaml
2019-11-20 12:01:19.360 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2019-11-20 12:01:19.360 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /etc/hyperledger/fabric/configtx.yaml
2019-11-20 12:01:19.360 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
....
然后是创建锚节点通知提案。锚节点通知提案负责将Channel创建的消息告诉给各个锚节点,锚节点负责通知其他组织Channel创建的消息。
root@cli-7fdd76c644-vmttb:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts# configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org1MSPanchors.tx -channelID fabricchannel -asOrg Org1MSP
2019-11-20 12:03:11.983 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2019-11-20 12:03:11.986 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /etc/hyperledger/fabric/configtx.yaml
2019-11-20 12:03:11.989 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2019-11-20 12:03:11.989 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /etc/hyperledger/fabric/configtx.yaml
2019-11-20 12:03:11.989 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2019-11-20 12:03:11.990 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
同样的命令也给组织Org2和3运行一次,现在就会有三个锚节点通知的.tx文件:
root@cli-7fdd76c644-vmttb:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts# lsfabricchannel.block fabricchannel.tx Org1MSPanchors.tx Org2MSPanchors.tx Org3MSPanchors.tx
现在,需要进入到peer1节点容器中,创建Channel初始块。
root@peer0-77f66bf48d-hsxpp:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel create -t 50s -o orderer:7050 -c fabricchannel -f /etc/hyperledger/channel-artifacts/fabricchannel.tx
2019-11-20 13:35:05.585 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 13:35:05.589 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 13:35:05.590 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2019-11-20 13:35:05.729 UTC [cli.common] readBlock -> INFO 004 Received block: 0
注意,这里超级容易犯错的是,fabricchanel不能与orderer的创始区块重名,因为后面加入的区块不是orderer的创始区块
orderer.genisis.block
,而是在这个命令之后自动生成的区块fabricchannel.block
。错误可以查看:https://stackoverflow.com/questions/52019932/hyperledger-fabric-peer-join-fails-with-bad-proposal-response
然后将Pee1节点加入到Channel中。
root@peer0-78df849db8-nfjkk:/etc/hyperledger/channel-artifacts# peer channel join -b /etc/hyperledger/channel-artifacts/fabricchannel.block
2019-11-20 12:10:32.890 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 12:10:32.894 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 12:10:32.895 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2019-11-20 12:10:33.305 UTC [channelCmd] executeJoin -> INFO 004 Successfully submitted proposal to join channel
通知锚节点:
root@peer0-77f66bf48d-hsxpp:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel update -o orderer:7050 -c fabricchannel -f /etc/hyperledger/channel-artifacts/Org1MSPanchors.tx2019-11-20 13:36:48.638 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 13:36:48.646 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 13:36:48.647 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2019-11-20 13:36:48.666 UTC [channelCmd] update -> INFO 004 Successfully submitted channel update
运行下面的代码可以查看peer现在加入的channel:
root@peer0-78df849db8-nfjkk:/etc/hyperledger/channel-artifacts# peer channel list
2019-11-20 12:11:45.264 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 12:11:45.273 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-11-20 12:11:45.274 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
Channels peers has joined:
fabricchannel
之前将chaincode外挂,编写好chaincode.go之后,就可以安装chaincode了。
在cli容器内进行操作:
root@cli-698848dd7f-kn7qd:/opt/gopath/src# peer chaincode install -n mychaincode -v 1.0 -p chaincode/go
2019-11-20 12:58:11.708 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-11-20 12:58:11.708 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2019-11-20 12:58:12.034 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:
这个操作其实是调用了docker daemon 来实例化一个容器dev-peer0.org1.example.com-mychaincode-1.0
,只不过这个容器很快就退出了。
[root@master ~]# docker ps -a |grep peer
2dfd2ae2aacc dev-peer0.org1.example.com-mychaincode-1.0 "chaincode -peer.add…" About a minute ago Exited (0) 57 seconds ago dev-peer0.org1.example.com-mychaincode-1.0
c24f706229ef 6830dcd7b9b5 "peer node start" 3 minutes ago Up 3 minutes k8s_peer0_combined-fabric-f8b9b9bc9-gllhq_fabric_d0b1d077-ffde-4f17-ba94-03732eafabaf_0
30908e545989 dev-peer0.org1.example.com-mychaincode-1.1-d8a53caa451b4c7a3a23711f2bc136d62a0b714897f0f45a6eb9aa006e8cec7e "chaincode -peer.add…" 2 days ago Exited (0) 12 hours ago
我们用查看该容器初始化的历史:
[root@master ~]# docker history dev-peer0.org1.example.com-mychaincode-1.0
IMAGE CREATED CREATED BY SIZE COMMENT
052c49738f17 9 hours ago /bin/sh -c #(nop) ENV CORE_CHAINCODE_BUILDL… 0B
588baab3f55c 9 hours ago /bin/sh -c #(nop) LABEL org.hyperledger.fab… 0B
7408fa328de0 9 hours ago /bin/sh -c #(nop) ADD file:396d10acb8621dea5… 16.2MB
4b0cab202084 2 years ago /bin/sh -c cd /tmp/scripts && common/ini… 39.3MB
2 years ago /bin/sh -c #(nop) COPY dir:e0b3f18ba57fdfefb… 8.34kB
2 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
2 years ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B
2 years ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$… 2.76kB
2 years ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B
2 years ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B
2 years ago /bin/sh -c #(nop) ADD file:141408db9037263a4… 117MB
其实就是在pee0容器的基础上添加了file并运行。
接着实例化chaincode:
root@combined-fabric-f8b9b9bc9-gllhq:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode instantiate -o combined-fabric:7050 -C mcbupt -n mychaincode -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
2019-11-22 01:20:30.527 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2019-11-22 01:20:30.527 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2019-11-22 01:20:30.528 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2019-11-22 01:20:30.528 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2019-11-22 01:20:30.529 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A92070A6408031A0C08DEEFDCEE0510...324D53500A04657363630A0476736363
2019-11-22 01:20:30.529 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: C7F514F14D7B23F8F1B9505059F1E60BC1C99BBE4F0ACA469E83F99ED1DBF4A3
...
如果遇到初始化失败,可以参考这篇Deploy Hyperledger Fabric on Kubernetes Part 1和这篇https://github.com/MCLDG-zz/fabric-on-kubernetes来修改docker的dns,其原因是docker启动了一个chaincode的容器,导致k8s无法感知到。