所有的节点分离部署, 每台主机上有一个节点
名称 | IP | Hostname | 组织机构 |
orderer | 192.168.220.31 | orderer.test.com | Orderer |
goPeer0 | 192.168.220.32 | peer0.orgGo.com | OrgGo |
cppPeer0 | 192.168.220.33 | peer0.orgCpp.com | OrgCpp |
ps:安装Fabric一机多节点和配置证书详情等请看上一节文档。
1. n台主机需要创建一个名字相同的工作目录
# 192.168.220.31
mkdir ~/testwork
# 192.168.220.32
mkdir ~/testwork
# 192.168.220.33
mkdir ~/testwork
关闭防火墙:
systemctl stop firewalld
systemctl disable firewalld
2.安装Fabric1.4单机版,并将bin文件中的可执行文件拷贝至/usr/local/bin中,(单机版教程请参考上一节)
cd ....//fabric 1.4fabric-sample中的bin文件
cp * /usr/local/bin
3.编写配置文件 -> 生成证书(只在orderer节点上运行)
vim crypto-config.yaml
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
# ---------------------------------------------------------------------------
# Orderer
# ---------------------------------------------------------------------------
- Name: Orderer
Domain: test.com
# ---------------------------------------------------------------------------
# "Specs" - See PeerOrgs below for complete description
# ---------------------------------------------------------------------------
Specs:
- Hostname: orderer
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: OrgGo
Domain: orgGo.test.com
EnableNodeOUs: false
# ---------------------------------------------------------------------------
# "CA"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of the CA for this
# organization. This entry is a Spec. See "Specs" section below for details.
# ---------------------------------------------------------------------------
# CA:
# Hostname: ca # implicitly ca.org1.example.com
# Country: US
# Province: California
# Locality: San Francisco
# OrganizationalUnit: Hyperledger Fabric
# StreetAddress: address for org # default nil
# PostalCode: postalCode for org # default nil
# ---------------------------------------------------------------------------
# "Specs"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of hosts in your
# configuration. Most users will want to use Template, below
#
# Specs is an array of Spec entries. Each Spec entry consists of two fields:
# - Hostname: (Required) The desired hostname, sans the domain.
# - CommonName: (Optional) Specifies the template or explicit override for
# the CN. By default, this is the template:
#
# "{{.Hostname}}.{{.Domain}}"
#
# which obtains its values from the Spec.Hostname and
# Org.Domain, respectively.
# - SANS: (Optional) Specifies one or more Subject Alternative Names
# to be set in the resulting x509. Accepts template
# variables {{.Hostname}}, {{.Domain}}, {{.CommonName}}. IP
# addresses provided here will be properly recognized. Other
# values will be taken as DNS names.
# NOTE: Two implicit entries are created for you:
# - {{ .CommonName }}
# - {{ .Hostname }}
# ---------------------------------------------------------------------------
# Specs:
# - Hostname: foo # implicitly "foo.org1.example.com"
# CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
# SANS:
# - "bar.{{.Domain}}"
# - "altfoo.{{.Domain}}"
# - "{{.Hostname}}.org6.net"
# - 172.16.10.31
# - Hostname: bar
# - Hostname: baz
# ---------------------------------------------------------------------------
# "Template"
# ---------------------------------------------------------------------------
# Allows for the definition of 1 or more hosts that are created sequentially
# from a template. By default, this looks like "peer%d" from 0 to Count-1.
# You may override the number of nodes (Count), the starting index (Start)
# or the template used to construct the name (Hostname).
#
# Note: Template and Specs are not mutually exclusive. You may define both
# sections and the aggregate nodes will be created for you. Take care with
# name collisions
# ---------------------------------------------------------------------------
Template:
Count: 2
# Start: 5
# Hostname: {{.Prefix}}{{.Index}} # default
# SANS:
# - "{{.Hostname}}.alt.{{.Domain}}"
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
# ---------------------------------------------------------------------------
# Org2: See "Org1" for full specification
# ---------------------------------------------------------------------------
- Name: OrgCpp
Domain: orgCpp.test.com
EnableNodeOUs: false
Template:
Count: 2
Users:
Count: 1
运行(只在orderer节点上运行)
cryptogen generate --config=crypto-config.yaml
- 生成通道文件和创始块文件(只在orderer节点上运行)
# vim configtx.yaml -> 名字不能变
################################################################################
#
# Section: Organizations
#
################################################################################
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/test.com/msp
- &OrgGo
Name: OrgGoMSP
ID: OrgGoMSP
MSPDir: crypto-config/peerOrganizations/orgGo.test.com/msp
AnchorPeers:
- Host: peer0.orgGo.test.com
Port: 7051
- &OrgCpp
Name: OrgCppMSP
ID: OrgCppMSP
MSPDir: crypto-config/peerOrganizations/orgCpp.test.com/msp
AnchorPeers:
- Host: peer0.orgCpp.test.com
Port: 7051
################################################################################
#
# SECTION: Capabilities
#
################################################################################
Capabilities:
Global: &ChannelCapabilities
V1_1: true
Orderer: &OrdererCapabilities
V1_1: true
Application: &ApplicationCapabilities
V1_2: true
################################################################################
#
# SECTION: Application
#
################################################################################
Application: &ApplicationDefaults
Organizations:
################################################################################
#
# SECTION: Orderer
#
################################################################################
Orderer: &OrdererDefaults
# Available types are "solo" and "kafka"
OrdererType: solo
Addresses:
- orderer.test.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 100
AbsoluteMaxBytes: 32 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
Organizations:
################################################################################
#
# Profile
#
################################################################################
Profiles:
ItcastOrgsOrdererGenesis:
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *OrgGo
- *OrgCpp
ItcastOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *OrgGo
- *OrgCpp
Capabilities:
<<: *ApplicationCapabilities
创建channel-artifacts目录(只在orderer节点上运行)
mkdir channel-artifacts
生成创始块文件(只在orderer节点上运行)
configtxgen -profile ItcastOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
生成通道文件(只在orderer节点上运行)
configtxgen -profile ItcastOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID testchannel
若未指定channelID,则默认是mychannel
- 编写orderer节点启动的docker-compose.yaml配置文件
version: '2'
services:
orderer.test.com:
container_name: orderer.test.com
image: hyperledger/fabric-orderer:latest
environment:
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=testwork_default
- ORDERER_GENERAL_LOGLEVEL=INFO
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./crypto-config/ordererOrganizations/test.com/orderers/orderer.test.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/test.com/orderers/orderer.test.com/tls/:/var/hyperledger/orderer/tls
networks:
default:
aliases:
- testwork # 这个名字使用当前配置文件所在的目录 的名字
ports:
- 7050:7050
部署文件:
docker-compose -f docker-compose.yaml up -d
查看是否成功:
[root@node2 testwork]# docker-compose -f docker-compose.yaml ps
Name Command State Ports
-----------------------------------------------------------
orderer.test.com orderer Up 0.0.0.0:7050->7050/tcp
1.拷贝ordder节点中testwork目录下的channel-artifacts、crypto-config至goPeer0中
#使用ssh
scp (文件名) [email protected]:/home{目标path}
scp -r channel-artifacts crypto-config [email protected]:/root/testwork
2.修改docker-compose.yaml
version: '2'
services:
peer0.orgGo.test.com:
container_name: peer0.orgGo.test.com
image: hyperledger/fabric-peer:latest
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=testwork_default
- CORE_LOGGING_LEVEL=INFO
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_LOCALMSPID=OrgGoMSP
- CORE_PEER_ID=peer0.orgGo.test.com
- CORE_PEER_ADDRESS=peer0.orgGo.test.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.orgGo.test.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.orgGo.test.com:7051
# TLS
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/orgGo.test.com/peers/peer0.orgGo.test.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/orgGo.test.com/peers/peer0.orgGo.test.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
networks:
default:
aliases:
- testwork
ports:
- 7051:7051
- 7053:7053
extra_hosts: # 声明域名和IP的对应关系
- "orderer.test.com:192.168.220.31"
cli:
container_name: cli
image: hyperledger/fabric-tools:latest
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.orgGo.test.com:7051
- CORE_PEER_LOCALMSPID=OrgGoMSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgGo.test.com/peers/peer0.orgGo.test.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgGo.test.com/peers/peer0.orgGo.test.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgGo.test.com/peers/peer0.orgGo.test.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgGo.test.com/users/[email protected]/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./chaincode/:/opt/gopath/src/github.com/chaincode
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on: # 启动顺序
- peer0.orgGo.test.com
networks:
default:
aliases:
- testwork
extra_hosts:
- "orderer.test.com:192.168.220.31"
- "peer0.orgGo.test.com:192.168.220.32"
3.在testwork目录下创建chaincode目录,并将链代码放入其中
mkdir chaincode
链代码地址:https://github.com/lsy-zhaoshuaiji/faricInstall
4.运行docker-compose文件
docker-compose -f docker-compose.yaml up -d
执行命令后,若无报错,则代表成功。
5.进入到Cli容器中, 创建通道
peer channel create -o orderer.test.com:7050 -c testchannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/test.com/msp/tlscacerts/tlsca.test.com-cert.pem
若没error,则代表成功。
6.将当前节点加入到通道中
peer channel join -b testchannel.block
7.安装链码
peer chaincode install -n testcc -v 1.0 -l golang -p github.com/chaincode
1.拷贝ordder节点中testwork目录下的channel-artifacts、crypto-config至cppPeer0中
#使用ssh
scp (文件名) [email protected]:/home{目标path}
scp -r channel-artifacts crypto-config [email protected]:/root/testwork
2.从GoPeer0中拷贝通道文件到该宿主机:(在gopeer0上执行)
docker cp cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/testchannel.block ./
scp testchannel.block [email protected]:/root/testwork/
3.修改docker-compose.yaml
version: '2'
services:
peer0.orgCpp.test.com:
container_name: peer0.orgCpp.test.com
image: hyperledger/fabric-peer:latest
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=testwork_default
- CORE_LOGGING_LEVEL=INFO
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_LOCALMSPID=OrgCppMSP
- CORE_PEER_ID=peer0.orgCpp.test.com
- CORE_PEER_ADDRESS=peer0.orgCpp.test.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.orgCpp.test.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.orgCpp.test.com:7051
# TLS
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/orgCpp.test.com/peers/peer0.orgCpp.test.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/orgCpp.test.com/peers/peer0.orgCpp.test.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
networks:
default:
aliases:
- testwork
ports:
- 7051:7051
- 7053:7053
extra_hosts: # 声明域名和IP的对应关系
- "orderer.test.com:192.168.220.31"
- "peer0.orgGo.test.com:192.168.220.32"
cli:
container_name: cli
image: hyperledger/fabric-tools:latest
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.orgCpp.test.com:7051
- CORE_PEER_LOCALMSPID=OrgCppMSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgCpp.test.com/peers/peer0.orgCpp.test.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgCpp.test.com/peers/peer0.orgCpp.test.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgCpp.test.com/peers/peer0.orgCpp.test.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgCpp.test.com/users/[email protected]/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./chaincode/:/opt/gopath/src/github.com/chaincode
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on: # 启动顺序
- peer0.orgCpp.test.com
networks:
default:
aliases:
- testwork
extra_hosts:
- "orderer.test.com:192.168.220.31"
- "peer0.orgGo.test.com:192.168.220.32"
- "peer0.orgCpp.test.com:192.168.220.33"
3.运行docker-compose文件
docker-compose -f docker-compose.yaml up -d
执行命令后,若无报错,则代表成功。
5.进入Cli容器中,将当前节点加入到通道中
fabric/peer# peer channel join -b ./channel-artifacts/testchannel.block
6.安装链码
peer chaincode install -n testcc -v 1.0 -l golang -p github.com/chaincode
7.初始化链码:
$ peer chaincode instantiate -o orderer节点地址:端口 --tls true --cafile orderer节点pem格式的证书文件 -C 通道名称 -n 链码名称 -l 链码语言 -v 链码版本 -c 链码Init函数调用 -P 背书策略
peer chaincode instantiate -o orderer.test.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/test.com/msp/tlscacerts/tlsca.test.com-cert.pem -C testchannel -n testcc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('OrgGoMSP.member', 'OrgCppMSP.member')"
8.通过查询进行验证
peer chaincode query -C testchannel -n testcc -c '{"Args":["query","a"]}'
若返回值中有100则代表验证成功!
9.调用方法修改数据进行验证(可略)
peer chaincode invoke -o orderer.test.com:7050 -C testchannel -n testcc --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/test.com/orderers/orderer.test.com/msp/tlscacerts/tlsca.test.com-cert.pem --peerAddresses peer0.OrgGo.test.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgGo.test.com/peers/peer0.orgGo.test.com/tls/ca.crt --peerAddresses peer0.orgCpp.test.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgCpp.test.com/peers/peer0.orgCpp.test.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
10.链码的打包(可略)
我们在进行多机多节点部署的时候, 所有的peer节点都需要安装链码, 有时候会出现链码安装失败的问题, 提示链码的指纹(哈希)不匹配,我们可以通过以下方法解决
1. 通过客户端在第1个peer节点中安装好链码之后, 将链码打包
peer chaincode package -n testcc -p github.com/chaincode -v 1.0 mycc.1.0.out
-n: 链码的名字
-p: 链码的路径
-v: 链码的版本号
-mycc.1.0.out: 打包之后生成的文件
2. 将打包之后的链码从容器中拷贝出来
$ docker cp cli:/xxxx/mycc.1.0.out ./
3. 将得到的打包之后的链码文件拷贝到其他的peer节点上
4. 通过客户端在其他peer节点上安装链码
peer chaincode install mycc.1.0.out