diff --git a/docs/TEST_NETWORK_K8S.md b/docs/TEST_NETWORK_K8S.md deleted file mode 100644 index 21304d7..0000000 --- a/docs/TEST_NETWORK_K8S.md +++ /dev/null @@ -1,117 +0,0 @@ -# Kubernetes Test Network - -The [Kube Test Network](https://github.com/hyperledger/fabric-samples/tree/main/test-network-k8s) includes support for the k8s builder by setting the `TEST_NETWORK_CHAINCODE_BUILDER="k8s"` environment variable. - -## Create a Sample Network - -In the `fabric-samples/test-network-k8s` directory: - -```shell -export PATH=$PWD:$PWD/bin:$PATH - -export TEST_NETWORK_K8S_CHAINCODE_BUILDER_VERSION="v0.6.0" # (optional - defaults to v0.4.0) -export TEST_NETWORK_CHAINCODE_BUILDER="k8s" - -network kind -network cluster init -network up -network channel create -``` - -(Check / follow the detailed log file for errors and progress at `network-debug.log`. E.g. in a separate shell:) -```shell -tail -f network-debug.log -``` - -## Set the `peer` CLI environment - -Make sure the `build` directory exists -- this will be created by `network channel create`. - -Set the `peer` command environment, e.g. for org1, peer1: - -```shell -export FABRIC_CFG_PATH=${PWD}/config/org1 -export CORE_PEER_ADDRESS=org1-peer1.${TEST_NETWORK_DOMAIN:-vcap.me}:443 -export CORE_PEER_MSPCONFIGPATH=${PWD}/build/enrollments/org1/users/org1admin/msp -export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/build/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem -``` - -## Download a chaincode package - -The [sample contracts for Go, Java, and Node.js](samples/README.md) publish a Docker image which the k8s builder can use _and_ a chaincode package file which can be used with the `peer lifecycle chaincode install` command. -Use of a pre-generated chaincode package .tgz greatly simplifies the deployment, aligning with standard industry practices for CI/CD and git-ops workflows. - -Download a sample chaincode package, e.g. for the Go contract: - -```shell -curl -fsSL \ - https://github.com/hyperledger-labs/fabric-builder-k8s/releases/download/v0.7.2/go-contract-v0.7.2.tgz \ - -o go-contract-v0.7.2.tgz -``` - -## Deploying chaincode - -Deploy the chaincode package as usual, starting by installing the k8s chaincode package. - -```shell -peer lifecycle chaincode install go-contract-v0.7.2.tgz -``` - -Export a `PACKAGE_ID` environment variable for use in the following commands. - -```shell -export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid go-contract-v0.7.2.tgz) && echo $PACKAGE_ID -``` - -Note: the `PACKAGE_ID` must match the chaincode code package identifier shown by the `peer lifecycle chaincode install` command. - -Approve the chaincode: - -```shell -peer lifecycle \ - chaincode approveformyorg \ - --channelID mychannel \ - --name sample-contract \ - --version 1 \ - --package-id ${PACKAGE_ID} \ - --sequence 1 \ - --orderer org0-orderer1.${TEST_NETWORK_DOMAIN:-vcap.me}:443 \ - --tls --cafile ${PWD}/build/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem -``` - -Commit the chaincode. - -```shell -peer lifecycle \ - chaincode commit \ - --channelID mychannel \ - --name sample-contract \ - --version 1 \ - --sequence 1 \ - --orderer org0-orderer1.${TEST_NETWORK_DOMAIN:-vcap.me}:443 \ - --tls --cafile ${PWD}/build/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem -``` - -Inspect chaincode pods. - -```shell -kubectl -n test-network describe pods -l app.kubernetes.io/created-by=fabric-builder-k8s -``` - -## Running transactions - -Query the chaincode metadata! - -```shell -network chaincode query sample-contract '{"Args":["org.hyperledger.fabric:GetMetadata"]}' -``` - -## Reset - -Invariably, something in the recipe above will go awry. Look for additional diagnostics in `network-debug.log` and... - -Reset the stage with: - -```shell -network down && network up && network channel create -``` diff --git a/docs/TEST_NETWORK_NANO.md b/docs/TEST_NETWORK_NANO.md deleted file mode 100644 index 9df4cd8..0000000 --- a/docs/TEST_NETWORK_NANO.md +++ /dev/null @@ -1,84 +0,0 @@ -# Nano Test Network - -The k8s builder can be used with the [nano test network](https://github.com/hyperledger/fabric-samples/tree/main/test-network-nano-bash) by following the instructions below. - -## Download builder binaries - -Download the latest builder binaries from the [releases page](https://github.com/hyperledger-labs/fabric-builder-k8s/releases) and extract them to a `k8s_builder/bin` directory in your home directory. - -## Configure builder - -After installing the nano test network prereqs, the `fabric-samples/config/core.yaml` file needs to be updated with the k8s builder configuration. - -``` - externalBuilders: - - name: k8s_builder - path: /k8s_builder - propagateEnvironment: - - CORE_PEER_ID - - KUBECONFIG_PATH -``` - -You can use [yq](https://mikefarah.gitbook.io/yq/) to update the `fabric-samples/config/core.yaml` files. -Make sure you are in the `fabric-samples` directory before running the following commands. - -```shell -FABRIC_K8S_BUILDER_PATH=${HOME}/k8s_builder yq -i '.chaincode.externalBuilders += { "name": "k8s_builder", "path": "${FABRIC_K8S_BUILDER_PATH}" | envsubst(ne), "propagateEnvironment": [ "CORE_PEER_ID", "KUBECONFIG_PATH" ] }' config/core.yaml -``` - -## Kubernetes configuration - -The k8s builder needs a kubeconfig file to access a Kubernetes cluster to deploy chaincode. Make sure the `KUBECONFIG_PATH` environment variable is available on every peer the builder is configured on. - -```shell -export KUBECONFIG_PATH=$HOME/.kube/config -``` - -## Downloading chaincode package - -The [sample contracts for Go, Java, and Node.js](samples/README.md) publish a Docker image which the k8s builder can use _and_ a chaincode package file which can be used with the `peer lifecycle chaincode install` command. -Use of a pre-generated chaincode package .tgz greatly simplifies the deployment, aligning with standard industry practices for CI/CD and git-ops workflows. - -Download a sample chaincode package, e.g. for the Go contract: - -```shell -curl -fsSL \ - https://github.com/hyperledger-labs/fabric-builder-k8s/releases/download/v0.7.2/go-contract-v0.7.2.tgz \ - -o go-contract-v0.7.2.tgz -``` - -## Deploying chaincode - -Deploy the chaincode package as usual, starting by installing the k8s chaincode package. - -```shell -peer lifecycle chaincode install go-contract-v0.7.2.tgz -``` - -Export a `PACKAGE_ID` environment variable for use in the following commands. - -```shell -export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid go-contract-v0.7.2.tgz) && echo $PACKAGE_ID -``` - -Note: the `PACKAGE_ID` must match the chaincode code package identifier shown by the `peer lifecycle chaincode install` command. - -Approve the chaincode. - -```shell -peer lifecycle chaincode approveformyorg -o 127.0.0.1:6050 --channelID mychannel --name sample-contract --version 1 --package-id $PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt -``` - -Commit the chaincode. - -```shell -peer lifecycle chaincode commit -o 127.0.0.1:6050 --channelID mychannel --name sample-contract --version 1 --sequence 1 --tls --cafile "${PWD}"/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt -``` - -## Running transactions - -Query the chaincode metadata! - -```shell -peer chaincode query -C mychannel -n sample-contract -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' -``` diff --git a/docs/about/community.md b/docs/about/community.md new file mode 100644 index 0000000..50e6c89 --- /dev/null +++ b/docs/about/community.md @@ -0,0 +1,3 @@ +# Community + +You can find community discussion related to the Kubernetes Builder on the [#fabric-kubernetes](https://discord.com/channels/905194001349627914/945796983795384331) channel on Hyperledger Discord ([invite link](https://discord.gg/hyperledger)). diff --git a/docs/about/objectives.md b/docs/about/objectives.md new file mode 100644 index 0000000..a52908e --- /dev/null +++ b/docs/about/objectives.md @@ -0,0 +1,21 @@ +# Objectives + +The aim is for the k8s builder to work as closely as possible with the existing [Fabric chaincode lifecycle](https://hyperledger-fabric.readthedocs.io/en/latest/chaincode_lifecycle.html), making sensible compromises for deploying chaincode on Kubernetes within those limitations. +(The assumption being that there are more people with Kubernetes skills than are familiar with the inner workings of Fabric!) + +The two key principles are: + +1. **The contents of the chaincode package must uniquely identify the chaincode functions executed on the ledger:** + In the case of the k8s builder the chaincode source code is not actually inside the package. + In order not to break the Fabric chaincode lifecycle, the chaincode image must be specified using an immutable `@digest`, not `:label` which can be altered post commit. + See [Pull an image by digest (immutable identifier)](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier) for more details. + +2. **The Fabric peer manages the chaincode process, not Kubernetes:** + Running the chaincode in server mode, i.e. allowing the peer to initiate the gRPC connection, would make it possible to leave Kubernetes to manage the chaincode process by creating a chaincode deployment. + Unfortunately due to limitations in Fabric's builder and launcher implementation, that is not possible and the peer expects to control the chaincode process. + +## Status + +The k8s builder is [close to a version 1 release](https://github.com/hyperledger-labs/fabric-builder-k8s/milestone/1) and has been tested in a number of Kubernetes environments, deployment platforms, and provides semantic-revision aware [release tags](https://github.com/hyperledger-labs/fabric-builder-k8s/tags) for the external builder binaries. + +The current status should be considered as STABLE and any bugs or enhancements delivered as GitHub Issues in conjunction with community PRs. diff --git a/docs/assets/Hyperledger_Fabric.svg b/docs/assets/Hyperledger_Fabric.svg new file mode 100644 index 0000000..3c7c3da --- /dev/null +++ b/docs/assets/Hyperledger_Fabric.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/Hyperledger_Fabric_Icon.svg b/docs/assets/Hyperledger_Fabric_Icon.svg new file mode 100644 index 0000000..69d8da5 --- /dev/null +++ b/docs/assets/Hyperledger_Fabric_Icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/assets/Hyperledger_Fabric_White.svg b/docs/assets/Hyperledger_Fabric_White.svg new file mode 100644 index 0000000..3b53a16 --- /dev/null +++ b/docs/assets/Hyperledger_Fabric_White.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/content/assets/project-icon.png b/docs/assets/project-icon.png similarity index 100% rename from docs/content/assets/project-icon.png rename to docs/assets/project-icon.png diff --git a/docs/content/assets/project-logo.png b/docs/assets/project-logo.png similarity index 100% rename from docs/content/assets/project-logo.png rename to docs/assets/project-logo.png diff --git a/docs/concepts/chaincode-builder.md b/docs/concepts/chaincode-builder.md new file mode 100644 index 0000000..abcd3b0 --- /dev/null +++ b/docs/concepts/chaincode-builder.md @@ -0,0 +1,10 @@ +# Chaincode builder + +See [External Builders and Launchers](https://hyperledger-fabric.readthedocs.io/en/latest/cc_launcher.html) for details of Hyperledger Fabric builders. + +| Script | Description | +| ------- | ----------------------------------------------------------------------------------------------------------------- | +| detect | Detects chaincode packages with a type of `k8s` | +| build | No-op (a chaincode image must be built and published to a container registry before it can be deployed to Fabric) | +| release | No-op | +| run | Starts a Kubernetes pod using the chaincode image identified by an immutable digest | diff --git a/docs/concepts/chaincode-image.md b/docs/concepts/chaincode-image.md new file mode 100644 index 0000000..a09d68a --- /dev/null +++ b/docs/concepts/chaincode-image.md @@ -0,0 +1,18 @@ +# Chaincode image + +Unlike the traditional chaincode language support for Go, Java, and Node.js, the k8s builder *does not* build a chaincode Docker image using Docker-in-Docker. +Instead, a chaincode Docker image must be built and published before it can be used with the k8s builder. + +The chaincode will have access to the following environment variables: + +- CORE_CHAINCODE_ID_NAME +- CORE_PEER_ADDRESS +- CORE_PEER_TLS_ENABLED +- CORE_PEER_TLS_ROOTCERT_FILE +- CORE_TLS_CLIENT_KEY_PATH +- CORE_TLS_CLIENT_CERT_PATH +- CORE_TLS_CLIENT_KEY_FILE +- CORE_TLS_CLIENT_CERT_FILE +- CORE_PEER_LOCALMSPID + +See the [sample contracts for Go, Java, and Node.js](https://github.com/hyperledger-labs/fabric-builder-k8s/tree/main/samples) for basic docker images which will work with the k8s builder. diff --git a/docs/concepts/chaincode-package.md b/docs/concepts/chaincode-package.md new file mode 100644 index 0000000..581620e --- /dev/null +++ b/docs/concepts/chaincode-package.md @@ -0,0 +1,77 @@ +# Chaincode package + +The k8s chaincode package file, which is installed by the `peer lifecycle chaincode install` command, must contain the Docker image name and digest of the chaincode being deployed. + +[Fabric chaincode packages](https://hyperledger-fabric.readthedocs.io/en/latest/cc_launcher.html#chaincode-packages) are `.tgz` files which contain two files: + +- `metadata.json` - the chaincode label and type +- `code.tar.gz` - source artifacts for the chaincode + +To create a k8s chaincode package file, start by creating an `image.json` file. +For example, + +```shell +cat << IMAGEJSON-EOF > image.json +{ + "name": "ghcr.io/hyperledger-labs/go-contract", + "digest": "sha256:802c336235cc1e7347e2da36c73fa2e4b6437cfc6f52872674d1e23f23bba63b" +} +IMAGEJSON-EOF +``` + +Note: the k8s chaincode package file uses digests because these are immutable, unlike tags. +The docker inspect command can be used to find the digest if required. + +``` +docker pull ghcr.io/hyperledger-labs/go-contract:v0.7.2 +docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/hyperledger-labs/go-contract:v0.7.2 | cut -d'@' -f2 +``` + +Create a `code.tar.gz` archive containing the `image.json` file. + +```shell +tar -czf code.tar.gz image.json +``` + +Create a `metadata.json` file for the chaincode package. +For example, + +```shell +cat << METADATAJSON-EOF > metadata.json +{ + "type": "k8s", + "label": "go-contract" +} +METADATAJSON-EOF +``` + +Create the final chaincode package archive. + +```shell +tar -czf go-contract.tgz metadata.json code.tar.gz +``` + +Ideally the chaincode package should be created in the same CI/CD pipeline which builds the docker image. +There is an example [package-k8s-chaincode-action](https://github.com/hyperledgendary/package-k8s-chaincode-action) GitHub Action which can create the required k8s chaincode package. + +The GitHub Action repository includes a basic shell script which can also be used for automating the process above outside GitHub workflows. +For example, to create a basic k8s chaincode package using the `pkgk8scc.sh` helper script. + +```shell +curl -fsSL https://raw.githubusercontent.com/hyperledgendary/package-k8s-chaincode-action/main/pkgk8scc.sh -o pkgk8scc.sh && chmod u+x pkgk8scc.sh +./pkgk8scc.sh -l go-contract -n ghcr.io/hyperledger-labs/go-contract -d sha256:802c336235cc1e7347e2da36c73fa2e4b6437cfc6f52872674d1e23f23bba63b +``` + +## Chaincode deploy + +Deploy the chaincode package as usual, starting by installing the k8s chaincode package. + +```shell +peer lifecycle chaincode install go-contract.tgz +``` + +You can also use the `peer` command to get the chaincode package ID. + +```shell +export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid go-contract.tgz) && echo $PACKAGE_ID +``` diff --git a/docs/KUBERNETES_CONFIG.md b/docs/configuring/kubernetes-namespace.md similarity index 52% rename from docs/KUBERNETES_CONFIG.md rename to docs/configuring/kubernetes-namespace.md index 745b6dc..5330e6f 100644 --- a/docs/KUBERNETES_CONFIG.md +++ b/docs/configuring/kubernetes-namespace.md @@ -1,72 +1,4 @@ -# Kubernetes Configuration - -## Builder requirements - -The k8s builder needs sufficient permissions to manage chaincode pods on behalf of the Fabric `peer`. - -| Resource | Permissions | -| -------- | -------------------------------- | -| pods | get, list, watch, create, delete | -| secrets | create, patch | - -For example, follow these steps if the builder will be running in the `default` namespace using the `default` service account. - -1. Create a `fabric-builder-role` role. - -```shell -cat <