What's the correct connection profile for accessing hyperledger fabric v2.x deployed on k8s

9/10/2021

I have my hyperledger fabric blockchain deployed on k8s in the namespace: hlf-blockchain and my client app is deployed is in another namespace: hlf-app

The cpp-profile template is below. url-> grpcs://<service-name>.<namespace>:<port> which enables cross namespace communication.

{
    "name": "test-network",
    "version": "1.0.0",
    "client": {
        "organization": "MyOrg",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "10000"
                }
            }
        }
    },
    "organizations": {
        "TboxOrg": {
            "mspid": "MyOrg",
            "peers": [
                "peer0",
                "peer1",
                "peer2"
                ],
            "certificateAuthorities": [
                "ca-myorg"
            ]
        }
    },
    "peers": {
        "peer0": {
            "url": "grpcs://peer0.hlf-blockchain:${P0PORT}",
            "tlsCACerts": {
                "pem": "${PEERPEM}"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0",
                "hostnameOverride": "peer0",
                "request-timeout": 10000,
                "grpc.keepalive_time_ms": 60000
            }
        },
        "peer1": {
            "url": "grpcs://peer1.hlf-blockchain:${P1PORT}",
            "tlsCACerts": {
                "pem": "${PEERPEM}"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer1",
                "hostnameOverride": "peer1",
                "request-timeout": 10000,
                "grpc.keepalive_time_ms": 60000
            }
        },
        "peer2-tbox": {
            "url": "grpcs://peer2.hlf-blockchain:${P2PORT}",
            "tlsCACerts": {
                "pem": "${PEERPEM}"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer2",
                "hostnameOverride": "peer2",
                "request-timeout": 10000,
                "grpc.keepalive_time_ms": 60000
            }
        }
    },
    "certificateAuthorities": {
        "ca-tboxorg": {
            "url": "https://ca-myorg.hlf-blockchain:${CAPORT}",
            "caName": "ca-myorg",
            "tlsCACerts": {
                "pem": ["${CAPEM}"]
            },
            "httpOptions": {
                "verify": false
            }
        }
    }
}

From my client-app using fabrid-sdk-go I am able to connect to the network using the gateway. While invoking the chaincode I am getting the following error:

Endorser Client Status Code: (2) CONNECTION_FAILED. Description: dialing connection on target [peer0:7051]: connection is in TRANSIENT_FAILURE\nTransaction processing for endorser

I am able to invoke the transactions using cli command from the same namespace: hfl-blockchain

My peer service configuration:

kind: Service
apiVersion: v1
metadata:
  name: peer0
  labels:
    app: peer0
spec:
  selector:
    name: peer0
  type: ClusterIP
  ports:
    - name: grpc
      port: 7051
      protocol: TCP
    - name: event
      port: 7061
      protocol: TCP
    - name: couchdb
      port: 5984
      protocol: TCP

I believe this error is due to communication error between different namespace, which the client apps gets from the cpp-profile.

What's the correct way to configure the peer service or the cpp connection profile?

-- Niraj Kumar
blockchain
hyperledger
hyperledger-fabric
kubernetes

2 Answers

9/13/2021

Please, feel free to correct me on this.

So the problem lies with the discovery service. When the client tries to establish the connection to peer through gateway (which is embedded in the peer) in order to invoke transaction, the client receives the network topology- through the Discovery service which describes the no. of endorser peers, their url and other metadata.

This metadata is built from the configtx/core.yaml where we specify the peers and orderer (including their host and port).

Since my client app is in different namespace than the hyperledger fabric blockchain, the client needs the url in grpcs://<host-name>.<namespace>:<port> but my configuration in the configtx/core.yaml were <host-name>:<port> which works if the client app is also in the same namespace as the blockchain nodes.

Also, one might think to name the service as peer0-myorg.<namespace> but k8s does not allows . in the name.

To fix my issue, I just moved the client app in the same namespace as that of blockchain network. Depending on your use-case if you're using DNS name for the services then you might not face this.

-- Niraj Kumar
Source: StackOverflow

9/14/2021

You are correct, the discovery service is returning network URLs that are unreachable from the hlf-blockchain namespace.

It is possible to run a Gateway client in a different namespace from the Fabric network. If you are using Kube DNS, each of the fabric nodes can be referenced with a fully qualified host name <service-name>.<namespace>.svc.cluster.local.

In order to connect a gateway client across namespaces, you will need to introduce the <namespace>.svc.cluster.local Fully Qualified Domain Name to the fabric URLs returned by discovery:

  • In your TLS CA enrollments, make sure that the certificate signing requests include a valid Subject Alternate Name with the FQDN. For example, if your peer0 TLS certificate is only valid for the host peer0, then the grpcs:// connection will be rejected in the TLS handshake when connecting to grpcs://peer0.hlf-blockchain.svc.cluster.local.

  • In the Gateway Client Connection Profile, use the FQDN when connecting to the discovery peers. In addition to the peer url attribute, make sure to address host names in the grpcOptions stanzas.

  • Discovery will return the peer host names as specified in the core.yaml peer.gossip.externalendpoint (CORE_PEER_GOSSIP_EXTERNALENDPOINT env) parameter. Make sure that this specifies the FQDN for all peers visible to discovery.

  • Discovery will return the orderer host names as specified in the configtx.yaml organization OrdererEndpoints stanza. Make sure that these URLs specify the FQDN for all orderers.

Regarding the general networking, make sure to double-check that the gateway client application has visibility and a network route to the pods running fabric services in a different namespace. Depending on your Calico configuration and Kube permissions, it's possible that traffic is getting blocked before it ever reaches the Fabric services.

-- Josh
Source: StackOverflow