環境: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-alpha (Fabric 的主項目)
Hyperledger Fabric-sdk-node branch v1.0.0-alpha(Fabric的js應用的sdk)
Hyperledger Fabric-ca branch v1.0.0-alpha(Fabric的權限管理項目)
兩台主機,處於同一個網段。
這里要多說兩句,我們從git hub 服務器(無論是github.com還自己搭建的服務器)上clone下來的工程一般默認是在master分支上的,所以我們下載下來上面三個工程后要記得切換分支,目前在我寫這篇博文的時候已經是Fabric1.0已經推出三個版本了(alpha、alpha2、beta),我們用的是第一個發行版本v1.0.0-alpha。
說一下切換分支的方法,熟悉的人可以跳過:
第一種在克隆的時候指定分支
git clone --branch <遠程分支名> <源地址>
第二種是克隆后切換分支
git clone <源地址>
git checkout <遠程分支名> #此時你的git倉庫頭指針是游離的,需要新建一個本地分支和遠程綁定
git checkout -b <本地分支名> #綁定完成
ps:切換分支之前請保證本地的文件已經完全提交且與遠程一致,否則會報錯。
二、鏡像獲取
鏡像的獲取方式有很多種,不一定非要自己從源代碼編譯,你也可以從官網指定的地址去拉去鏡像,或者直接執行 `docker pull` 命令。
如果想用源碼編譯鏡像的話很簡單,分別切換到$fabric、$fabric-ca下執行 ` make docker `
ps:這里友情提示以下,從源碼編譯最好是准備一個梯子,否則你會痛苦不堪,推薦直接拉取編譯好的鏡像。
參考地址:
三、環境搭建
現在開始講最重要的部分,所有服務基於docker多機環境搭建繞不開一個問題:跨主機通信的。根據我在網上搜集來的信息可以將實現跨主機通訊的方法分為以下幾種:
1> 本地共享:最直接的方式就是與主機共享網絡資源,這種方式的弊端也很明顯。
2> 物理橋接:將物理網卡橋接到docker的所依賴的虛擬網橋中,將ip地址限定為物理主機同一網段,這個方式跟1差不多。
3> swarm(docker或第三 提供的docker集成管理項目):簡單來說就是將多主機納入同一個docker manager下,將底層的資源調度分配與客戶端部署隔離,主要是構建docker集群。Fabric社區中有一個kubernetes的討論組,他們現在主要研究方向就是將雲服務器與kubernetes相結合,部署一個“雲區塊鏈”,方便那些中小企業部署區塊鏈方案,但是我個人認為這已經是跑偏了。區塊鏈本身是一個去中心化的技術,如果完全托管到雲上,豈不是一種變相的中心化?畢竟你所有的數據都在雲服務商手中。
4>overlay network: swarm 中也應用到了overlay network 基於的是vxlan技術,就是在主機網絡上在封裝一層虛擬網絡,達到將所有容器納入同一網段的目的。而且它相比於直接的物理橋接有一個好處就是可以根據容器的host name來動態解析路由容器的ip,只要你容器host name不變,我們之間就能互聯,從而實現了ip的動態分配。
其實用第三種方法更方便一些,因為我們要執行docker-compose.yml來部署環境,而在swarm二中可以通過 ‘docker stack deploy -c <compose>.yml <name>'來一鍵完成傻瓜式部署,但是它有一個弊端,容器的到底部署在哪個節點是根據其調度算法來分配的,我們則是想要指定每一個節點安裝的主機。
參考網址:http://www.sdnlab.com/7241.html
綜上所述,我們最后采用了 docker-compose + overlay network 的方式來實現我們想要的分布式部署,我們先看一下 $fabric-sdk-node/test/fixtures目錄下的 docker-compose.yaml
version: '3' services: ca0: image: hyperledger/fabric-ca 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_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/a22daf356b2aab5792ea53e35f66fccef1d7f1aa2b3a2b92dbfbf96a448ea26a_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/a22daf356b2aab5792ea53e35f66fccef1d7f1aa2b3a2b92dbfbf96a448ea26a_sk -b admin:adminpw -d' volumes: - ./channel/crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca_peerOrg1 ca1: image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_CA_NAME=ca-org2 - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org2.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/464d550fe9bf9e7d8976cdf59d1a5d472598f54c058c3546317c5c5fb0ddfd6e_sk ports: - "8054:7054" command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/org2.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/464d550fe9bf9e7d8976cdf59d1a5d472598f54c058c3546317c5c5fb0ddfd6e_sk -b admin:adminpw -d' volumes: - ./channel/crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca_peerOrg2 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=/etc/hyperledger/configtx/twoorgs.genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer - ORDERER_GENERAL_TLS_ENABLED=true - ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/msp/orderer/keystore/e8a4fdaacf1ef1d925686f19f56eb558b6c71f0116d85916299fc1368de2d58a_sk - ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/msp/orderer/signcerts/orderer.example.com-cert.pem - ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/msp/orderer/cacerts/example.com-cert.pem, /etc/hyperledger/msp/peerOrg1/cacerts/org1.example.com-cert.pem, /etc/hyperledger/msp/peerOrg2/cacerts/org2.example.com-cert.pem] working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer command: orderer ports: - 7050:7050 dns: - 8.8.8.8 - 8.8.4.4 volumes: - ./channel:/etc/hyperledger/configtx - ./channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/msp/orderer - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peerOrg1 - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peerOrg2 peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer environment: - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_PEER_ID=peer0.org1.example.com - CORE_LOGGING_PEER=debug - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/msp/peer/keystore/ecd9f80eb183352d5d4176eeb692e30bbfba4c38813ff9a0b6b799b546dda1d8_sk - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/msp/peer/signcerts/peer0.org1.example.com-cert.pem - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/msp/peer/cacerts/org1.example.com-cert.pem # # 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=fixtures_default - GOPATH=/tmp/gopath working_dir: /opt/gopath/src/github.com/hyperledger/fabric command: peer node start --peer-defaultchain=false ports: - 7051:7051 - 7053:7053 volumes: - ./src/github.com:/tmp/gopath/src/github.com - /var/run/:/host/var/run/ - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peer depends_on: - orderer.example.com peer0.org2.example.com: container_name: peer0.org2.example.com image: hyperledger/fabric-peer environment: - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_PEER_ID=peer0.org2.example.com - CORE_PEER_LOCALMSPID=Org2MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_ADDRESS=peer0.org2.example.com:7051 - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/msp/peer/keystore/81c71fd393054571c8d789f302a10390e0e83eb079b02a26a162ee26f02ff796_sk - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/msp/peer/signcerts/peer0.org2.example.com-cert.pem - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/msp/peer/cacerts/org2.example.com-cert.pem # # 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=fixtures_default - GOPATH=/tmp/gopath working_dir: /opt/gopath/src/github.com/hyperledger/fabric command: peer node start --peer-defaultchain=false ports: - 8051:7051 - 8053:7053 volumes: - ./src/github.com:/tmp/gopath/src/github.com - /var/run/:/host/var/run/ - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peer depends_on: - orderer.example.com couchdb: container_name: couchdb image: hyperledger/fabric-couchdb ports: - 5984:5984 environment: DB_URL: http://localhost:5984/member_db
它所部署Fabric 網絡是一個單orderer的solo網絡,結構如下:
OrdererMsp |----- orderer.example.com (共識服務節點) Org1MSP |-----peer0.org1.example.com (peer節點、Anchor節點) |-----ca0(ca服務) Org2MSP |-----peer0.org2.example.com |-----ca1 DB |---- couchdb(總帳存儲)
為了能分布式部署其中有一些環境變量參數是需要我們進行修改的,至於怎么修改我們等下再說,先說一下構建overlay網絡環境,我主要參考了Tony大神的一篇博客,只是因為環境不同有一些改動。
參考網址: http://tonybai.com/2016/02/15/understanding-docker-multi-host-networking/
1、創建consul 服務
考慮到kv store在本文並非關鍵,僅作跨多主機容器網絡創建啟動的前提條件之用,因此僅用包含一個server節點的”cluster”。
參照拓撲圖,我們在上啟動一個consul,關於consul集群以及服務注冊、服務發現等細節可以參考我之前的一 篇文章:
$consul agent -server -bootstrap-expect 1 -data-dir ./data -node=master -bind=10.10.126.101 -client=0.0.0.0 &
ps :這個consul解壓出來之后就是一個二進制的執行文件,我們可以直接把它添加到$PATH路徑下面
2、修改Docker Daemon DOCKER_OPTS參數
前面提到過,通過Docker 1.9創建跨多主機容器網絡需要重新配置每個主機節點上的Docker Daemon的啟動參數:
ubuntu系統這個配置在/lib/systemd/system/docker.service 下: ExecStart=/usr/bin/dockerd -H fd://
修改為ExecStart=/usr/bin/dockerd -H fd:// --dns 8.8.8.8 --dns 8.8.4.4 -H tcp://0.0.0.0:2375 --cluster-advertise <物理網卡的名字,不一定是eth0>:2375 --cluster-store consul://10.10.126.101:8500/network --storage-driver=devicemapper
ps:注意有可能啟動服務時候會失敗,不要慌。這是因為我們平時默認--storage-driver使用的是aufs模式,當切換到devicemapper模式時可能會發生錯誤。
code bash:
sudo /usr/bin/dockerd --storage-driver=devicemapper #這時會顯示錯誤的具體信息,其中大概的意思是不能rename一個文件,我們就假設它為 xxx
sudo apt-get install dmsteup
sudo dmsteup rm xxx #執行這個命令之前一定要備份鏡像,因為這個命令執行完之后你會發現之前的鏡像都不見了
或者
修改 ExecStart=/usr/bin/dockerd -H fd:// --dns 8.8.8.8 --dns 8.8.4.4 -H tcp://0.0.0.0:2375 --cluster-advertise <物理網卡的名字,不一定是eth0>:2375 --cluster-store consul://10.10.126.101:8500/network --storage-driver=aufs
aufs 這時一個默認的docker的 --storage-driver,主要是用於docker容器和主機共享文件卷,它和devicemapper的具體區別還有帶查證,但現在的Linux系統大部分支持aufs,所以沒有切換的必要了。
這里多說幾句:
-H(或–host)配置的是Docker client(包括本地和遠程的client)與Docker Daemon的通信媒介,也是Docker REST api的服務端口。默認是/var/run/docker.sock(僅用於本地),當然也可以通過tcp協議通信以方便遠程Client訪問,就像上面 配置的那樣。非加密網通信采用2375端口,而TLS加密連接則用2376端口。這兩個端口已經申請在IANA注冊並獲批,變成了知名端口。-H可以配置多個,就像上面配置的那樣。 unix socket便於本地docker client訪問本地docker daemon;tcp端口則用於遠程client訪問。這樣一來:docker pull ubuntu,走docker.sock;而docker -H 10.10.126.101:2375 pull ubuntu則走tcp socket。
–cluster-advertise 配置的是本Docker Daemon實例在cluster中的地址;
–cluster-store配置的是Cluster的分布式KV store的訪問地址;
如果你之前手工修改過iptables的規則,建議重啟Docker Daemon之前清理一下iptables規則:sudo iptables -t nat -F, sudo iptables -t filter -F等。
ps:為了圖方便我直接把防火牆關了,另外我有一篇博客也說過直接修改/etc/default/docker
不會生效。
3、啟動各節點上的Docker Daemon
以10.10.126.101為例:
$ sudo service docker start
$ ps -ef|grep docker
root 2069 1 0 Feb02 ? 00:01:41 /usr/bin/docker -d --dns 8.8.8.8 --dns 8.8.4.4 --storage-driver=devicemapper -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-advertise eth0:2375 --cluster-store consul://10.10.126.101:8500/network
啟動后iptables的nat, filter規則與單機Docker網絡初始情況並無二致。
101節點上初始網絡driver類型:
$docker network ls
NETWORK ID NAME DRIVER
47e57d6fdfe8 bridge bridge
7c5715710e34 none null
19cc2d0d76f7 host host
4、創建overlay網絡net1和net2
在101節點上,創建net1:
$ sudo docker network create -d overlay net1
在71節點上,創建net2:
$ sudo docker network create -d overlay net2
之后無論在71節點還是101節點,我們查看當前網絡以及驅動類型都是如下結果:
$ docker network ls
NETWORK ID NAME DRIVER
283b96845cbe net2 overlay
da3d1b5fcb8e net1 overlay
00733ecf5065 bridge bridge
71f3634bf562 none null
7ff8b1007c09 host host
此時,iptables規則也並無變化。
5、啟動兩個overlay net下的containers
我們分別在net1和net2下面啟動兩個container,每個節點上各種net1和net2的container各一個:
101:
sudo docker run -itd --name net1c1 --net net1 ubuntu:14.04
sudo docker run -itd --name net2c1 --net net2 ubuntu:14.04
71:
sudo docker run -itd --name net1c2 --net net1 ubuntu:14.04
sudo docker run -itd --name net2c2 --net net2 ubuntu:14.04
啟動后,我們就得到如下網絡信息(容器的ip地址可能與前面拓撲圖中的不一致,每次容器啟動ip地址都可能變化):
net1:
net1c1 - 10.0.0.7
net1c2 - 10.0.0.5
net2:
net2c1 - 10.0.0.4
net2c2 - 10.0.0.6
6、容器連通性
在net1c1中,我們來看看其到net1和net2的連通性:
root@021f14bf3924:/# ping net1c2
PING 10.0.0.5 (10.0.0.5) 56(84) bytes of data.
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=0.670 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=0.387 ms
^C
--- 10.0.0.5 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.387/0.528/0.670/0.143 ms
root@021f14bf3924:/# ping 10.0.0.4
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
^C
--- 10.0.0.4 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1008ms
可見,net1中的容器是互通的,但net1和net2這兩個overlay net之間是隔離的。
ps:這就是我們前面說的,overlay網絡同網段下運行容器可以根據容器的host name 路由到目的容器.
如果你一路執行到這里說明你的overlay環境已經搭好了,那么我們說一下docker-compose.yaml應該如何修改:
1>將Fabric拆分為兩個部分:
host1 (104)包含order、Org1、couchdb
host2 (121) 包含Org2
所以我將docker-compose.yaml也拆成了兩個部分。
2>網絡的設定:
我們之前會新建兩個overlay網絡net1、net2,為了省事我們就直接用net1作為指定的網絡。如果我們不指定網絡,docker-compose會默認生成一個brige網絡<($dirname)_default>,這樣是無法聯通的。
3>參數修改:
CORE_VM_ENDPOINT= tcp://ip:port
fabric目前沒有運行chain code 的虛擬機,當部署chain code時它會自動構建一個docker鏡像,然后再以運行容器的方式來執行chain code。這個環境變量的作用救是在部署chain code時候,指定peer與docker后台服務通信地址.
CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=net1
指定peer的network
4>示例
host(104) :docer-compose-0.yaml
version: '3' services: ca0: container_name: ca_peerOrg1 image: hyperledger/fabric-ca 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_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/a22daf356b2aab5792ea53e35f66fccef1d7f1aa2b3a2b92dbfbf96a448ea26a_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/a22daf356b2aab5792ea53e35f66fccef1d7f1aa2b3a2b92dbfbf96a448ea26a_sk -b admin:adminpw -d' volumes: - ./channel/crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config networks: - net1 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=/etc/hyperledger/configtx/twoorgs.genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer - ORDERER_GENERAL_TLS_ENABLED=true - ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/msp/orderer/keystore/e8a4fdaacf1ef1d925686f19f56eb558b6c71f0116d85916299fc1368de2d58a_sk - ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/msp/orderer/signcerts/orderer.example.com-cert.pem - ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/msp/orderer/cacerts/example.com-cert.pem, /etc/hyperledger/msp/peerOrg1/cacerts/org1.example.com-cert.pem, /etc/hyperledger/msp/peerOrg2/cacerts/org2.example.com-cert.pem] working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer command: orderer ports: - 7050:7050 volumes: - ./channel:/etc/hyperledger/configtx - ./channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/msp/orderer - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peerOrg1 - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peerOrg2 networks: - net1 peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer environment: - CORE_VM_ENDPOINT=tcp://192.168.1.104:2375 - CORE_PEER_ID=peer0.org1.example.com - CORE_LOGGING_PEER=debug - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/msp/peer/keystore/ecd9f80eb183352d5d4176eeb692e30bbfba4c38813ff9a0b6b799b546dda1d8_sk - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/msp/peer/signcerts/peer0.org1.example.com-cert.pem - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/msp/peer/cacerts/org1.example.com-cert.pem # # 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=net1 working_dir: /opt/gopath/src/github.com/hyperledger/fabric command: peer node start --peer-defaultchain=false ports: - 7051:7051 - 7053:7053 volumes: - /var/run/:/host/var/run/ - ./channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peer depends_on: - orderer.example.com networks: - net1 couchdb: container_name: couchdb image: hyperledger/fabric-couchdb ports: - 5984:5984 environment: DB_URL: http://localhost:5984/member_db networks: - net1 networks: net1: external: true #此網絡由外部引用,無需創建
host(121) docker-compose-1.yaml
version: '3' services: ca1: image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_CA_NAME=ca-org2 - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org2.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/464d550fe9bf9e7d8976cdf59d1a5d472598f54c058c3546317c5c5fb0ddfd6e_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/org2.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/464d550fe9bf9e7d8976cdf59d1a5d472598f54c058c3546317c5c5fb0ddfd6e_sk -b admin:adminpw -d' volumes: - ./channel/crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca_peerOrg2 networks: - net1 peer0.org2.example.com: container_name: peer0.org2.example.com image: hyperledger/fabric-peer environment: - CORE_VM_ENDPOINT=tcp://192.168.1.104:2375 - CORE_PEER_ID=peer0.org2.example.com - CORE_PEER_LOCALMSPID=Org2MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_ADDRESS=peer0.org2.example.com:7051 - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/msp/peer/keystore/81c71fd393054571c8d789f302a10390e0e83eb079b02a26a162ee26f02ff796_sk - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/msp/peer/signcerts/peer0.org2.example.com-cert.pem - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/msp/peer/cacerts/org2.example.com-cert.pem # # 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=net1 - GOPATH=/tmp/gopath working_dir: /opt/gopath/src/github.com/hyperledger/fabric command: peer node start --peer-defaultchain=false ports: - 7051:7051 - 7053:7053 volumes: - ./src/github.com:/tmp/gopath/src/github.com - /var/run/:/host/var/run/ - ./channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peer - ./channel:/etc/hyperledger/configtx networks: - net1 networks: net1: external: true
運行的時候先運行docker-compose-0.yaml:
docker-compose -f docer-compose-0.yaml up --force-recreate
然后在另一台主機運行docker-compose-1.yaml
docker-compose -f docer-compose-1.yaml up --force-recreate
運行后執行docker命令進入容器的bash界面
docker exec -it <container> bash
ping 另一個主機上的容器驗證是否聯通,fabric的鏡像里面是沒有ping的 我們需要自己手動安裝
apt-get update
apt-get install inetutils-ping
如果ping通了那么恭喜你,你已經完成了一半工程了,如果發現無法ping通也不要慌張,先關閉清理當前的容器 :
docker-compose -f xx.yaml down
然后再清理一下沒有被使用的docker網絡(此時不要有docker 容器運行):
docker network prune -f
清理之后重啟fabric網絡再試試。