Hyperledger Fabric动态配置Raft节点

Hyperledger Fabric动态配置Raft节点

最近看官方文档发现新的共识算法etcdRaft允许动态添加或删除排序节点,所以也花了一天时间操作了以下,写篇文章把整个过程记录一下。
初始网络本文设置了4个Orderer节点,1个Peer节点(用于更新配置文件以及测试用),然后动态添加第五个Orderer节点。
本文分成两个部分:

  1. 第一部分是手动通过Fabric-CA生成每一个节点的证书文件
  2. 第二部分是更新Fabric网络配置添加新的Orderer节点。

本文基于Fabric v2.0.0-beta版本。版本号只要高于1.4.1就行

1 搭建定制化的Fabric网络

前提条件是成功跑起来Fabric的示例网络,可以看这里->Hyperledger Fabric环境搭建

首先在$GOPATH下(本文路径地址为$GOPATH/src/github.com/hyperledger/fab)建立如下几个文件夹用于之后的操作:

.  # 这里是根目录fab
├── ca    # 用于生成CA证书的ca配置文件的文件夹
│?? ├── org1
│?? │?? └── fabric-ca-server-config.yaml
│?? └── server
│??     └── fabric-ca-server-config.yaml
├── channel-artifacts    #用于保存创世区块以及通道配置文件
├── configtx.yaml      #配置文件:用于生成创世区块以及通道配置文件
├── crypto-config     #存储生成的证书文件
├── docker      # Fabric网络节点通过Docker启动,用于启动节点的Docker文件
│?? ├── base.yaml
│?? ├── docker-compose-addOrderer5.yaml
│?? ├── docker-compose-ca.yaml
│?? ├── docker-compose-orderers.yaml
│?? └── docker-compose-peer.yaml
└── store    #存储区块等信息

以下所有操作默认都在根目录文件夹内!

1.1CA配置文件

直接在这里贴出来:org1/fabric-ca-server-config.yaml:

展开查看org1/fabric-ca-server-config.yaml


version: 1.2.0

# Server's listening port (default: 7054)
port: 7054

# Enables debug logging (default: false)
debug: false

crlsizelimit: 512000

tls:
  # Enable TLS (default: false)
  enabled: true
  certfile:
  keyfile:
  clientauth:
    type: noclientcert
    certfiles:

ca:
  # Name of this CA
  name: Org1CA
  keyfile:
  certfile:
  chainfile:

crl:
  expiry: 24h

registry:

  maxenrollments: -1

  identities:
     - name: admin
       pass: adminpw
       type: client
       affiliation: ""
       attrs:
          hf.Registrar.Roles: "*"
          hf.Registrar.DelegateRoles: "*"
          hf.Revoker: true
          hf.IntermediateCA: true
          hf.GenCRL: true
          hf.Registrar.Attributes: "*"
          hf.AffiliationMgr: true

db:
  type: sqlite3
  datasource: fabric-ca-server.db
  tls:
      enabled: false
      certfiles:
      client:
        certfile:
        keyfile:

ldap:

   enabled: false
   url: ldap://<adminDN>:<adminPassword>@<host>:<port>/<base>
   tls:
      certfiles:
      client:
         certfile:
         keyfile:
   attribute:
      names: ['uid','member']
      converters:
         - name:
           value:
      maps:
         groups:
            - name:
              value:

affiliations:
   org1:
      - department1
      - department2
   org2:
      - department1

signing:
    default:
      usage:
        - digital signature
      expiry: 8760h
    profiles:
      ca:
         usage:
           - cert sign
           - crl sign
         expiry: 43800h
         caconstraint:
           isca: true
           maxpathlen: 0
      tls:
         usage:
            - signing
            - key encipherment
            - server auth
            - client auth
            - key agreement
         expiry: 8760h

csr:
   cn: ca.org1.example.com
   names:
      - C: US
        ST: "North Carolina"
        L: "Durham"
        O: org1.example.com
        OU:
   hosts:
     - localhost
     - org1.example.com
   ca:
      expiry: 131400h
      pathlength: 1

bccsp:
    default: SW
    sw:
        hash: SHA2
        security: 256
        filekeystore:
            keystore: msp/keystore

cacount:

cafiles:

intermediate:
  parentserver:
    url:
    caname:

  enrollment:
    hosts:
    profile:
    label:

  tls:
    certfiles:
    client:
      certfile:
      keyfile:
      

以及server/fabric-ca-server-config.yaml::

展开查看server/fabric-ca-server-config.yaml:

# Version of config file
version: 1.2.0
# Server's listening port (default: 7054)
port: 7054
# Enables debug logging (default: false)
debug: false
# Size limit of an acceptable CRL in bytes (default: 512000)
crlsizelimit: 512000
tls:
  # Enable TLS (default: false)
  enabled: true
  # TLS for the server's listening port
  certfile:
  keyfile:
  clientauth:
    type: noclientcert
    certfiles:

ca:
  # Name of this CA
  name: OrdererCA
  keyfile:
  certfile:
  chainfile:

crl:
  expiry: 24h

registry:
  maxenrollments: -1

  identities:
     - name: admin
       pass: adminpw
       type: client
       affiliation: ""
       attrs:
          hf.Registrar.Roles: "*"
          hf.Registrar.DelegateRoles: "*"
          hf.Revoker: true
          hf.IntermediateCA: true
          hf.GenCRL: true
          hf.Registrar.Attributes: "*"
          hf.AffiliationMgr: true

db:
  type: sqlite3
  datasource: fabric-ca-server.db
  tls:
      enabled: false
      certfiles:
      client:
        certfile:
        keyfile:

ldap:
   enabled: false
   url: ldap://<adminDN>:<adminPassword>@<host>:<port>/<base>
   tls:
      certfiles:
      client:
         certfile:
         keyfile:
   attribute:
      names: ['uid','member']
      converters:
         - name:
           value:
      maps:
         groups:
            - name:
              value:

affiliations:
   org1:
      - department1
      - department2
   org2:
      - department1

signing:
    default:
      usage:
        - digital signature
      expiry: 8760h
    profiles:
      ca:
         usage:
           - cert sign
           - crl sign
         expiry: 43800h
         caconstraint:
           isca: true
           maxpathlen: 0
      tls:
         usage:
            - signing
            - key encipherment
            - server auth
            - client auth
            - key agreement
         expiry: 8760h

csr:
   cn: ca.example.com
   names:
      - C: US
        ST: "New York"
        L: "New York"
        O: example.com
        OU:
   hosts:
     - localhost
     - example.com
   ca:
      expiry: 131400h
      pathlength: 1

bccsp:
    default: SW
    sw:
        hash: SHA2
        security: 256
        filekeystore:
            keystore: msp/keystore

cacount:
cafiles:

intermediate:
  parentserver:
    url:
    caname:

  enrollment:
    hosts:
    profile:
    label:

  tls:
    certfiles:
    client:
      certfile:
      keyfile:

docker-compose-ca.yaml文件:

展开查看docker-compose-ca.yaml文件

version: '2'

services:
  ca:
    image: hyperledger/fabric-ca:1.4.4
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-orderer
      - FABRIC_CA_SERVER_TLS_ENABLED=true
      - FABRIC_CA_SERVER_PORT=9054
    ports:
      - "9054:9054"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
    volumes:
      - ../ca/server:/etc/hyperledger/fabric-ca-server
    container_name: ca_orderer

  ca0:
    image: hyperledger/fabric-ca:1.4.4
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-org1
      - FABRIC_CA_SERVER_TLS_ENABLED=true
      - FABRIC_CA_SERVER_PORT=7054
    ports:
      - "7054:7054"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
    volumes:
      - ../ca/org1:/etc/hyperledger/fabric-ca-server
    container_name: ca_org1

将以上三个文件保存到指定的路径,然后使用以下命令启动CA服务器:

docker-compose -f docker/docker-compose-ca.yaml up -d

服务器会自动读取上面的两个配置文件,并初始化CA服务器。
当然,服务器配置文件将自动生成在ca/server/子文件夹内,其中最主要使用到的是tls-cert.pem文件。

1.2 注册Orderer节点

首先配置环境变量并登陆管理员账号:

#创建存储Order节点证书的子文件夹。
mkdir -p crypto-config/orderOrganization/example.com
export FABRIC_CA_CLIENT_HOME=${PWD}/crypto-config/orderOrganization/example.com
fabric-ca-client enroll -u https://admin:[email protected]:9054 --caname ca-orderer --tls.certfiles ${PWD}/ca/server/tls-cert.pem

生成节点类型分类配置文件(不知道这个文件应该称作什么,暂且使用这个名字称呼好了):

  echo 'NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: client
  PeerOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: peer
  AdminOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: admin
  OrdererOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: orderer' > ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml

之后注册网络中初始的4个Orderer节点:

fabric-ca-client register -u https://admin:[email protected]:9054 --caname ca-orderer --id.name orderer1 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client register -u https://admin:[email protected]:9054 --caname ca-orderer --id.name orderer2 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client register -u https://admin:[email protected]:9054 --caname ca-orderer --id.name orderer3 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client register -u https://admin:[email protected]:9054 --caname ca-orderer --id.name orderer4 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem

注册Admin节点:

fabric-ca-client register -u https://admin:[email protected]:9054 --caname ca-orderer --id.name ordererAdmin --id.secret ordererAdminpw --id.type admin --id.attrs '"hf.Registrar.Roles=admin"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem

1.3 获取Orderer证书文件

为刚刚创建的几个用户创建各自的文件夹用于存储证书文件:

mkdir -p crypto-config/orderOrganization/example.com/orderers
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer1.example.com
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer2.example.com
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer3.example.com
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer4.example.com

接下来获取每一个Orderer节点的MSP证书文件:

fabric-ca-client enroll -u https://orderer1:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp --csr.hosts orderer1.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer2:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp --csr.hosts orderer2.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer3:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp --csr.hosts orderer3.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer4:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp --csr.hosts orderer4.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem

还有每一个节点的TLS证书:

fabric-ca-client enroll -u https://orderer1:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls --enrollment.profile tls --csr.hosts orderer1.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer2:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls --enrollment.profile tls --csr.hosts orderer2.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer3:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls --enrollment.profile tls --csr.hosts orderer3.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer4:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls --enrollment.profile tls --csr.hosts orderer4.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem

将之前生成的节点类型分类配置文件拷贝到每一个节点的MSP文件夹:

cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp/config.yaml
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp/config.yaml
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp/config.yaml
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp/config.yaml

然后为每一个节点的TLS证书以及秘钥文件修改名字,方便之后的使用:

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.key

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.key

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.key

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.key

然后在MSP文件夹内创建tlscacerts文件夹,并将TLS文件拷贝过去:

mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts
mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp/tlscacerts
mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp/tlscacerts
mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp/tlscacerts

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

复制TLS根证书:

mkdir -p ${PWD}/crypto-config/orderOrganization/example.com/msp/tlscacerts
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/msp/tlscacerts/tlsca.example.com-cert.pem

最后是Admin节点的证书文件:

#首先也是创建文件夹
mkdir -p crypto-config/orderOrganization/example.com/users
mkdir -p crypto-config/orderOrganization/example.com/users/[email protected]
#获取证书文件
fabric-ca-client enroll -u https://ordererAdmin:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/users/[email protected]/msp --tls.certfiles ${PWD}/ca/server/tls-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/users/[email protected]/msp/config.yaml

到这里Orderer节点证书已经生成完毕(可以根据实际需要修改Orderer节点数量,最少不能低于3个),接下来是网络中唯一的peer节点的配置文件生成:

1.4 注册Peer节点

和上面步骤相同,首先创建子文件夹用于存储证书文件:

mkdir -p crypto-config/peerOrganizations/org1.example.com/

配置环境变量并登陆管理员身份:

export FABRIC_CA_CLIENT_HOME=${PWD}/crypto-config/peerOrganizations/org1.example.com/
fabric-ca-client enroll -u https://admin:[email protected]:7054 --caname ca-org1 --tls.certfiles ${PWD}/ca/org1/tls-cert.pem

生成节点类型分类配置文件:

echo 'NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/localhost-7054-ca-org1.pem
    OrganizationalUnitIdentifier: client
  PeerOUIdentifier:
    Certificate: cacerts/localhost-7054-ca-org1.pem
    OrganizationalUnitIdentifier: peer
  AdminOUIdentifier:
    Certificate: cacerts/localhost-7054-ca-org1.pem
    OrganizationalUnitIdentifier: admin
  OrdererOUIdentifier:
    Certificate: cacerts/localhost-7054-ca-org1.pem
    OrganizationalUnitIdentifier: orderer' > ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/config.yaml

虽然网络中只有一个peer节点,但是我们需要注册三个用户:peer0,user1,org1admin,其中第一个是必需的,第二个是用于测试的,第三个为Admin用户,安装和实例化链码需要Admin用户的证书:

fabric-ca-client register -u https://admin:[email protected]:7054 --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --id.attrs '"hf.Registrar.Roles=peer"' --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
fabric-ca-client register -u https://admin:[email protected]:7054 --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --id.attrs '"hf.Registrar.Roles=client"' --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
fabric-ca-client register -u https://admin:[email protected]:7054 --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --id.attrs '"hf.Registrar.Roles=admin"' --tls.certfiles ${PWD}/ca/org1/tls-cert.pem

1.5 获取Peer节点证书文件

节点注册完毕,获取他们的证书文件:
创建子文件夹:

mkdir -p crypto-config/peerOrganizations/org1.example.com/peers
mkdir -p crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.co

获取证书文件:

#MSP文件
fabric-ca-client enroll -u https://peer0:[email protected]:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp --csr.hosts peer0.org1.example.com --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
#TLS证书
fabric-ca-client enroll -u https://peer0:[email protected]:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls --enrollment.profile tls --csr.hosts peer0.org1.example.com --csr.hosts localhost --tls.certfiles ${PWD}/ca/org1/tls-cert.pem

拷贝节点分类配置文件:

cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/config.yaml

修改证书以及秘钥文件,方便之后使用:

cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/signcerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/keystore/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key

将TLS相关证书复制一份:

mkdir ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/ca.crt

mkdir ${PWD}/crypto-config/peerOrganizations/org1.example.com/tlsca
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem

mkdir ${PWD}/crypto-config/peerOrganizations/org1.example.com/ca
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/cacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem

获取userAdmin用户证书文件:

#创建子文件夹
mkdir -p crypto-config/peerOrganizations/org1.example.com/users
mkdir -p crypto-config/peerOrganizations/org1.example.com/users/[email protected]
mkdir -p crypto-config/peerOrganizations/org1.example.com/users/[email protected]
#获取证书文件
fabric-ca-client enroll -u https://user1:[email protected]:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
fabric-ca-client enroll -u https://org1admin:[email protected]:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp/config.yaml

1.6 启动网络之前的准备

到这里我们已经生成了所有需要的证书文件,接下来是生成用于启动网络的创世区块,生成创世区块需要一个文件configtx.yaml,直接复制过来:

展开查看configtx.yaml


Organizations:
    - &OrdererOrg
        Name: OrdererOrg
        ID: OrdererMSP
        MSPDir: ./crypto-config/orderOrganization/example.com/msp   #这里路径需要对应!!!
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"

    - &Org1  #如果需要更多组织节点,可以按照该模板在下面添加
        Name: Org1MSP
        ID: Org1MSP
        MSPDir: ./crypto-config/peerOrganizations/org1.example.com/msp  #这里路径需要对应!!!
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org1MSP.admin')"
            Endorsement:
                Type: Signature
                Rule: "OR('Org1MSP.peer')"
        AnchorPeers:
              Port: 7051

Capabilities:
    Channel: &ChannelCapabilities
        V2_0: true

    Orderer: &OrdererCapabilities
        V2_0: true

    Application: &ApplicationCapabilities
        V2_0: true

Application: &ApplicationDefaults
    Organizations:
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        LifecycleEndorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"
        Endorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"
    Capabilities:
        <<: *ApplicationCapabilities

Orderer: &OrdererDefaults
    OrdererType: etcdraft

    Addresses:
        - orderer1.example.com:7050
    BatchTimeout: 2s
    BatchSize:
        MaxMessageCount: 10
        AbsoluteMaxBytes: 99 MB
        PreferredMaxBytes: 512 KB
    Organizations:
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        BlockValidation:
            Type: ImplicitMeta
            Rule: "ANY Writers"
Channel: &ChannelDefaults
    Policies:
        # 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

Profiles:

    TwoOrgsChannel:   #用于生成通道配置文件
        Consortium: SampleConsortium
        <<: *ChannelDefaults
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
            Capabilities:
                <<: *ApplicationCapabilities

    SampleMultiNodeEtcdRaft:   #用于生成系统通道创世区块
        <<: *ChannelDefaults
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults
            OrdererType: etcdraft   #指定使用etcdraft共识算法
            EtcdRaft:
                Consenters:
                - Host: orderer1.example.com
                  Port: 7050
                  ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
                  ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
                - Host: orderer2.example.com
                  Port: 8050
                  ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.crt
                  ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.crt
                - Host: orderer3.example.com
                  Port: 9050
                  ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.crt
                  ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.crt
                - Host: orderer4.example.com
                  Port: 10050
                  ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.crt
                  ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.crt
#                    - Host: orderer5.example.com
#                      Port: 11050
#                      ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
#                      ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
            Addresses:
                - orderer1.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

将该文件保存到指定位置,接下来生成创世区块:

export FABRIC_CFG_PATH=$PWD
configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
# 生成通道配置文件
export CHANNEL_NAME=mychannel
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID $CHANNEL_NAME

1.7 启动网络

首先写包含所有节点的Docker文件,这里直接贴出来:

展开查看base.yaml

version: '2'

services:
  orderer-base:
    image: hyperledger/fabric-orderer:2.0.0-beta
    environment:
      - FABRIC_LOGGING_SPEC=INFO
#      - FABRIC_LOGGING_SPEC=DEBUG
      - 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节点的Docker文件:

展开查看docker-compose-orderers.yaml

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

version: '2'

volumes:
  orderer1.example.com:
  orderer2.example.com:
  orderer3.example.com:
  orderer4.example.com:

networks:
  byfn:

services:

  orderer1.example.com:
    extends:
      file: base.yaml
      service: orderer-base
    environment:
      - ORDERER_GENERAL_LISTENPORT=7050
    container_name: orderer1.example.com
    networks:
      - byfn
    volumes:
      - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ../crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp:/var/hyperledger/orderer/msp
      - ../crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/:/var/hyperledger/orderer/tls
      - ../store/o1:/var/hyperledger/production/orderer
    ports:
      - 7050:7050

  orderer2.example.com:
    extends:
      file: base.yaml
      service: orderer-base
    environment:
      - ORDERER_GENERAL_LISTENPORT=8050
    container_name: orderer2.example.com
    networks:
      - byfn
    volumes:
      - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ../crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp:/var/hyperledger/orderer/msp
      - ../crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/:/var/hyperledger/orderer/tls
      - ../store/o2:/var/hyperledger/production/orderer
    ports:
      - 8050:8050

  orderer3.example.com:
    extends:
      file: base.yaml
      service: orderer-base
    environment:
      - ORDERER_GENERAL_LISTENPORT=9050
    container_name: orderer3.example.com
    networks:
      - byfn
    volumes:
      - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ../crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp:/var/hyperledger/orderer/msp
      - ../crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/:/var/hyperledger/orderer/tls
      - ../store/o3:/var/hyperledger/production/orderer
    ports:
      - 9050:9050

  orderer4.example.com:
    extends:
      file: base.yaml
      service: orderer-base
    environment:
      - ORDERER_GENERAL_LISTENPORT=10050
    container_name: orderer4.example.com
    networks:
      - byfn
    volumes:
      - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ../crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp:/var/hyperledger/orderer/msp
      - ../crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/:/var/hyperledger/orderer/tls
      - ../store/o4:/var/hyperledger/production/orderer
    ports:
      - 10050:10050

最后一个是peer节点的Docker文件:

展开查看docker-compose-peer.yaml

version: '2'

volumes:
  peer0.org1.example.com:

networks:
  byfn:

services:

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    image: hyperledger/fabric-peer:2.0.0-beta
    environment:
      #Generic peer variables
      - 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=${COMPOSE_PROJECT_NAME}_byfn
      - 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
      # Peer specific variabes
      - 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=peer0.org1.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
      - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
      # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
      # provide the credentials for ledger to connect to CouchDB.  The username and password must
      # match the username and password set for the associated CouchDB.
      - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
      - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
    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
      - ../store/p1:/var/hyperledger/production
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    depends_on:
      - couchdb0
    ports:
      - 7051:7051
    networks:
      - byfn

  couchdb0:
    container_name: couchdb0
    image: couchdb:2.3
    # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
    # for CouchDB.  This will prevent CouchDB from operating in an "Admin Party" mode.
    environment:
      - COUCHDB_USER=
      - COUCHDB_PASSWORD=
    # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
    # for example map it to utilize Fauxton User Interface in dev environments.
    ports:
      - "5984:5984"
    networks:
      - byfn

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:2.0.0-beta
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
#      - FABRIC_LOGGING_SPEC=DEBUG
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_ID=peer0.org1.example.com
      - 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/hyperledger/fabric-samples/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.org1.example.com
    networks:
      - byfn

将以上文件保存到指定位置后,使用以下命令直接启动:

docker-compose -f docker/docker-compose-orderers.yaml -f docker/docker-compose-peer.yaml up -d

启动完成后可以查看每个节点的日志确认节点成功运行:

docker logs orderer1.example.com
...
docker logs peer0.org1.example.com

如果没有错误的话就可以进行第二部分了,如果出现错误则要回去检查是不是哪里漏掉了。

1.8 简单测试

先进行第一部分的测试,看一下创建通道,加入通道是否成功:

#进入CLI容器
docker exec -it cli bash
#配置环境变量
export CHANNEL_NAME=mychannel
export ORDERER_CA=${PWD}/crypto/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export PEER0_ORG1_CA=${PWD}/crypto/peerOrganization/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

创建通道:

peer channel create -o orderer1.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/mychannel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA --outputBlock ./channel-artifacts/${CHANNEL_NAME}.block

加入通道:

peer channel join -b ./channel-artifacts/$CHANNEL_NAME.block

如果一切顺利的话,网络就成功搭建起来了,至于链码就不再测试了。
直接到第二部分,动态添加一个Orderer节点。

2 动态添加Raft节点

主要步骤如下:

  1. 为该节点生成证书文件
  2. 获取当前网络的配置文件
  3. 将证书文件添加到配置文件中
  4. 更新配置文件
  5. 启动新的Orderer节点

2.1 生成证书文件

2.1.1 注册该节点身份

fabric-ca-client register -u https://admin:[email protected]:9054 --caname ca-orderer --id.name orderer5 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem

为该节点创建存储证书的文件夹:

mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer5.example.com

2.1.2 获取该节点证书

#MSP
fabric-ca-client enroll -u https://orderer5:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp --csr.hosts orderer5.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
#TLS
fabric-ca-client enroll -u https://orderer5:[email protected]:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls --enrollment.profile tls --csr.hosts orderer5.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem

复制节点分类配置文件:

cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp/config.yaml

修改证书与秘钥文件名称:

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/server.key

创建文件夹并拷贝TLS证书文件:

mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp/tlscacerts
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

2.2 获取网络配置文件

将节点添加进网络,首先需要将该节点添加到系统通道内,所以先获取系统通道的配置文件:
进入cli容器:

docker exec -it cli bash

配置环境变量,需要使用Orderer节点的身份信息:

export CORE_PEER_LOCALMSPID="OrdererMSP"
export ORDERER_CA=${PWD}/crypto/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/crypto/ordererOrganization/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderOrganization/example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

获取系统通道配置文件:

peer channel fetch config channel-artifacts/config_block.pb -o orderer1.example.com:7050 -c byfn-sys-channel --tls --cafile $ORDERER_CA

解码该配置文件:

configtxlator proto_decode --input channel-artifacts/config_block.pb --type common.Block | jq .data.data[0].payload.data.config > channel-artifacts/config.json

2.3将证书文件添加到配置文件中

退出容器,可以在channel-artifacts文件内找到config.json文件。将该文件复制一份并在channel-artifacts文件夹下保存为update_config.json,使用编辑工具打开,并搜索.example.com字段如下:
字段一部分:

  {
    "client_tls_cert": "一连串的字符串",
    "host": "orderer1.example.com",
    "port": 7050,
    "server_tls_cert": "一连串的字符串"
  }

以及匹配到的第二部分的字段:

      "OrdererAddresses": {
        "mod_policy": "/Channel/Orderer/Admins",
        "value": {
          "addresses": [
            "orderer1.example.com:7050",
            "orderer2.example.com:8050",
            "orderer3.example.com:9050",
            "orderer4.example.com:10050"
          ]
        },
        "version": "0"
    }

在字段一部分,需要将我们生成的新的节点的证书添加上去,其中证书文件地址为:

crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt

使用BASE64转码:

cat crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt | base64 > cert.txt

update_config.json文件中字段一的部分下面按照字段一的格式添加相同的代码块,并进行修改:
cert.txt文件中的内容复制到字段一的client_tls_cert,server_tls_cert对应部分,并修改host对应部分为orderer5.example.comport11050.

2.4更新配置文件

接下来进入cli容器:

docker exec -it cli bash

对原有的配置文件与更新的配置文件进行编码:

configtxlator proto_encode --input channel-artifacts/config.json --type common.Config > channel-artifacts/config.pb
configtxlator proto_encode --input channel-artifacts/update_config.json --type common.Config > channel-artifacts/config_update.pb

计算出两个文件的差异:

configtxlator compute_update --channel_id byfn-sys-channel --original channel-artifacts/config.pb --updated channel-artifacts/config_update.pb > channel-artifacts/updated.pb

对该文件进行解码,并添加用于更新配置的头部信息:

configtxlator proto_decode --input channel-artifacts/updated.pb --type common.ConfigUpdate > channel-artifacts/updated.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"byfn-sys-channel", "type":2}},"data":{"config_update":'$(cat channel-artifacts/updated.json)'}}}' | jq . > channel-artifacts/updated_envelope.json

编码为Envelope格式的文件:

configtxlator proto_encode --input channel-artifacts/updated_envelope.json --type common.Envelope > channel-artifacts/updated_envelope.pb

对该文件进行签名操作,用于更新配置:

peer channel signconfigtx -f channel-artifacts/updated_envelope.pb

提交更新通道配置交易:

peer channel update -f channel-artifacts/updated_envelope.pb -c byfn-sys-channel -o orderer1.example.com:7050 --tls true --cafile $ORDERER_CA

如果没有错误的话,新的Orderer节点证书已经成功添加到网络配置中,接下来可以启动新的节点了:

2.5 启动新的Orderer节点

写一下新的Orderer节点的Docker文件:

展开查看docker-compose-addOrderer5.yaml


version: '2'

volumes:
  orderer5.example.com:

networks:
  byfn:

services:
  orderer5.example.com:
    extends:
      file: base.yaml
      service: orderer-base
    environment:
      - ORDERER_GENERAL_LISTENPORT=11050
    container_name: orderer5.example.com
    networks:
      - byfn
    volumes:
      - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ../crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp:/var/hyperledger/orderer/msp
      - ../crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/:/var/hyperledger/orderer/tls
      - ../store/o5:/var/hyperledger/production/orderer
    ports:
      - 11050:11050

直接通过命令启动它:

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

可以查看新节点的日志确认新的节点已经成功加入了网络。

到这里,本文成功把新的Orderer节点添加进了网络,但是只将该节点添加到了系统通道内,对于应用通道mychannel来说,新的节点并没有添加进来,将新的节点添加进mychannel通道和以上步骤相同,只需要将通道名称由系统通道修改为mychannel即可。本文便不再说明了。
而动态删除节点的过程与添加相似,只不过是从配置文件中删除节点证书。

原文地址:https://www.cnblogs.com/cbkj-xd/p/12123860.html

时间: 2024-10-02 07:55:05

Hyperledger Fabric动态配置Raft节点的相关文章

HyperLedger Fabric基于zookeeper和kafka集群配置解析

简述 在搭建HyperLedger Fabric环境的过程中,我们会用到一个configtx.yaml文件(可参考Hyperledger Fabric 1.0 从零开始(八)--Fabric多节点集群生产部署),该配置文件主要用于构建创世区块(在构建创世区块之前需要先创建与之对应的所有节点的验证文件集合),其中在配置Orderer信息中有一个OrdererType参数,该参数可配置为"solo" and "kafka",之前博文所讲的环境配置皆是solo,即单节点共

HyperLedger Fabric 1.2 单机单节点部署(10.2)

单机单节点指在一台电脑上部署一个排序(Orderer)服务.一个组织(Org1),一个节点(Peer,属于Org1),然后运行官方案例中的example02智能合约例子,实现转财交易和查询功能.单机单节点部署结构图如下: 图:单机单节点部署结构图 单机单节点部署步骤如下:1. 创建singlepeer目录 # cd $GOPATH/src/github.com/hyperledger/fabric # mkdir singlepeer # cd singlepeer 2. 获取生成工具 把下载的

Hyperledger Fabric区块链工具configtxgen配置configtx.yaml

configtx.yaml是Hyperledger Fabric区块链网络运维工具configtxgen用于生成通道创世块或通道交易的配置文件,configtx.yaml的内容直接决定了所生成的创世区块的内容.本文将给出configtx.yaml的详细中文说明. 如果需要快速掌握Fabric区块链的链码与应用开发,推荐访问汇智网的在线互动教程: Fabric区块链Java开发详解 Fabric区块链NodeJS开发详解 Capabilities / 通道能力配置 Capabilities段用来定

基于docker的 Hyperledger Fabric 多机环境搭建(上)

环境:ubuntu 16.04 Docker  17.04.0-ce go 1.7.4 consoul v0.8.0.4 ======================================================================= 一.项目准备 想必能搜到这篇文章的人对Hyperledger Fabric(以下简称Fabric)已经是有了一定的了解了,我就不多介绍了. 先说一下Fabric的构建环境: Hyperledger Fabric  tag v1.0.0

HyperLedger Fabric 学习思路分享

HyperLedger Fabric 学习思路分享 HyperLedger Fabric最初是由Digital Asset和IBM公司贡献的.由Linux基金会主办的一个超级账本项目,它是一个目前非常流行并广为人知的区块链网络框架的实现方案.作为一种基于模块化架构开发应用程序或解决方案的基础,HyperLedger Fabric支持如共识和会员服务等即插即用的组件,它的设计初衷是支持不同组件的可插拔实现,并适应整个经济生态系统的复杂性和高精度性.HyperLedger Fabric利用容器技术运

HyperLeger Fabric SDK开发(二)——Fabric SDK配置

HyperLeger Fabric SDK开发(二)--Fabric SDK配置 一.Fabric SDK配置 Fabric区块链网络应用程序需要大量的参数,用于连接Fabric区块链网络.通常将Fabric区块链网络应用程序所需的参数放到一个配置文件进行管理,配置文件定义Fabric SDK Go的配置和用户自定义参数,指定了连接Fabric区块链网络所需的全部信息,例如Fabric区块链网络组件的主机名和端口等.Fabric SDK GO为应用程序提供的配置文件通常使用yaml文件格式编写,

hyperledger fabric超级账本java sdk样例e2e代码流程分析

一  checkConfig  Before 1.1  private static final TestConfig testConfig = TestConfig.getConfig(); 这里加载一个配置文件(test路径/src/test/java/org/hyperledger/fabric/sdk/testutils.properties,文件不存在就加载代码中写死的默认配置), 配置文件需要设置peer,orderer,ca,eventhub的地址,组织mspid,组织域名.解析配

Hyperledger Fabric原理(3)通道与组织

1,通道的结构 通道是Fabric中非常重要的概念(类似微信群?),它实质是由排序节点划分和管理的私有原子广播通道,目的是对通道的信息进行隔离,使得通道外的实体无法访问通道内的信息,从而实现交易的隐私性. 目前通道分为系统通道(System Channel)和应用通道(Application Channel).排序节点通过系统通道来管理应用通道,用户的交易信息通过应用通道传递.对一般用户来说,通道是指应用通道.系统通道与应用通道的关系如下图: 在文章https://www.cnblogs.com

Hyperledger Fabric 建立一个简单网络

p { margin-bottom: 0.25cm; line-height: 120% } Building you first network 网络结构: 2个Orgnizations(每个Org包含2个peer节点)+1个solo ordering service 打开fabric-sample下的示例first-network p { margin-bottom: 0.25cm; line-height: 120% } 其中byfn.sh为启动这个网络的启动脚本,启动脚本中除建立一个包含