Hyperledger fabric v1.0.0 环境部署过程

前言

本文主要基于 Hyperledger fabric 的官方文档来搭建其实验环境,但官方文档对于很多步骤都有省略,所以本文将比较详细的在一台新安装的 Ubuntu 16.04 虚拟机上来介绍 fabric 的环境部署流程步骤。

环境部署

1. 更换 apt 源

先备份 sources.list 文件:

1
$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

再修改 sources.list 文件,换成阿里云的国内源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sudo vim /etc/apt/sources.list
deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse

最后更新一下源:

1
$ sudo apt-get update

2. 安装 curl

Ubuntu 16.04 一般默认是安装了 curl 的,可以通过以下命令验证:

1
2
3
4
$ curl -V
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets

如果没有安装,则通过 apt-get 安装:

1
$ sudo apt-get install curl

3. 安装 Docker

  • 由于 apt 源使用HTTPS以确保软件下载过程中不被篡改。因此,我们首先需要添加使用HTTPS传输的软件包以及CA证书。

    1
    2
    3
    4
    5
    $ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
  • 为了确认所下载软件包的合法性,需要添加软件源的 GPG 秘钥

    1
    $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  • 然后,我们需要向 sources.list 中添加 Docker 软件源

    1
    2
    3
    4
    $ sudo add-apt-repository \
    "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

    以上命令会添加稳定版本的Docker CE apt 镜像源。

  • 更新 apt 软件包缓存,并安装 docker-ce:

    1
    2
    3
    $ sudo apt-get update

    $ sudo apt-get install docker-ce
  • 查看 Docker 版本:

    1
    2
    $ docker -v
    Docker version 18.06.0-ce, build 0ffa825

    满足官方文档中 Docker version 17.06.2-ce or greater is required 的要求。

  • 启动 Docker CE

    1
    2
    $ sudo systemctl enable docker
    $ sudo systemctl start docker
  • 建立 docker 用户组

    默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。

    1
    $ sudo groupadd docker

    其实一般按照上面的方法安装 Docker 后就已经创建好 docker 用户组了,可以使用 $ cat /etc/group | grep docker 命令来验证,所以就不需要再建立 docker 用户组了,再建立也会报错提示用户组已存在的。

  • 将当前用户加入 docker 用户组:

    1
    $ sudo usermod -aG docker $USER

    下次登录时即可方便的使用 docker 命令。

  • 测试 Docker 是否安装正确

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    $ docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    9db2ca6ccae0: Pull complete
    Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
    Status: Downloaded newer image for hello-world:latest

    Hello from Docker!
    This message shows that your installation appears to be working correctly.

    To generate this message, Docker took the following steps:
    1. The Docker client contacted the Docker daemon.
    2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
    3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
    4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

    To try something more ambitious, you can run an Ubuntu container with:
    $ docker run -it ubuntu bash

    Share images, automate workflows, and more with a free Docker ID:
    https://hub.docker.com/

    For more examples and ideas, visit:
    https://docs.docker.com/engine/userguide/
  • 配置镜像加速器

    国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:

    当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。

    国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。

    我们以 Docker 官方加速器 https://registry.docker-cn.com 为例进行介绍。

    /etc/docker/daemon.json 中写入如下内容(如果文件不存在则创建)

    1
    2
    3
    4
    5
    {
    "registry-mirrors": [
    "https://registry.docker-cn.com"
    ]
    }

    之后重新启动服务

    1
    2
    $ sudo systemctl daemon-reload
    $ sudo systemctl restart docker

    4. 安装 Docker Compose

  • 通过二进制包来安装,从 官方 GitHub Release 处直接下载编译好的二进制文件即可。

    1
    2
    3
    $ sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

    $ sudo chmod +x /usr/local/bin/docker-compose
  • 查看 Docker compose 版本

    1
    2
    $ docker-compose --version
    docker-compose version 1.22.0, build f46880fe

    满足官方文档中 Docker Compose version 1.14.0 or greater 的要求。

5. 安装 Go 语言环境

Hyperledger Fabric 在很多组件中使用了 Go 语言,并且 Hyperledger fabric 1.2.0 要求使用的是 GO version 1.10.x ,所以需要在我们的环境中安装对应的 Go 语言。

  • 从官网下载 1.10.x 版本的 Linux 平台的源码包

    1
    $ wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
  • 解压到指定目录

    1
    $ sudo tar zxvf go1.10.3.linux-amd64.tar.gz -C /usr/local/
  • 先创建 Go 的工作目录

    1
    $ mkdir ~/go
  • 配置环境变量

    1
    2
    3
    4
    5
    $ vi ~/.bashrc
    添加
    export GOROOT=/usr/local/go
    export GOPATH=/home/user1/go
    export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

    保存并使生效:

    1
    $ source ~/.bashrc
  • 测试 Go 的 demo 程序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    $ cd ~/go

    $ vi hello.go
    package main

    import "fmt"

    func main() {
    fmt.Printf("hello world\n")
    }

    $ go build hello.go

    $ ls
    hello hello.go

    $ ./hello
    hello world

    6. Fabric 源码下载

  • 首先创建存放源码的文件夹:

    1
    $ mkdir -p ~/go/src/github.com/hyperledger
  • 使用 Git 下载完整源码:

    1
    $ git clone https://github.com/hyperledger/fabric.git
  • 进入 fabric 目录查看版本分支并切换分支:

    1
    2
    3
    4
    $ cd fabric
    $ git branch
    * release-1.2
    $ git checkout v1.0.0

    由于在 release-1.2 版本中碰到没有解决的问题,所以先切换到 v1.0.0 来完成搭建并测试的过程。

7. Fabric Docker 镜像下载

进入 ~/go/src/github.com/hyperledger/fabrci/examples/e2e_cli/ 目录,完成镜像下载,执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ cd ~/go/src/github.com/hyperledger/fabrci/examples/e2e_cli/
$ ls
base docker-compose-cli.yaml download-dockerimages.sh scripts
channel-artifacts docker-compose-couch.yaml end-to-end.rst
configtx.yaml docker-compose-e2e-template.yaml generateArtifacts.sh
crypto-config.yaml docker-compose-e2e.yaml network_setup.sh
$ source download-dockerimages.sh -c x86_64-1.0.0 -f x86_64-1.0.0
$ docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
hyperledger/fabric-tools latest 0403fd1c72c7 13 months ago 1.32GB
hyperledger/fabric-tools x86_64-1.0.0 0403fd1c72c7 13 months ago 1.32GB
hyperledger/fabric-couchdb latest 2fbdbf3ab945 13 months ago 1.48GB
hyperledger/fabric-couchdb x86_64-1.0.0 2fbdbf3ab945 13 months ago 1.48GB
hyperledger/fabric-kafka latest dbd3f94de4b5 13 months ago 1.3GB
hyperledger/fabric-kafka x86_64-1.0.0 dbd3f94de4b5 13 months ago 1.3GB
hyperledger/fabric-zookeeper latest e545dbf1c6af 13 months ago 1.31GB
hyperledger/fabric-zookeeper x86_64-1.0.0 e545dbf1c6af 13 months ago 1.31GB
hyperledger/fabric-orderer latest e317ca5638ba 13 months ago 179MB
hyperledger/fabric-orderer x86_64-1.0.0 e317ca5638ba 13 months ago 179MB
hyperledger/fabric-peer latest 6830dcd7b9b5 13 months ago 182MB
hyperledger/fabric-peer x86_64-1.0.0 6830dcd7b9b5 13 months ago 182MB
hyperledger/fabric-javaenv latest 8948126f0935 13 months ago 1.42GB
hyperledger/fabric-javaenv x86_64-1.0.0 8948126f0935 13 months ago 1.42GB
hyperledger/fabric-ccenv latest 7182c260a5ca 13 months ago 1.29GB
hyperledger/fabric-ccenv x86_64-1.0.0 7182c260a5ca 13 months ago 1.29GB
hyperledger/fabric-ca latest a15c59ecda5b 13 months ago 238MB
hyperledger/fabric-ca x86_64-1.0.0 a15c59ecda5b 13 months ago 238MB
hyperledger/fabric-baseos x86_64-0.3.1 4b0cab202084 15 months ago 157MB

8. 启动 fabric 网络并完成 chaincode 测试

还是在刚刚的 e2e_cli 文件加下,执行:

1
2
3
4
5
6
7
8
9
$ ./network_setup.sh up
......
......
===================== All GOOD, End-2-End execution completed =====================
_____ _ _ ____ _____ ____ _____
| ____| | \ | | | _ \ | ____| |___ \ | ____|
| _| | \| | | | | | _____ | _| __) | | _|
| |___ | |\ | | |_| | |_____| | |___ / __/ | |___
|_____| |_| \_| |____/ |_____| |_____| |_____|

最后出现上面字符说明 fabric 网络已经启动并完成了 chaincode 的测试。


搭建过程中碰到的问题:

v1.0.0 版本搭建过程中会碰到的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
===================== Chaincode is installed on remote peer PEER2 ===================== 

Instantiating chaincode on org2/peer2...
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
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_LOCALMSPID=Org2MSP
CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
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_ENABLED=true
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ID=cli
CORE_LOGGING_LEVEL=DEBUG
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
2018-08-21 13:24:09.596 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-08-21 13:24:09.596 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-08-21 13:24:09.602 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-08-21 13:24:09.602 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-08-21 13:24:09.603 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A95070A6708031A0C08F9A4F0DB0510...324D53500A04657363630A0476736363
2018-08-21 13:24:09.603 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: D73172E2164A0DD4FA9B64DBAFE980C3ABC412EB3CD32FEBF6EF7A7AFE3B6431
Error: Error endorsing chaincode: rpc error: code = Unknown desc = Error starting container: API error (404): {"message":"network e2ecli_default not found"}

Usage:
peer chaincode instantiate [flags]

Flags:
-C, --channelID string The channel on which this command should be executed (default "testchainid")
-c, --ctor string Constructor message for the chaincode in JSON format (default "{}")
-E, --escc string The name of the endorsement system chaincode to be used for this chaincode
-l, --lang string Language the chaincode is written in (default "golang")
-n, --name string Name of the chaincode
-P, --policy string The endorsement policy associated to this chaincode
-v, --version string Version of the chaincode specified in install/instantiate/upgrade commands
-V, --vscc string The name of the verification system chaincode to be used for this chaincode

Global Flags:
--cafile string Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
--logging-level string Default logging level and overrides, see core.yaml for full syntax
-o, --orderer string Ordering service endpoint
--test.coverprofile string Done (default "coverage.cov")
--tls Use TLS when communicating with the orderer endpoint

!!!!!!!!!!!!!!! Chaincode instantiation on PEER2 on channel 'mychannel' failed !!!!!!!!!!!!!!!!
================== ERROR !!! FAILED to execute End-2-End Scenario ==================

解决方法:

这个主要是因为 e2e_cli/base目录下的 peer-base.yaml 文件中的网络名称打成了 e2ecli_default,将其改成 e2e_cli_default 即可。