Hyperledger Fabric 1.0 从零开始(九)——Fabric多节点集群生产启动

7Fabric多节点集群生产启动

7.1、多节点服务器配置

在生产环境上,我们沿用4.1、配置说明中的服务器各节点配置方案。

我们申请了五台生产服务器,其中四台服务器运行peer节点,另外一台服务器运行orderer节点,为其它四个节点提供排序服务。

虚拟机具体参数如下表所示:

名称

ip

节点标识

节点Hostname

Organization(组织机构)

Server1

10.130.116.8

orderer

orderer.example.com

Orderer

Server2

10.130.116.9

org0

peer0.org.example.com

org

Server3

10.130.116.10

orgs0

peer0.orgs.example.com

orgS

Server4

10.130.116.25

orgpay0

peer0.orgpay.example.com

orgPAY

Server5

10.130.116.27

orgt0

peer0.orgt.example.com

orgT

7.2、启动orderer排序服务节点

第六章中提到的所有配置方案可以在任意一台符合条件的服务器上进行生成配置,配置完成后,我们首先要启动属于本组织(org)的排序节点服务,启动之前需要创建一个docker-compose-orderer.yaml文件,该文件可参考fabric-samples-release/first-network/docker-compose-cli.yaml进行个性化编写。

具体的编写步骤和内容介绍可参考4.6、设置order节点的docker-compose文件,根据第六章所配置的联盟环境及本组织名称等内容及4.5节中的介绍,我们最终得到属于本组织的专属docker-compose-orderer.yaml文件,具体内容如下:

version: '2'

services:

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

这里有一个协助启动文件,是位于base目录下的docker-compose-base.yaml文件,这个文件的参数配置如下:

docker-compose-base.yaml

version: '2'

services:

  orderer.example.com:
    container_name: orderer.example.com
    image: hyperledger/fabric-orderer
    environment:
      - ORDERER_GENERAL_LOGLEVEL=debug
      - 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]
    working_dir: /opt/gopath/src/org/peer
    command: orderer
    volumes:
    - ../bin/channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
   - ../bin/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
    - ../bin/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
    ports:
      - 7050:7050

文件及目录编写完成后上传至服务器指定位置,本组织的目录为org,如下视图:

随后在org目录下执行如下命令:

docker-compose -f docker-compose-orderer.yaml up -d

完成后执行如下命令:

docker ps

至此我们在10.130.116.8这台服务器上启动了orderer排序服务。

 

7.3、启动orgMSP peer节点

peer节点的启动方式可参考4.4、设置peer0.org1.excmple.com节点的docker-compose文件,这里因为在6.6、生成channel下节点集合认证文件已经生成了orgMSP的认证文件,故此我们不必再去创建和生成,为了不必要的混乱,建议各组织生成统一认证的服务器固定。

我们需要将orderer排序服务器上的org/bin目录下的文件拷贝至org组织所在节点服务器org0,即10.130.116.9服务器的/opt/gopath/src目录下。其中crypto-config.yaml和configtx.yaml文件无需拷贝,因为具体的证书等生成都交由orderer排序服务器去执行。

这里的启动步骤与上一节的内容类似,在启动orgMSP之前需要创建一个docker-compose-org.yaml文件,该文件可参考fabric-samples-release/first-network/docker-compose-cli.yaml进行个性化编写。

具体的编写步骤和内容介绍可参考4.4、设置peer0.org1.excmple.com节点的docker-compose文件,根据第六章所配置的联盟环境及本组织名称等内容及4.4节中的介绍,我们最终得到属于本组织的专属docker-compose-org.yaml文件,具体内容如下:

version: '2'

services:

  peer0.org.example.com:
    container_name: peer0.org.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org.example.com
    extra_hosts:
     - "orderer.example.com:10.130.116.8"

  cli:
    container_name: cli
    image: hyperledger/fabric-tools
    tty: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org.example.com:7051
      - CORE_PEER_LOCALMSPID=orgMSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/org/peer/crypto/peerOrganizations/org.example.com/peers/peer0.org.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/org/peer/crypto/peerOrganizations/org.example.com/peers/peer0.org.example.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/org/peer/crypto/peerOrganizations/org.example.com/peers/peer0.org.example.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/org/peer/crypto/peerOrganizations/org.example.com/users/Admin@org.example.com/msp
    working_dir: /opt/gopath/src/org/peer
    volumes:
        - /var/run/:/host/var/run/
        - ./chaincode/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
        - ./bin/crypto-config:/opt/gopath/src/org/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./bin/channel-artifacts:/opt/gopath/src/org/peer/channel-artifacts
    depends_on:
      - peer0.org.example.com
    extra_hosts:
     - "orderer.example.com:10.130.116.8"
     - "peer0.org.example.com:10.130.116.9"

这里orderer不同,有两个协助启动文件,分别是位于base目录下的docker-compose-base.yaml和peer-base.yaml文件,这两个文件的参数配置分别如下:

docker-compose-base.yaml:

version: '2'

services:

  peer0.org.example.com:
    container_name: peer0.org.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.org.example.com
      - CORE_PEER_ADDRESS=peer0.org.example.com:7051
      - CORE_PEER_CHAINCODELISTENADDRESS=peer0.org.example.com:7052
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org.example.com:7051
      - CORE_PEER_LOCALMSPID=orgMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../bin/crypto-config/peerOrganizations/org.example.com/peers/peer0.org.example.com/msp:/etc/hyperledger/fabric/msp
        - ../bin/crypto-config/peerOrganizations/org.example.com/peers/peer0.org.example.com/tls:/etc/hyperledger/fabric/tls
    ports:
      - 7051:7051
      - 7052:7052
      - 7053:7053

peer-base.yaml:

version: '2'
services:
  peer-base:
    image: hyperledger/fabric-peer
    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=e2ecli_default
      #- CORE_LOGGING_LEVEL=ERROR
      - CORE_LOGGING_LEVEL=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/org/peer
    command: peer node start

随后在org目录下执行如下命令:

docker-compose -f docker-compose-org.yaml up -d

完成后执行如下命令:

docker ps

即可查看当前启动镜像,如下视图:

继续执行如下命令来查看我们挂载的peer工作路径是否正确,是否为/opt/gopath/src/org/peer:

docker exec -it cli bash

该命令执行后会有如下结果视图:

出现上述目录,则表示我们的挂载没有问题。

因为后续的工作都需要在cli容器中执行,而peer节点的操作就挂载在cli容器中的指定目录。

 

7.4、创建并加入channel

操作org所在组织的所在节点,即org组织所在节点服务器org0,即10.130.116.9服务器。

7.3中最后所述,当我们进入peer挂载目录后,即可对当前peer进行相关操作。

6.5、生成channel源文件的过程中,我们定义了当前channel的名称为examplechannel。参照/scripts/ script.sh文件,我们可以看到创建channel的相关命令,也可以参照官网给定的方案。

具体需要执行命令的样本如下:

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA

上述命令中需要根据生产中实际的需求进行替换,将orderer.example.com组织替换成我们之前定义的orderer.example.com;将$CHANNEL_NAME替换成examplechannel;$CORE_PEER_TLS_ENABLED这个全局变量我们在docker-compose-org.yaml已经定义过了,可以直接引用;$ORDERER_CA是orderer排序服务器TLS证书所在位置,该位置需要通过peer的挂载路径来定位,因此将$ORDERER_CA替换成/opt/gopath/src/org/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem。

在前一步$ORDERER_CA定位的过程中,我们通过ftp等在peer下是找不到指定目录及文件的,主要是通过挂载的方式将./bin/crypto-config和/opt/gopath/src/org/peer/crypto/路径相关联,参考7.3、启动orgMSP peer节点对docker-compose-org.yaml文件的配置详情。

综上所述,我们最终在peer挂载路径下需要执行的命令如下:

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

执行该命令会返回了一个genesis block- <channel-ID.block> -我们可以通过这个id进入到channel。它包含channel.tx中指定的配置信息,创建成功后有如下视图:

接下来,我们要将本组织的当前节点,即org组织所在节点服务器org0,即10.130.116.9服务器节点,加入到channel中,这其中会用到channel-ID.block,而channel-ID.block是上一步所生成的,即example.block。

参照/scripts/ script.sh文件,我们可以看到加入channel的相关命令,也可以参照官网给定的方案。

具体需要执行命令的样本如下:

peer channel join -b $CHANNEL_NAME.block

$CHANNEL_NAME修改成example.block,即执行如下命令:

peer channel join -b example.block

加入成功后,会有如下视图:

 7.4.1注意事项-必读

通过peer来创建并加入一个channel的时候,如果之前已经创建过同样的channel,导致系统已经返回过一个[channel-ID].block,此时再执行创建的时候会提示该channel已经创建过,若执行加入又会提示该channel的[channel-ID].block 文件不存在,无法加入。

解决上述问题的方案目前笔者已知的有且仅有一个,即在创建channel的时候,系统会返回一个[channel-ID].block文件,该文件就存储在cli容器入口目录里面,当我们创建一个channel成功之后,再次执行如下命令:

docker exec -it cli bash
ls

该命令执行后会有如下视图:

可以看到我们这里有一个example.block文件,该文件的命名方式以各自联盟channel需求为主,这个文件会跟随cli进程的生命周期,即当cli进程被销毁的时候,该进程下的所有目录、文件都会被销毁,比如执行了如下两种命令来销毁进程:

docker-compose -f docker-compose.yaml down -d

docker stop [CONTAINER ID]

因此,当我们确认channel创建无误后,需要对该[channel-ID].block文件进行备份,而docker容器内的文件拷贝到实际挂载硬盘中需要docker cp命令的支持,这里给一个简单的demo,如下命令格式:

docker cp <containerId>:/file/path/within/container /host/path/target

这里实际操作的命令是:

docker cp 56d4d547f93f:/opt/gopath/src/github.com/hyperledger/fabric/peer/example.block /opt/gopath/src/github.com/hyperledger/fabric/example/org/channelbak/

我们在org目录下新建一个channelbak目录,专门用来备份各种[channel-ID].block文件。

有了这个备份之后,我们可以停止或删除之前创建的cli及peer等进程,随后当我们创建新的cli及peer容器后,将备份的[channel-ID].block文件拷贝回容器中即可,执行如下命令格式:

docker cp /host/path/target <containerId>:/file/path/within/container

这里实际操作的命令是:

docker cp /opt/gopath/src/github.com/hyperledger/fabric/example/org/channelbak/example.block c912fb6c0a0b:/opt/gopath/src/github.com/hyperledger/fabric/peer/

如果之前没有备份[channel-ID].block文件,那么该服务器可能已经被污染,执行任何删除或销毁容器的方法都无法再次成功创建或加入之前已经创建过的channel中,只能暴力解决该问题,即删除peer、cli等相关镜像,并重新load进来,再执行后续初始化yaml等方法来一步一步实现,但该方案笔者并未尝试过,只是猜测,因为channel的创建依赖cli容器。

补充说明一点,根据peer创建channel的命令来看,创建channel需要的文件都是由configtxgen生成的channel.tx及orderer组织下的pem文件,这两个文件是固定的,且在各不同组织的节点都是相同的,只要其中一个组织生成了[channel-ID].block文件,并将其拷贝给其它组织,其它组织的peer节点无需再次生成,只需要藉此文件执行加入channel的命令就可以了。

即,如果想加入该channel的组织的peer节点服务器因为一些错误操作导致丢失[channel-ID].block文件,可以通过从其它组织的peer节点中拷贝的方式来继续完成加入channel流程。

 

posted @ 2017-11-02 14:13  Aberic  阅读(...)  评论(...编辑  收藏