Skip to content

Commit

Permalink
Tidy up doc build and readme
Browse files Browse the repository at this point in the history
Signed-off-by: James Taylor <[email protected]>
  • Loading branch information
jt-nti committed May 24, 2024
1 parent 23061de commit 934a6b1
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 164 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ name: Deploy mkdocs site to Pages
on:
pull_request:
branches: ["main"]
paths:
- 'docs/**'
push:
branches: ["main"]
paths:
- 'docs/**'
workflow_dispatch:

permissions:
Expand Down Expand Up @@ -41,7 +45,7 @@ jobs:
- name: Install requirements
run: pip install -r requirements.txt
- name: Build with mkdocs
run: mkdocs build
run: mkdocs build --strict
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
# vendor/
.idea/

# mkdocs documentation
/site

.fabric

*.log
168 changes: 8 additions & 160 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# fabric-builder-k8s

Kubernetes [external chaincode builder](https://hyperledger-fabric.readthedocs.io/en/latest/cc_launcher.html) for Hyperledger Fabric.
The Kubernetes [external chaincode builder](https://hyperledger-fabric.readthedocs.io/en/latest/cc_launcher.html) for Hyperledger Fabric (k8s builder) is an alternative to Fabric's legacy built in Docker chaincode builder, which does not work in a Kubernetes deployment, and the preconfigured chaincode-as-a-service builder, which is more suited to chaincode development and test.

With the k8s builder, the Fabric administrator is responsible for [preparing a chaincode image](#chaincode-docker-image), publishing to a container registry, and [preparing a chaincode package](#chaincode-package) with coordinates of the contract's immutable image digest.
When Fabric detects the installation of a `type=k8s` contract, the builder assumes full ownership of the lifecycle of pods, containers, and network linkages necessary to communicate securely with the peer.
For more information, including how to deploy your first chaincode with the k8s builder, see the [k8s builder documentation](https://labs.hyperledger.org/fabric-builder-k8s/).

To find out how to report issues, suggest enhancements and contribute to the k8s builder project, see the [contributing guide](CONTRIBUTING.md).

## Overview

With the k8s builder, the Fabric administrator is responsible for preparing a [chaincode image](https://labs.hyperledger.org/fabric-builder-k8s/concepts/chaincode-image/), publishing to a container registry, and preparing a [chaincode package](https://labs.hyperledger.org/fabric-builder-k8s/concepts/chaincode-package/) with coordinates of the contract's immutable image digest.
When Fabric detects the installation of a `type=k8s` contract, the builder assumes full ownership of the lifecycle of pods, containers, and network linkages necessary to communicate securely with the peer.

Advantages:

Expand All @@ -19,160 +24,3 @@ Advantages:
🛡️ Pre-published chaincode images remove any and all dependencies on a root-level _docker daemon_.

🕵️ Pre-published chaincode images provide traceability and change management features (e.g. Git commit hash as image tag)

The aim is for the 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 constraints.
(The assumption being that there are more people with Kubernetes skills than are familiar with the inner workings of Fabric!)

For example:

- 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 a `: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.


- 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.

## Usage

The k8s builder can be run in cluster using the `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment variables, or it can connect using a `KUBECONFIG_PATH` environment variable.

The following optional environment variables can be used to configure the k8s builder:

- `FABRIC_K8S_BUILDER_DEBUG` whether to enable additional logging
- `FABRIC_K8S_BUILDER_NAMESPACE` specifies the namespace to deploy chaincode to
- `FABRIC_K8S_BUILDER_SERVICE_ACCOUNT` specifies the service account for the chaincode pod

A `CORE_PEER_ID` environment variable is also currently required.

External builders are configured in the `core.yaml` file, for example:

```
externalBuilders:
- name: k8s_builder
path: /opt/hyperledger/k8s_builder
propagateEnvironment:
- CORE_PEER_ID
- FABRIC_K8S_BUILDER_DEBUG
- FABRIC_K8S_BUILDER_NAMESPACE
- FABRIC_K8S_BUILDER_SERVICE_ACCOUNT
- KUBERNETES_SERVICE_HOST
- KUBERNETES_SERVICE_PORT
```

See [External Builders and Launchers](https://hyperledger-fabric.readthedocs.io/en/latest/cc_launcher.html) for details of Hyperledger Fabric builders.

As well as configuring Fabric to use the k8s builder, you will need to [configure Kubernetes](docs/KUBERNETES_CONFIG.md) to allow the builder to start chaincode pods successfully.

There are addition docs with more detailed usage instructions for specific Fabric network deployments:

- [Kubernetes Test Network](docs/TEST_NETWORK_K8S.md)
- [Nano Test Network](docs/TEST_NETWORK_NANO.md)
- [Fabric Operator](docs/FABRIC_OPERATOR.md)
- [HLF Operator](docs/HLF_OPERATOR.md)

## Chaincode Docker 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](samples/README.md) for basic docker images which will work with the k8s builder.

## 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
```
2 changes: 1 addition & 1 deletion docs/tutorials/bevel-operator.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ kubectl auth can-i patch secrets --namespace default --as system:serviceaccount:

## 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.
The [sample contracts for Go, Java, and Node.js](https://github.com/hyperledger-labs/fabric-builder-k8s/tree/main/samples) 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:
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/fabric-operator.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/temp/channel-msp/peerOrganizations/org

## 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.
The [sample contracts for Go, Java, and Node.js](https://github.com/hyperledger-labs/fabric-builder-k8s/tree/main/samples) 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:
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ markdown_extensions:
- pymdownx.details
- pymdownx.emoji:
emoji_generator: !!python/name:materialx.emoji.to_svg
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_index: !!python/name:material.extensions.emoji.twemoji
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
Expand Down

0 comments on commit 934a6b1

Please sign in to comment.