0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Hyperledger Fabric Multi Host 対応(1)

Last updated at Posted at 2020-02-29

Hyperledger Fabric のマルチホスト構成について、実装方法の検討とFabcar を使用した実装例を考えてみる。

Hyperledger Fabric のマルチホスト構成の検討

Hyperledger Fabric のマルチホスト構成については、Docker swarm を使用する方法が、よく紹介されている。
swarm を使用すると、Docker 内の名前解決などが解決できるため容易に構築ができる反面、Docker network を共有することになり、企業を跨いだ環境を考えた場合、セキュリティ上の問題が出る可能性があり、現実的ではない。

本ドキュメントでは、Hyperledger のサンプルである fabric-sample の fabcar をベースに swarm を使用せずにマルチホスト化する。

swarm を使用しない場合の課題

Docker swarm を使用しない場合は、ホスト側のIPを使用して通信することになる。そのため、以下のような課題がある。

コンテナ名の名前解決

名前解決が必要な箇所は2つある。
Docker内と、ホストOS での名前解決が必要。

Docker内の名前解決

Dockerコンテナ上では、Docker networkがコンテナ名で名前解決を行ってくれるが、Docker networkが分離された場合、名前解決を行うことができない。
Extra-hosts を指定することで、コンテナ内のhostsの設定を行うことができ、静的に名前解決を行うことができる。
今回は、Extra-hosts で対応する。

Host os上からの名前解決

javascript からのアクセスなど、ホストOSからのアクセスの場合は、ホストOK 上からのコンテナ名の名前解決が必要となる。fabric-sample は、同一ホスト上で実行することを想定しているので、名前解決は行わず localhost アクセスするで対応している。
ccp-template.json (.yaml) で、javascript からの接続先などを取得しているが、以下のように、grpc の接続先を'localhost' としている。

ccp-template.json の peer部分の抜粋

    "peers": {
        "peer0.org${ORG}.example.com": {
            "url": "grpcs://localhost:${P0PORT}",
            "tlsCACerts": {
                "pem": "${PEERPEM}"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org${ORG}.example.com",
                "hostnameOverride": "peer0.org${ORG}.example.com"
            }
        },

マルチホストの場合は、localhost では他のホスト上のコンテナにもアクセスする必要があり、宛先を指定する必要がある。
直接 IPアドレスを記載することも可能であるが、IPの変更への対応が困難になるので、以下のように コンテナ名とし、名前解決を行うようにする。

    "peers": {
        "peer0.org${ORG}.example.com": {
            "url": "grpcs://peer0.org${ORG}.example.com:${P0PORT}",
            "tlsCACerts": {
                "pem": "${PEERPEM}"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org${ORG}.example.com",
                "hostnameOverride": "peer0.org${ORG}.example.com"
            }
        },

コンテナ名の名前解決については、DNS を使用するか hosts に記載する方法があるが、今回は、以下のように hosts で対応する。

$ sudo vi /etc/hosts

以下のように、ノードを配置したホストのIPを設定する。
※ ordererと、org1 は、192.168.1.100 に、org2 を192.168.1.101 に配置した例

192.168.1.100   orderer.example.com
192.168.1.100   ca.org1.example.com
192.168.1.100   peer0.org1.example.com
192.168.1.100   peer1.org1.example.com
192.168.1.101   ca.org2.example.com
192.168.1.101   peer0.org2.example.com
192.168.1.101   peer1.org2.example.com

あと、javascript 内の 'gateway.connect' にも修正が必要。
現状は、以下のように設定されている。


        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });

asLocalhost: true だと、他のホスト側の参照がlocalhost に置き換えられてしまい以下のようなエラーが出ます。

2020-02-09T08:45:59.979Z - error: [Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:10051
2020-02-09T08:45:59.981Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G1:0 - endorsement failed - Error: Failed to connect before the deadline URL:grpcs://localhost:10051
2020-02-09T08:46:02.981Z - error: [Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:9051
2020-02-09T08:46:02.982Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G1:0 - endorsement failed - Error: Failed to connect before the deadline URL:grpcs://localhost:9051
2020-02-09T08:46:02.983Z - error: [DiscoveryEndorsementHandler]: _endorse - endorsement failed::Error: Endorsement has failed
    at DiscoveryEndorsementHandler._endorse (/home/fukata/fabric-samples/fabcar/javascript/node_modules/fabric-client/lib/impl/DiscoveryEndorsementHandler.js:185:19)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:189:7)
Failed to submit transaction: Error: Endorsement has failed

そのため、以下のように、asLocalhost: false に修正する必要があります。

        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: false } });

各peerやordererの証明書ファイルの配布

fabric-sample では、cryptogen で生成した全コンテナの証明書を、ホスト上のフォルダに格納し各コンテナが参照するようになっている。
マルチホストの場合は、各ホストで生成して公開鍵を他のホストに配るなどの対応が必要となる。
今回は、1つのホスト上で作成した証明書を他のホストに配るようにする。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?