本文最后更新于:1 年前
本文尝试编译 Fabric 源码来构建网络。
bootstrap.sh 在上一篇文章中,我直接执行了 bootstrap.sh 这个脚本一键部署。使用这个方法根本不需要拉取 Fabric 的源代码,它为我们做了三件事情:
从 github 上克隆 hyperledger/fabric-samples 并进入该目录,然后检出适当的版本
在 fabric-samples 目录下安装特定平台的 Hyperledger Fabric 二进制可执行文件和配置文件
下载指定版本的 Hyperledger Fabric 的 docker 镜像
其中第二步是执行 curl 去下载 tar 包并解压,二进制文件会被放在 bin 目录下:
名称
作用
peer
负责启动节点,存储区块链数据,运行维护链码
orderer
负责启动排序节点,对交易进行排序,并将排序好的交易打包成模块
cryptogen
生成组织结构和身份文件
configtxgen
生成配置区块和配置交易
configtxlator
解读配置信息
fabric-ca-client
fabric-ca 客户端命令
discover
fabric 发现服务的客户端命令
idemixgen
身份混合机制
部分镜像说明如下:
镜像名称
是否可选
镜像说明
hyperledger/fabric-tools
可选
包含 crytogen、configtxgen、configtxlator 工具的镜像文件
hyperledger/fabric-couchdb
可选
CouchDB 的数据库镜像文件、状态数据库选择 CouchDB 的时候才需要
hyperledger/fabric-kafka
可选
Kafka 的镜像文件
hyperledger/fabric-zookeeper
可选
Zookeeper 的镜像文件
hyperledger/fabric-peer
必选
Peer 节点的镜像文件
hyperledger/fabric-orderer
必选
排序服务节点的镜像文件
hyperledger/fabric-javaenv
可选
Java 链码的基础镜像文件
hyperledger/fabric-ccenv
必选
Golang 链码的基础镜像文件
hyperledger/fabric-ca
可选
fabric-ca 的镜像文件,用到 fabric-ca 的时候才需要
编译源码 接下来尝试一下从 Fabric 源码入手,来搭建网络。
1. 下载 fabric 源码 1 2 3 $ git clone https://github.com/hyperledger/fabric.git $ cd fabric $ git checkout v2.4.0
2. 编译 fabric 源码
编译好的二进制可执行文件在 fabric/release/linux-amd64/bin/ 下:
测试编译 我注意到网上的教程都需要我们把 fabric 的源码放在 $GOPATH/src/github.com/heperledger/ 目录下,Makefile 文件中的编译路径也是:
1 2 3 4 5 6 7 8 9 10 PKGNAME = github.com/hyperledger/fabric pkgmap.configtxgen := $(PKGNAME) /cmd/configtxgen pkgmap.configtxlator := $(PKGNAME) /cmd/configtxlator pkgmap.cryptogen := $(PKGNAME) /cmd/cryptogen pkgmap.discover := $(PKGNAME) /cmd/discover pkgmap.ledgerutil := $(PKGNAME) /cmd/ledgerutil pkgmap.orderer := $(PKGNAME) /cmd/orderer pkgmap.osnadmin := $(PKGNAME) /cmd/osnadmin pkgmap.peer := $(PKGNAME) /cmd/peer
为了测试能否在自定义路径中编译源码,我修改了 fabric/internal/peer/version/version.go :
然后编译并执行:
1 2 3 $ make peer $ export PATH=$PWD/build/bin $ peer
3. 下载 fabric-ca 源码 1 2 $ git clone https://github.com/hyperledger/fabric-ca.git $ cd fabric-ca
4. 编译 fabric-ca 源码 1 2 $ make fabric-ca-server $ make fabric-ca-client
编译好的二进制可执行文件在 fabric-ca/bin/ 下:
制作镜像 把当前用户加入到 docker 用户组后,分别在 fabric 和 fabric-ca 目录下执行:
镜像代码 Makefile 中制作 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 .PHONY : dockerdocker: $(RELEASE_IMAGES:%=%-docker) .PHONY : $(RELEASE_IMAGES:%=%-docker)$(RELEASE_IMAGES:%=%-docker): %-docker: $(BUILD_DIR) /images/%/$(DUMMY) $(BUILD_DIR) /images/baseos/$(DUMMY) : BUILD_CONTEXT=images/baseos$(BUILD_DIR) /images/ccenv/$(DUMMY) : BUILD_CONTEXT=images/ccenv$(BUILD_DIR) /images/peer/$(DUMMY) : BUILD_ARGS=--build-arg GO_TAGS=${GO_TAGS}$(BUILD_DIR) /images/orderer/$(DUMMY) : BUILD_ARGS=--build-arg GO_TAGS=${GO_TAGS}$(BUILD_DIR) /images/tools/$(DUMMY) : BUILD_ARGS=--build-arg GO_TAGS=${GO_TAGS}$(BUILD_DIR) /images/%/$(DUMMY) : @echo "Building Docker image $(DOCKER_NS) /fabric-$* " @mkdir -p $(@D) $(DBUILD) -f images/$* /Dockerfile \ --build-arg GO_VER=$(GO_VER) \ --build-arg ALPINE_VER=$(ALPINE_VER) \ $(BUILD_ARGS) \ -t $(DOCKER_NS) /fabric-$* ./$(BUILD_CONTEXT) docker tag $(DOCKER_NS) /fabric-$* $(DOCKER_NS) /fabric-$* :$(BASE_VERSION) docker tag $(DOCKER_NS) /fabric-$* $(DOCKER_NS) /fabric-$* :$(TWO_DIGIT_VERSION) docker tag $(DOCKER_NS) /fabric-$* $(DOCKER_NS) /fabric-$* :$(DOCKER_TAG) @touch $@
其中 $(DBUILD) -f 即 docker build -f 指明了 Dockerfile 的路径。以 fabric/images/peer/Dockerfile 为例:
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 FROM alpine:${ALPINE_VER} as peer-baseRUN apk add --no-cache tzdata RUN echo 'hosts: files dns' > /etc/nsswitch.conf FROM golang:${GO_VER}-alpine${ALPINE_VER} as golangRUN apk add --no-cache \ bash \ binutils-gold \ gcc \ git \ make \ musl-dev ADD . $GOPATH /src/github.com/hyperledger/fabric WORKDIR $GOPATH /src/github.com/hyperledger/fabric FROM golang as peerARG GO_TAGSRUN make peer GO_TAGS=${GO_TAGS} FROM peer-baseENV FABRIC_CFG_PATH /etc/hyperledger/fabricVOLUME /etc/hyperledger/fabric VOLUME /var/hyperledger COPY --from=peer /go/src/github.com/hyperledger/fabric/build/bin /usr/local/bin COPY --from=peer /go/src/github.com/hyperledger/fabric/sampleconfig/msp ${FABRIC_CFG_PATH} /msp COPY --from=peer /go/src/github.com/hyperledger/fabric/sampleconfig/core.yaml ${FABRIC_CFG_PATH} EXPOSE 7051 CMD ["peer" ,"node" ,"start" ]
这是一个分阶段构建镜像的过程,每个阶段生成一个镜像,下一个阶段在此基础上生成:
peer-base 阶段:
基于指定的 Alpine 版本构建基础镜像。
安装 tzdata 包,用于时区设置。
配置 nsswitch.conf 文件,以支持 Go 的 “netgo” 实现。
golang 阶段:
基于指定的 Go 版本和 Alpine 版本构建 Golang 镜像。
安装构建所需的工具和依赖,如 bash、binutils-gold、gcc、git、make 和 musl-dev。
将当前目录下 的文件复制到 Golang 镜像的对应路径 $GOPATH/src/github.com/hyperledger/fabric。
peer 阶段:
基于 golang 阶段构建一个临时的 Golang 镜像。
使用 make 命令构建 Peer 节点的二进制文件。
使用 GO_TAGS 参数指定构建所需的 Go 标签。
最终 阶段:
基于 peer-base 阶段构建最终的镜像。
设置环境变量 FABRIC_CFG_PATH 为 /etc/hyperledger/fabric。
创建两个数据卷,分别用于存储 Fabric 配置文件和 Hyperledger 数据。
从 peer 阶段复制生成的二进制文件到 /usr/local/bin 目录下。
从 peer 阶段复制生成的 MSP 配置到 /etc/hyperledger/fabric/msp 目录下。
从 peer 阶段复制生成的核心配置文件 core.yaml 到 /etc/hyperledger/fabric 目录下。
暴露容器的 7051 端口。
使用 CMD 指令在容器启动时运行 peer node start 命令。
可以看出该镜像并非直接复制主机编译的二进制文件,而是复制当前目录的代码,在容器中自己编译。
测试镜像 保留之前测试编译的更改,制作 peer 镜像并进入容器测试:
1 2 3 4 $ make peer-docker $ docker run hyperledger/fabric-peer $ docker exec -it container_id /bin/sh # peer
启动网络
将之前编译的二进制文件全部放在 fabric-samples/bin 下:
此时还需要生成节点的配置文件,将 fabric/sampleconfig 复制到 fabric-samples,并改名 config。
启动:
1 2 $ cd test-network $ ./network.sh up
成功启动!
但是在创建通道的时候组织二的节点无法加入,将 peer 的二进制文件更换为官方提供直接下载的则没有这个问题。