天天看點

基于Raft排序的Fabric多機叢集部署教程

Raft是Hyperledger Fabric 1.4.1中新增的排序服務子產品,這個教程将介紹如何部署一個基于Raft排序服務的多機Fabric網絡。

相關教程推薦:

1、用Raft排序服務啟動byfn示例

BYFN是學習Hyperledger Fabric的一個很好的例子:它包含了Fabric網絡的所有元素,并且在byfn.sh中完整表現出來。當我們不加任何參數運作這個腳本時,它将啟動一個包含2個機構、4個peer和1個orderer(使用solo排序)的Fabric網絡。byfn.sh的參數

-o

用來指定排序服務的類型:

./byfn.sh up -o <kafka | etcdraft>           

最新的BYFN網絡設計中包含了5個orderer的密碼學資料。如果使用Solo或Kafka排序服務,将值運作第一個Orderer(參見docker-compose-cli.yaml中的定義)。

當我們指定raft作為排序服務時的一個差別之處在于,使用configtxgen生成創世區塊我們需要指定configtx.yaml中的SampleMultiNodeEtcdRaft配置端。其他的操作都保持不變。

最後,我們還需要啟動其他4個orderer,這些内容在docker-compose-etcdraft2.yaml中定義。

下面時基于raft排序的BYFN網絡啟動後的情況,你可以看到有5個orderer在運作:

基于Raft排序的Fabric多機叢集部署教程

下面是基于Raft排序服務的BYFN網絡的拓撲示意圖:

基于Raft排序的Fabric多機叢集部署教程

在下面的内容中,我們将不再使用BYFN腳本,而是從零開始來學習如何建構多主機的Raft排序的Fabric網絡。

2、Hyperledger Fabric多機部署的不同方案

由于Hyperledger Fabric的元件以容器形式部署,當這些容器都在本機時會很順利的工作。但是當這些容器需要運作在不同的主機上時,我們需要找出讓它們彼此通信的辦法。

雖然Hyperledger Fabric官方沒有給出正式的推薦方案,目前大緻有三種方案:

使用靜态IP:通過指定容器運作的主機IP,容器之間就可以彼此通信。可以在docker-compose檔案中使用extra_hosts方法來指定主機IP,當容器運作後,就可以在/etc/hosts檔案中看到這些項。這一方案容易了解,我們也不需要依賴于外部元件,缺點在于所有的東西都是靜态配置的,不利于需要動态修改配置的應用場景。

使用docker swarm:Docker Swarm是Docker環境中的原生容器編排服務。簡而言之,Docker Swarm為跨主機的容器提供了一個疊加網絡層,使容器彼此之間能夠通信,就像在一台主機上一樣。這一方案的好處在于原始的配置隻需要簡單修改就可以使用,也不需要在配置中寫死像IP位址這樣的靜态資訊。缺點在于需要依賴外部元件Docker Swarm。在這個教程中我們将使用這一方案。

使用Kubernetes:k8s使目前最流行的容器編排工具,其機制類似于Docker Swarm。我們已經注意到有一些教程嘗試利用k8s來進行fabric的多機部署,但是使用k8s的難度要明顯高于前兩種方案。

3、Fabrc Raft多機示範環境搭建

我們需要将容器分發到4個主機,本教程使用AWS上的4個EC2執行個體,但是并不使用AWS提供的特别功能,僅僅是用它來運作Ubuntu以及必要的軟體,采用公共IP進行通信。當然你可以可以選擇其他的雲服務提供商。

基于Raft排序的Fabric多機叢集部署教程

在Fabric網絡啟動運作後,我們将使用Fabcar鍊碼進行測試。總體流程如下:

  • 啟動AWS EC2執行個體,安裝必要的鏡像和工具。
  • 建構一個疊加網絡,将4個主機都加入該網絡
  • 在主機1上準備所有資料,包括密碼學資料、通道配置交易、每個節點的docker-compose

    檔案等。然後拷貝到其他主機。

  • 使用docker-compose啟動所有元件
  • 建立通道mychannel并将所有peer加入該通道
  • 安裝并執行個體化Fabcar鍊碼
  • 調用查詢鍊碼方法

4、Fabric Raft多機示範

4.1 啟動主機

本教程使用AWS EC2 t2.small執行個體,使用fabric 1.4.4。注意在示範中我們使用了簡化的全開放安全組,在生産環境中你應當根據自己的需求來決定開放哪些端口:

基于Raft排序的Fabric多機叢集部署教程

4.2 使用Docker Swarm建構疊加網絡

現在我們可以打開4個終端,分别對應每個主機:

ssh -i <key> ubuntu@<public IP>           

從Host 1執行如下指令:

docker swarm init --advertise-addr <host-1 ip address>
docker swarm join-token manager           

運作結果如下:

基于Raft排序的Fabric多機叢集部署教程

使用最後的輸出,将其他節點以管理者身份加入swarm。

從host 2/3/4執行如下指令:

<output from join-token manager> --advertise-addr <host n ip>           
基于Raft排序的Fabric多機叢集部署教程

最後,我們添加一個疊加網絡,該網絡将用于下面的示範,這一步的操作隻需要在一個節點上執行。如果Docker Swarm正常工作,所有的節點都會加入這個疊加網絡。

從host 1建立疊加網絡first-network:

docker network create --attachable --driver overlay first-networkdocker network ls           
基于Raft排序的Fabric多機叢集部署教程

在其他主機上,我們可以看到這個網絡:

基于Raft排序的Fabric多機叢集部署教程

現在已經建構好了疊加網絡,這些資訊将在稍後用于docker-compose檔案。

4.3 在host 1上準備資料

一個關鍵的環節時確定所有的Farbic成員使用相同的密碼學資料。我們将使用host 1來建立這些密碼學資料,然後拷貝到其他主機。

理論上,我們隻需要確定個體身份(證書和簽名私鑰)遵循所要求的規範。一個機構的證書應當由同一個CA簽發 —— 例如org1的證書應當由ca.org1簽發。出于簡化目的,在本教程中,我們在host 1上建立所有的密碼學資料,然後将整個目錄拷貝到其他主機。

首先進入fabric-samples目錄,然後建立一個raft-4node-swarm目錄。

在host 1上執行如下指令:

cd fabric-samples
mkdir raft-4node-swarm
cd raft-4node-swarm           

直接從first-network拷貝crypto-config.yaml和configtx.yaml檔案:

cp ../first-network/crypto-config.yaml .
cp ../first-network/configtx.yaml .           

然後生成必要的密碼學資料:

../bin/cryptogen generate --config=./crypto-config.yaml
export FABRIC_CFG_PATH=$PWD
mkdir channel-artifacts
../bin/configtxgen -profile SampleMultiNodeEtcdRaft -outputBlock ./channel-artifacts/genesis.block
../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP           

現在我們為所有主機準備docker-compose檔案,主要基于BYFN中的檔案,需要建立6個docker-compose檔案以及一個env檔案:

  • base/peer-base.yaml
  • base/docker-compose-peer.yaml
  • host1.yaml
  • host2.yaml
  • host3.yaml
  • host4.yaml
  • .env

4.3.1 base/peer-base.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

services:
  peer-base:
    image: hyperledger/fabric-peer:$IMAGE_TAG
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      # the following setting starts chaincode containers on the same
      # bridge network as the peers
      # https://docs.docker.com/compose/networking/
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=first-network
      - FABRIC_LOGGING_SPEC=INFO
      #- FABRIC_LOGGING_SPEC=DEBUG
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_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
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start

  orderer-base:
    image: hyperledger/fabric-orderer:$IMAGE_TAG
    environment:
      - FABRIC_LOGGING_SPEC=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - 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]
      - ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
      - ORDERER_KAFKA_VERBOSE=true
      - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: orderer           

4.3.2 base/docker-compose-base.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

services:

  orderer.example.com:
    container_name: orderer.example.com
    extends:
      file: peer-base.yaml
      service: orderer-base
    volumes:
        - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
        - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
        - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
        - orderer.example.com:/var/hyperledger/production/orderer
    ports:
      - 7050:7050

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.org1.example.com
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
        - peer0.org1.example.com:/var/hyperledger/production
    ports:
      - 7051:7051

  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.org1.example.com
      - CORE_PEER_ADDRESS=peer1.org1.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
        - peer1.org1.example.com:/var/hyperledger/production
    ports:
      - 7051:7051

  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.org2.example.com
      - CORE_PEER_ADDRESS=peer0.org2.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
        - peer0.org2.example.com:/var/hyperledger/production
    ports:
      - 7051:7051

  peer1.org2.example.com:
    container_name: peer1.org2.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.org2.example.com
      - CORE_PEER_ADDRESS=peer1.org2.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls
        - peer1.org2.example.com:/var/hyperledger/production
    ports:
      - 7051:7051           

4.3.3 host1.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
  orderer.example.com:
  orderer5.example.com:
  peer0.org1.example.com:

networks:
  byfn:
    external:
      name: first-network

services:

  orderer.example.com:
    extends:
      file:   base/docker-compose-base.yaml
      service: orderer.example.com
    container_name: orderer.example.com
    networks:
      - byfn

  orderer5.example.com:
    extends:
      file: base/peer-base.yaml
      service: orderer-base
    container_name: orderer5.example.com
    networks:
    - byfn
    volumes:
        - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/msp:/var/hyperledger/orderer/msp
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/:/var/hyperledger/orderer/tls
        - orderer5.example.com:/var/hyperledger/production/orderer
    ports:
    - 8050:7050

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org1.example.com
    networks:
      - byfn

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:$IMAGE_TAG
    tty: true
    stdin_open: true
    environment:
      - SYS_CHANNEL=$SYS_CHANNEL
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      #- FABRIC_LOGGING_SPEC=DEBUG
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.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/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.example.com
      - peer0.org1.example.com
    networks:
      - byfn           

4.3.4 host2.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
  orderer2.example.com:
  peer1.org1.example.com:

networks:
  byfn:
    external:
      name: first-network

services:

  orderer2.example.com:
    extends:
      file: base/peer-base.yaml
      service: orderer-base
    container_name: orderer2.example.com
    networks:
    - byfn
    volumes:
        - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/msp:/var/hyperledger/orderer/msp
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/:/var/hyperledger/orderer/tls
        - orderer2.example.com:/var/hyperledger/production/orderer
    ports:
    - 7050:7050

  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org1.example.com
    networks:
      - byfn           

4.3.5 host3.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
  orderer3.example.com:  
  peer0.org2.example.com:

networks:
  byfn:
    external:
      name: first-network

services:

  orderer3.example.com:
    extends:
      file: base/peer-base.yaml
      service: orderer-base
    container_name: orderer3.example.com
    networks:
    - byfn
    volumes:
        - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/msp:/var/hyperledger/orderer/msp
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/:/var/hyperledger/orderer/tls
        - orderer3.example.com:/var/hyperledger/production/orderer
    ports:
    - 7050:7050

  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org2.example.com
    networks:
      - byfn           

4.3.6 host4.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
  orderer4.example.com:
  peer1.org2.example.com:

networks:
  byfn:
    external:
      name: first-network

services:

  orderer4.example.com:
    extends:
      file: base/peer-base.yaml
      service: orderer-base
    container_name: orderer4.example.com
    networks:
    - byfn
    volumes:
        - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/msp:/var/hyperledger/orderer/msp
        - ./crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/:/var/hyperledger/orderer/tls
        - orderer4.example.com:/var/hyperledger/production/orderer
    ports:
    - 7050:7050

  peer1.org2.example.com:
    container_name: peer1.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org2.example.com
    networks:
      - byfn           

4.3.7 .env

COMPOSE_PROJECT_NAME=net
IMAGE_TAG=latest
SYS_CHANNEL=byfn-sys-channel           

下面是目錄中的内容:

基于Raft排序的Fabric多機叢集部署教程

下面是針對BYFN中的檔案所作的修改:

  • base/peer-base.yaml

    中,CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE修改為

    我們之前建立的疊加網絡first-network

  • base/docker-compose-base.yaml

    中,由于所有的peers都在不同的主機上,我們

    将端口映射改回7051:7051。在每個peer的環境變量中也進行了相應的修改。

  • 在所有的

    hostn.yaml

    檔案中,我們添加疊加網絡first-network

現在我們在host 1上準備好了所有資料,将該目錄拷貝到其他主機。由于不能跨EC2執行個體拷貝檔案,我們使用本地機器進行橋接操作:

# on Host 1
cd ..
tar cf raft-4node-swarm.tar raft-4node-swarm/# on my localhost
scp -i <key> ubuntu@<Host 1 IP>:/home/ubuntu/fabric-samples/raft-4node-swarm.tar .
scp -i <key> raft-4node-swarm.tar ubuntu@<Host 2, 3 and 4 IP>:/home/ubuntu/fabric-samples/# on Host 2, 3 and 4
cd fabric-samples
tar xf raft-4node-swarm
cd raft-4node-swarm           

現在所有的節點都有了同樣的密碼學資料和docker-compose檔案,我們可以啟動容器了。

4.4 分别啟動各主機上的容器

我們使用docker-compose啟動全部主機:

# on Host 1, 2, 3 and 4, bring up corresponding yaml file
docker-compose -f hostn.yaml up -d           
基于Raft排序的Fabric多機叢集部署教程
基于Raft排序的Fabric多機叢集部署教程

4.5 建立通道并加入peer

由于我們僅在host 1上由指令行CLI,是以從host 1的終端執行所有的指令。

為mychannel通道建立創世區塊:

docker exec cli peer channel create -o orderer.example.com:7050 -c mychannel \
       -f ./channel-artifacts/channel.tx --tls \
       --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem           

将peer0.org1加入mychannel:

docker exec cli peer channel join -b mychannel.block           

将peer1.org1加入mychannel:

docker exec -e CORE_PEER_ADDRESS=peer1.org1.example.com:7051 \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt \
       cli peer channel join -b mychannel.block           

将peer0.org2加入mychannel:

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer0.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
       cli peer channel join -b mychannel.block           

将peer1.org2 加入mychannel:

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer1.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt \
       cli peer channel join -b mychannel.block           

4.6 安裝并執行個體化Fabcar鍊碼

從host 1的終端将Fabcar鍊碼安裝到所有peer節點:

# to peer0.org1
docker exec cli peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/fabcar/go/

# to peer1.org1
docker exec -e CORE_PEER_ADDRESS=peer1.org1.example.com:7051 \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt \
       cli peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/fabcar/go/

# to peer0.org2
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer0.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
       cli peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/fabcar/go/
       
# to peer1.org2
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer1.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt \
       cli peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/fabcar/go/           

在通道mychannle執行個體化Fabcar鍊碼:

docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
       --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
       -C mychannel -n mycc -v 1.0 -c '{"Args":[]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"           

4.7 鍊碼調用與查詢

首先調用

initLedger

方法将10個車輛記錄載入賬本。

在peer0.org1上執行:

docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls true \
       --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
       -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 \
       --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
       --peerAddresses peer0.org2.example.com:7051 \
       --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
       -c '{"Args":["initLedger"]}'           

現在可以從4個不同的peer節點查詢車輛記錄:

# from peer0.org1
docker exec cli peer chaincode query -n mycc -C mychannel -c '{"Args":["queryCar","CAR0"]}'

# from peer1.org1
docker exec -e CORE_PEER_ADDRESS=peer1.org1.example.com:7051 \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt \
       cli peer chaincode query -n mycc -C mychannel -c '{"Args":["queryCar","CAR0"]}'

# from peer0.org2
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer0.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
       cli peer chaincode query -n mycc -C mychannel -c '{"Args":["queryCar","CAR0"]}'

# from peer1.org2
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer1.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt \
       cli peer chaincode query -n mycc -C mychannel -c '{"Args":["queryCar","CAR0"]}'           
基于Raft排序的Fabric多機叢集部署教程

現在我們使用orderer3.example.com來調用 changeCarOwner,并在執行

後進行查詢:

docker exec cli peer chaincode invoke -o orderer3.example.com:7050 --tls true \
       --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
       -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 \
       --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
       --peerAddresses peer0.org2.example.com:7051 \
       --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
       -c '{"Args":["changeCarOwner","CAR0","KC"]}'
       
# from peer0.org1
docker exec cli peer chaincode query -n mycc -C mychannel -c '{"Args":["queryCar","CAR0"]}'

# from peer1.org2
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp \
       -e CORE_PEER_ADDRESS=peer1.org2.example.com:7051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
       -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt \
       cli peer chaincode query -n mycc -C mychannel -c '{"Args":["queryCar","CAR0"]}'           
基于Raft排序的Fabric多機叢集部署教程

你可以使用其他的orderer進行鍊碼調用。由于這些排序節點構成了raft叢集,你

應該得到同樣的結果,這表示排序節點叢集工作正常。

4.8 清理環境

要清理運作環境,使用docker-compose将容器停掉并移除即可:

# each host
docker-compose -f noden.yaml down -v           

5、總結

在本教程中,我們基于BYFN示例進行修改,建構了一個基于Raft排序叢集的

Hyperledger Fabric網絡,使用Docker Swarm來實作多主機容器的通信。

原文連結:

Hyperledger Fabric Raft排序多機部署 - 彙智網