Fabric v2.0 first-network测试网络运行与剖析

文章目录

  • 1. byfn测试网络的启动
    • 1.1 准备二进制可执行文件
    • 1.2 构建docker镜像
    • 1.3 启动测试网络
  • 2. networkUp 脚本分析
  • 3. 创建初始文件与配置分析
    • 3.1 generateCerts 生成证书
    • 3.2 generateChannelArtifacts 生成创世区块
    • 3.3 generateChannelArtifacts 生成channel配置
  • 4. 节点启动分析
    • 4.1 第一个排序节点的启动
    • 4.2 peer节点的启动
    • 4.3 剩余4个排序节点的启动

1. byfn测试网络的启动

1.1 准备二进制可执行文件

  1. 在fabric目录中执行make native命令可编译出二进制可执行文件,然后将fabric/build/bin目录拷贝到fabric-samples目录中;
  2. 但是最新的fabric版本在可能会造成后面运行./byfn generate报错的问题。因此可考虑直接从github上下载稳定的二进制可执行文件,运行命令wget https://github.com/hyperledger/fabric/releases/download/v2.0.1/hyperledger-fabric-linux-amd64-2.0.1.tar.gz,解压后同样将bin目录拷贝到fabric-samples目录中。

两种方法均可得到二进制可执行文件,如下图所示:
Fabric v2.0 first-network测试网络运行与剖析_第1张图片

1.2 构建docker镜像

在fabric目录中执行make docker命令,可得到所需的相关镜像。

从Fabric2.0开始docker镜像将基于Alpine Linux,这是一种面向安全的轻量级Linux发行版,只占5MB左右的空间,且更加安全可靠。另外Alpine Linux还提供了自己的包管理工具apk,我们在构建docker镜像过程中存在“apk add”的动作,可能会有从“dl-cdn.alpinelinux.org/alpine/v3.10”下载包失败的问题,这是由于在中国大陆无法连接官方的更新源,因此可考虑在所有Dockerfile中修改为使用阿里云的更新源:

FROM alpine:${ALPINE_VER} as base
RUN echo "#aliyun" > /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.10/main/" >> /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.10/community/" >> /etc/apk/repositories

最终构建成功,将会得到这些镜像:
Fabric v2.0 first-network测试网络运行与剖析_第2张图片

1.3 启动测试网络

在fabric-samples/first-network目录中,执行./byfn.sh up命令启动测试网络,默认会生成crypto-config和channel-artifacts目录中的文件。最后控制台输出如下内容,表示运行成功。
Fabric v2.0 first-network测试网络运行与剖析_第3张图片

2. networkUp 脚本分析

执行“./byfn.sh up”命令调用的就是networkUp,脚本逻辑步骤如下:

  1. 如果crypto-config目录不存在,networkUp会先执行generateCerts生成证书与密钥,以及generateChannelArtifacts生成创世区块、用户channel配置交易、 anchor peer节点更新交易;
  2. compose文件包括docker-compose-cli.yaml、docker-compose-etcdraft2.yaml;如果指定了CA,还将包括docker-compose-ca.yaml;如果指定了couchdb,还将包括docker-compose-couch.yaml;使用docker-compose构建和启动容器;
  3. 下载abstore链码的依赖包;
  4. 执行容器cli中的script.sh脚本,参数包括:
    channel名称(CHANNEL_NAME):mychannel
    命令延迟时间(DELAY):3秒
    链码语言(CC_SRC_LANGUAGE):go
    cli等待其他容器的超时(TIMEOUT):10秒
# Generate the needed certificates, the genesis block and start the network.
function networkUp() {
  checkPrereqs
  # generate artifacts if they don't exist
  if [ ! -d "crypto-config" ]; then
    generateCerts
    generateChannelArtifacts
  fi
  COMPOSE_FILES="-f ${COMPOSE_FILE} -f ${COMPOSE_FILE_RAFT2}"
  if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
    COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
    export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk)
    export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
  fi
  if [ "${IF_COUCHDB}" == "couchdb" ]; then
    COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
  fi
  IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1
  docker ps -a
  if [ $? -ne 0 ]; then
    echo "ERROR !!!! Unable to start network"
    exit 1
  fi

  echo "Sleeping 15s to allow Raft cluster to complete booting"
  sleep 15

  if [ "${NO_CHAINCODE}" != "true" ]; then
    echo Vendoring Go dependencies ...
    pushd ../chaincode/abstore/go
    GO111MODULE=on go mod vendor
    popd
    echo Finished vendoring Go dependencies
  fi

  # now run the end to end script
  docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $CC_SRC_LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE
  if [ $? -ne 0 ]; then
    echo "ERROR !!!! Test failed"
    exit 1
  fi
}

下面将对networkUp中的一些具体细节进行剖析。

3. 创建初始文件与配置分析

3.1 generateCerts 生成证书

generateCerts使用cryptogen工具生成组织证书,主要包括两个步骤:

  1. cryptogen generate --config=./crypto-config.yaml将根据crypto-config.yaml中的配置生成证书
  2. ./ccp-generate.sh生成调用SDK的相关配置文件。
# Generates Org certs using cryptogen tool
function generateCerts() {
  which cryptogen
  if [ "$?" -ne 0 ]; then
    echo "cryptogen tool not found. exiting"
    exit 1
  fi
  echo
  echo "##########################################################"
  echo "##### Generate certificates using cryptogen tool #########"
  echo "##########################################################"

  if [ -d "crypto-config" ]; then
    rm -Rf crypto-config
  fi
  set -x
  cryptogen generate --config=./crypto-config.yaml
  res=$?
  set +x
  if [ $res -ne 0 ]; then
    echo "Failed to generate certificates..."
    exit 1
  fi
  echo
  echo "Generate CCP files for Org1 and Org2"
  ./ccp-generate.sh
}
  • crypto-config.yaml中的配置分为OrdererOrgs和PeerOrgs两部分。
  • OrdererOrgs中定义管理orderer节点的组织,里面配置了5个排序节点,采用Specs配置模式,全名为:{{.Hostname}}.{{.Domain}},比如orderer.example.com。
OrdererOrgs:
  - Name: Orderer
    Domain: example.com
    Specs:
      - Hostname: orderer
      - Hostname: orderer2
      - Hostname: orderer3
      - Hostname: orderer4
      - Hostname: orderer5
  • 也可重写限定域名CommonName,默认值为Hostname,例如可以这样配置:
OrdererOrgs:
  - Name: Orderer
    Domain: example.com
    Specs:
      - Hostname: orderer
        CommonName: myorderer.example.com

  • PeerOrgs则定义了管理peer节点的组织,配置了Org1和Org2两个组织,每个组织2套证书,除Admin之外的普通User数量为1,EnableNodeOUs为true,允许节点out of service,用于区分clients, admins, peers,在msp目录会生成config.yaml。
    采用了Template模板定义节点:
    • Count:节点总数
    • Start:节点下标起始值,默认为0
    • Hostname 全限定域名,默认命名格式为{{.Prefix}}{{.Index}}
    • Prefix:默认为peer
    • Index:取Start值,无配置从0开始自增
PeerOrgs:
  - Name: Org1
    Domain: org1.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
     Users:
      Count: 1

  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1

3.2 generateChannelArtifacts 生成创世区块

generateChannelArtifacts使用工具configtxgen,生成创世区块的脚本为:configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block,SampleMultiNodeEtcdRaft 用于生成创始区块,支持etcdraft模式的共识。

raft共识的创世区块配置如下,里面包含所有的raft节点配置:

    SampleMultiNodeEtcdRaft:
        <<: *ChannelDefaults
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults # 引用OrdererDefaults详细配置
            OrdererType: etcdraft # 排序类型为etcdraft
            EtcdRaft:
                Consenters: # 系统channel中raft节点配置
                - Host: orderer.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
                  
                  # 此处省略了其他orderer节点
            Addresses:
                - orderer.example.com:7050
                - orderer2.example.com:8050
                - orderer3.example.com:9050
                - orderer4.example.com:10050
                - orderer5.example.com:11050

            Organizations:
            - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Application:
            <<: *ApplicationDefaults
            Organizations:
            - <<: *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                - *Org1
                - *Org2

orderer详细配置及配置项的说明:

Orderer: &OrdererDefaults
    OrdererType: etcdraft
    BatchTimeout: 2s          # 打包区块的超时时间
    BatchSize:                # 控制打包到区块的交易量
        MaxMessageCount: 10       # 打包到一个区块中的最大消息数量
        AbsoluteMaxBytes: 99 MB   # 打包到一个区块中允许的绝对最大字节数
        PreferredMaxBytes: 512 KB # 打包到一个区块中的首选最大字节数
    Organizations: # 参与orderer的组织列表
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        BlockValidation: # 指定orderer的区块中必须包含哪些orderer组织的签名,以便peer节点进行验证
            Type: ImplicitMeta
            Rule: "ANY Writers"

3.3 generateChannelArtifacts 生成channel配置

生成用户channe配置交易的脚本为:configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME,TwoOrgsChannel 用于生成两个组织的channel。

用户channel的配置及配置项的说明:

    TwoOrgsChannel:
        Consortium: SampleConsortium # 联盟名称
        <<: *ChannelDefaults # 引用ChannelDefaults详细配置
        Application:
            <<: *ApplicationDefaults # 引用ApplicationDefaults详细配置
            Organizations: # channel组织定义
                - *Org1
                - *Org2
            Capabilities:
                <<: *ApplicationCapabilities

用户channel的详细配置主要是针对channel的权限策略:

Channel: &ChannelDefaults
    Policies: # channel权限策略   
        # Who may invoke the 'Deliver' API
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        # Who may invoke the 'Broadcast' API
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        # By default, who may modify elements at this config level
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
    Capabilities:
        <<: *ChannelCapabilities

4. 节点启动分析

正如第2章节所分析的,节点容器启动脚本中的yaml文件默认是两个:docker-compose-cli.yaml、docker-compose-etcdraft2.yaml。

docker-compose-cli.yaml中将会启动6个容器,脚本中使用命令docker-compose -f docker-compose-cli.yaml up -d 2>&1启动这些节点,包括:

  • 第一个排序节点:orderer.example.com
  • 两个组织的4个peer节点:
    • peer0.org1.example.com
    • peer1.org1.example.com
    • peer0.org2.example.com
    • peer1.org2.example.com
  • fabric客户端:cli

docker-compose-etcdraft2.yaml中将会启动剩余的4个orderer容器,脚本中使用命令docker-compose -f docker-compose-etcdraft2.yaml up -d 2>&1启动这些节点,包括:

  • orderer2.example.com
  • orderer3.example.com
  • orderer4.example.com
  • orderer5.example.com

4.1 第一个排序节点的启动

第一个排序节点的yaml配置如下:

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

其中引入了外部的yaml文件base/docker-compose-base.yaml;引入的orderer.example.com的相关配置如下:

  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

再次引入了外部的peer-base.yaml文件,还定义了挂载目录、暴露的服务端口;peer-base.yaml中的orderer-base服务如下:

orderer-base:
    image: hyperledger/fabric-orderer:$IMAGE_TAG
    environment:
      - FABRIC_LOGGING_SPEC=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_BOOTSTRAPMETHOD=file
      - ORDERER_GENERAL_BOOTSTRAPFILE=/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_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

里面定义了镜像名称、环境变量配置、工作目录、启动命令,环境变量配置包括监听地址、证书地址等。
orderer启动后会建立一个raft集群。
使用命令docker logs -f orderer.example.com可查看到第一个orderer启动的日志,可查看到主要过程为:

  1. 根据orderer1的配置初始化排序节点
  2. 创建本地账本目录
  3. 设置排序节点服务监听端口
  4. 根据创始区块文件初始化本地账本
  5. 启动fabric系统通道
  6. 启动raft服务

4.2 peer节点的启动

peer的yaml文件配置结构与orderer类似,不在赘述。
使用命令docker logs -f peer0.org1.example.com可查看到其中一个peer的启动日志:
Fabric v2.0 first-network测试网络运行与剖析_第4张图片
日志中会输出容器的基本信息,peer节点启动过程主要是:

  1. 启动peer grpc服务;
  2. 初始化gossip服务;
  3. 初始化本地账本;
  4. 安装系统链码,这里比起1.x,2.0多了一个系统链码_lifecycle,负责生命周期管理;
  5. 基于gossip对同组织节点进行交互。

4.3 剩余4个排序节点的启动

docker-compose-etcdraft2.yaml中将会启动剩余的4个orderer容器。脚本中使用命令docker-compose -f docker-compose-etcdraft2.yaml up -d 2>&1启动这些节点。
查看一开始启动的第一个orderer的日志,可看到orderer.example.com以及成功连接其他raft节点,并且在raft 的term2,leader从orderer.example.com(0)变成orderer5.example.com(5)。
在这里插入图片描述
查看orderer5.example.com的日志,在term2 经过一轮投票后,orderer5获得5票回应成为了term2的raft leader。
Fabric v2.0 first-network测试网络运行与剖析_第5张图片
Fabric网络已完全启动,docker ps命令查看所有启动的节点:
在这里插入图片描述

感谢富强的博客:
https://blog.csdn.net/qq_28540443/article/details/104298137

你可能感兴趣的:(#,Fabric,v2.x,Hyperledger,Fabric)