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..f243202 --- /dev/null +++ b/docs/concepts/chaincode-builder.md @@ -0,0 +1,14 @@ +# Chaincode builder + +From version 2.0, Hyperledger Fabric supports External Builders and Launchers to manage the process of building and launching chaincode, rather than being limited to the peer's built in Docker based build and launch process. + +External Builders and Launchers are a collection of executables — `detect`, `build`, `release` and `run` — that the peer calls in order to build, launch, and discover chaincode. The k8s builder executables do the following. + +| Executable | 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 | + +For more information about Fabric builders, see the [External Builders and Launchers](https://hyperledger-fabric.readthedocs.io/en/latest/cc_launcher.html) documentation. diff --git a/docs/concepts/chaincode-image.md b/docs/concepts/chaincode-image.md new file mode 100644 index 0000000..001edcf --- /dev/null +++ b/docs/concepts/chaincode-image.md @@ -0,0 +1,18 @@ +# Chaincode image + +Unlike the traditional built-in 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..99f3b89 --- /dev/null +++ b/docs/concepts/chaincode-package.md @@ -0,0 +1,43 @@ +# Chaincode package + +From version 2.0, [Hyperledger 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 + +Chaincode packages are used by the `peer lifecycle chaincode` command as part of the Fabric chaincode lifecycle to deploy chaincode. For example, + +```shell +peer lifecycle chaincode install go-contract.tgz +``` + +For more information, see the [Fabric chaincode lifecycle](https://hyperledger-fabric.readthedocs.io/en/latest/chaincode_lifecycle.html) documentation. + +## metadata.json + +The k8s builder will detect chaincode packages which have a type of `k8s`. For example, + +```json +{ + "type": "k8s", + "label": "go-contract" +} +``` + +## code.tar.gz + +Unlike other chaincode packages, the source artifacts in a k8s chaincode package do not contain the chaincode source files. +Instead, the `code.tar.gz` file contains an `image.json` file which defines which chaincode image should be used. + +The `code.tar.gz` file can also contain CouchDB indexes. For more information, see the [CouchDB indexes](https://hyperledger-fabric.readthedocs.io/en/latest/couchdb_as_state_database.html#couchdb-indexes) Fabric documentation. + +## image.json + +The chaincode image must be built and published before creating the `image.json` file. The `image.json` contains the chaincode image name, and the immutable digest of the published image. For more information, see [Pull an image by digest (immutable identifier)](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier). For example. + +```json +{ + "name": "ghcr.io/hyperledger-labs/go-contract", + "digest": "sha256:802c336235cc1e7347e2da36c73fa2e4b6437cfc6f52872674d1e23f23bba63b" +} +``` 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 < image.json +{ + "name": "ghcr.io/hyperledger-labs/go-contract", + "digest": "sha256:802c336235cc1e7347e2da36c73fa2e4b6437cfc6f52872674d1e23f23bba63b" +} +IMAGEJSON-EOF +``` + +The k8s builder 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 +``` diff --git a/docs/mkdocs.yml b/mkdocs.yml similarity index 58% rename from docs/mkdocs.yml rename to mkdocs.yml index f64cac2..fb2fa29 100644 --- a/docs/mkdocs.yml +++ b/mkdocs.yml @@ -1,14 +1,20 @@ -site_name: Hyperledger Fabric Chaincode Builder for Kubernetes -repo_name: hyperledger-labs/fabric-builder-k8s +site_name: Kubernetes Builder +site_description: Kubernetes external chaincode builder for Hyperledger Fabric +repo_name: fabric-builder-k8s repo_url: https://github.com/hyperledger-labs/fabric-builder-k8s -docs_dir: content +docs_dir: docs theme: name: material - logo: assets/project-logo.png + logo: assets/Hyperledger_Fabric_White.svg favicon: assets/project-icon.png icon: repo: fontawesome/brands/github palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode # Palette toggle for light mode - media: "(prefers-color-scheme: light)" scheme: default @@ -20,7 +26,7 @@ theme: scheme: slate toggle: icon: material/brightness-4 - name: Switch to light mode + name: Switch to system preference features: - content.code.copy - navigation.expand @@ -77,5 +83,27 @@ plugins: extra: version: provider: mike + social: + - icon: fontawesome/brands/discord + link: https://discord.gg/hyperledger + name: Hyperledger Discord nav: - - Introduction: index.md + - About: + - Introduction: index.md + - Objectives: about/objectives.md + - Community: about/community.md + - Getting Started: + - Quick Start: getting-started/demo.md + - Requirements: getting-started/requirements.md + - Installation: getting-started/install.md + - FAQs: getting-started/faqs.md + - Concepts: + - Chaincode builder: concepts/chaincode-builder.md + - Chaincode image: concepts/chaincode-image.md + - Chaincode package: concepts/chaincode-package.md + - Configuring: + - Configuration overview: configuring/overview.md + - Kubernetes namespace: configuring/kubernetes-namespace.md + - Kubernetes permissions: configuring/kubernetes-permissions.md + - Tutorials: + - Creating a chaincode package: tutorials/package-chaincode.md diff --git a/docs/requirements.txt b/requirements.txt similarity index 100% rename from docs/requirements.txt rename to requirements.txt