From a5ce7ff43e8e173b4a771d91299750d696098644 Mon Sep 17 00:00:00 2001 From: Silas Davis <silas@erisindustries.com> Date: Tue, 4 Apr 2017 17:49:54 +0200 Subject: [PATCH] add cluster/kubernetes wrapper/templates --- deployment/README.md | 18 +++ deployment/kubernetes/all_nodes.yaml | 37 +++++ deployment/kubernetes/node000-deploy.yaml | 64 ++++++++ deployment/start_in_cluster | 184 ++++++++++++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 deployment/README.md create mode 100644 deployment/kubernetes/all_nodes.yaml create mode 100644 deployment/kubernetes/node000-deploy.yaml create mode 100755 deployment/start_in_cluster diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 00000000..61e4a0cc --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,18 @@ +### Deployment +Included in this directory are some template files for running Burrow in a +cluster orchestration environment. [start_in_cluster](start_in_cluster) +is a general purpose script and the files in [kubernetes](kubernetes) are some +example Service and Deployment files that illustrates its possible usage. + +#### start_in_cluster +[start_in_cluster](start_in_cluster) takes its parameters as environment variables. + +You can find the variables used at the top of the file along with their defaults. + +#### Kubernetes +[all_nodes.yml](kubernetes/all_nodes.yaml) is a Kubernetes Service definition +that launches an entire network of nodes based on Deployment definitions like the +example [node000-deploy.yaml](kubernetes/node000-deploy.yaml). Each validating +node should have it's own Deployment defintion like the one found in +[node000-deploy.yaml](kubernetes/node000-deploy.yaml) + diff --git a/deployment/kubernetes/all_nodes.yaml b/deployment/kubernetes/all_nodes.yaml new file mode 100644 index 00000000..91a73702 --- /dev/null +++ b/deployment/kubernetes/all_nodes.yaml @@ -0,0 +1,37 @@ +# All Nodes - Load balanced API ports +kind: Service +apiVersion: v1 +metadata: + name: your-app-chain-api + labels: + app: your-app + tier: chain + chain_name: your-chain + vendor: monax +spec: + sessionAffinity: ClientIP + selector: + app: your-app + tier: chain + # node_number: "001" + ports: + - protocol: TCP + port: 1337 + targetPort: 1337 + name: your-app-chain-api + +# All Nodes - genesis.json as ConfigMap +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: your-app-ecosystem-chain-genesis + labels: + app: your-app-ecosystem + tier: chain + chain_name: your-app + vendor: monax +data: + chain-genesis: | + {"chain_id":"your-chain","accounts":[{"address":"BD1EA8ABA4B44094A406092922AF7CD92E01E5FE","amount":99999999999999,"name":"your-app_root_000","permissions":{"base":{"perms":16383,"set":16383},"roles":[]}},{"address":"E69B68990FECA85E06421859DBD4B2958C80A0D5","amount":9999999999,"name":"your-app_participant_000","permissions":{"base":{"perms":2118,"set":16383},"roles":[]}},{"address":"15416FC158C2D106B2994C82724B3DBBA47CDF79","amount":9999999999,"name":"your-app_participant_001","permissions":{"base":{"perms":2118,"set":16383},"roles":[]}},{"address":"EA6EBC0569495F98F159D533E8DD7D1D3DCFC80C","amount":9999999999,"name":"your-app_participant_002","permissions":{"base":{"perms":2118,"set":16383},"roles":[]}},{"address":"242075F27576B80F2A2805488E23203CBCBCBDFB","amount":99999999999999,"name":"your-app_validator_000","permissions":{"base":{"perms":16383,"set":16383},"roles":[]}},{"address":"8B84E223A42DEDC8C62A19F99C45C94B807BDFB6","amount":9999999999,"name":"your-app_validator_001","permissions":{"base":{"perms":32,"set":16383},"roles":[]}},{"address":"68AFC7ADB01A8CF8F9B93166D749F0067D250981","amount":9999999999,"name":"your-app_validator_002","permissions":{"base":{"perms":32,"set":16383},"roles":[]}},{"address":"443BAD24961BEE41F052C6B55AF58BDE9A4DB75F","amount":9999999999,"name":"your-app_validator_003","permissions":{"base":{"perms":32,"set":16383},"roles":[]}}],"validators":[{"pub_key":[1,"ED3EAEAAA735EC41A3625BB8AAC754A381A5726269E584B77A594E4197F2B516"],"name":"your-app_validator_000","amount":9999999998,"unbond_to":[{"address":"242075F27576B80F2A2805488E23203CBCBCBDFB","amount":9999999998}]},{"pub_key":[1,"F8F98DE0E65FBF8FBA5CE0813898F4E2FAFC34DD37FDB45B58D73B6D75DCB9AE"],"name":"your-app_validator_001","amount":9999999998,"unbond_to":[{"address":"8B84E223A42DEDC8C62A19F99C45C94B807BDFB6","amount":9999999998}]},{"pub_key":[1,"31D592F81F688AEE06B3124CBAC5AE3E04B5398A34325D4D32A25105B9588385"],"name":"your-app_validator_002","amount":9999999998,"unbond_to":[{"address":"68AFC7ADB01A8CF8F9B93166D749F0067D250981","amount":9999999998}]},{"pub_key":[1,"A1562215F9025DAA180B06C4DD9254D6B92C9F6C19219A359956941EB5924148"],"name":"your-app_validator_003","amount":9999999998,"unbond_to":[{"address":"443BAD24961BEE41F052C6B55AF58BDE9A4DB75F","amount":9999999998}]}]} + diff --git a/deployment/kubernetes/node000-deploy.yaml b/deployment/kubernetes/node000-deploy.yaml new file mode 100644 index 00000000..b1d0dad5 --- /dev/null +++ b/deployment/kubernetes/node000-deploy.yaml @@ -0,0 +1,64 @@ +# Node 000 - Deployment +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: your-app-ecosystem-chain-000 +spec: + replicas: 1 + template: + metadata: + labels: + app: your-app-ecosystem + tier: chain + node_number: "000" + chain_name: your-app + vendor: monax + spec: + containers: + - name: your-app-ecosystem-chain-000 + image: "your-app-ecosystem-chain:latest" + imagePullPolicy: IfNotPresent + env: + - name: CHAIN_NAME + value: your-chain + - name: CHAIN_NODE_NUMBER + value: "000" + - name: CHAIN_SEEDS + value: "your-app-chain-000:46656,your-app-chain-001:46656,your-app-chain-002:46656,your-app-chain-003:46656" + - name: CHAIN_API_PORT + value: "1337" + - name: CHAIN_PEER_PORT + value: "46656" + - name: CHAIN_RPC_PORT + value: "46657" + - name: CHAIN_LOG_LEVEL + value: notice + - name: CHAIN_GENESIS + valueFrom: + configMapKeyRef: + name: your-app-ecosystem-chain-genesis + key: chain-genesis + - name: KEY_ADDRESS + valueFrom: + secretKeyRef: + name: your-app-ecosystem-chain-000-keys + key: address + - name: KEY_PUBLIC + valueFrom: + secretKeyRef: + name: your-app-ecosystem-chain-000-keys + key: public-key + - name: KEY_PRIVATE + valueFrom: + secretKeyRef: + name: your-app-ecosystem-chain-000-keys + key: private-key + - name: ORGANIZATION_NAME + value: allianz + ports: + - containerPort: 46656 + - containerPort: 46657 + - containerPort: 1337 + restartPolicy: Always + diff --git a/deployment/start_in_cluster b/deployment/start_in_cluster new file mode 100755 index 00000000..29b29fdd --- /dev/null +++ b/deployment/start_in_cluster @@ -0,0 +1,184 @@ +#!/usr/bin/env bash +set -e + +# This script is a wrapper for running burrow in a cluster, that is by a cluster +# orchestration environment like Kubernetes or Mesos + +# For why this is necessary see -> +# https://github.com/kubernetes/kubernetes/issues/23404 +CHAIN_NAME=$(echo $CHAIN_NAME | tr -d '\n') +CHAIN_NODE_NUMBER=$(echo $CHAIN_NODE_NUMBER | tr -d '\n') +CHAIN_SEEDS=$(echo $CHAIN_SEEDS | tr -d '\n') +ERIS=${ERIS:-$HOME/.eris} +ERIS=$(echo $ERIS | tr -d '\n') +KEY_ADDRESS=$(echo $KEY_ADDRESS | tr -d '\n') +KEY_PUBLIC=$(echo $KEY_PUBLIC | tr -d '\n') +KEY_PRIVATE=$(echo $KEY_PRIVATE | tr -d '\n') +ORG_NAME=$(echo $ORG_NAME | tr -d '\n') + +# Normal var setting +CHAIN_DIR=$ERIS/chains/$CHAIN_NAME +CHAIN_ID=${CHAIN_ID:-$CHAIN_NAME} +CHAIN_API_PORT=${CHAIN_API_PORT:-1337} +CHAIN_PEER_PORT=${CHAIN_PEER_PORT:-46656} +CHAIN_RPC_PORT=${CHAIN_RPC_PORT:-46657} +CHAIN_NODE_NUMBER=${CHAIN_NODE_NUMBER:-"000"} +CHAIN_SEEDS=${CHAIN_SEEDS:-""} +ORG_NAME=${ORG_NAME:-"myGreatOrg"} + +# All known variables should either have defaults set above, or checks here. +check() { + echo -e "\tChecking address of key." + [ -z "$KEY_ADDRESS" ] && { echo "Sad marmot face. Please set KEY_ADDRESS and re-run me."; exit 1; } + echo -e "\tChecking public key." + [ -z "$KEY_PUBLIC" ] && { echo "Sad marmot face. Please set KEY_PUBLIC and re-run me."; exit 1; } + echo -e "\tChecking private key." + [ -z "$KEY_PRIVATE" ] && { echo "Sad marmot face. Please set KEY_PRIVATE and re-run me."; exit 1; } + echo -e "\tChecking chain name." + [ -z "$CHAIN_NAME" ] && { echo "Sad marmot face. Please set CHAIN_NAME and re-run me."; exit 1; } + echo -e "\tChecking genesis." + if [ -z "$CHAIN_GENESIS" ] + then + if [ ! -e "$CHAIN_DIR"/genesis.json ] + then + echo "Sad marmot face. Please set CHAIN_GENESIS and re-run me." + exit 1 + fi + fi + echo -e "\tChecks complete." +} + +setup_dir() { + if [ ! -d "$CHAIN_DIR" ] + then + echo -e "\tChain dir does not exist. Creating." + mkdir -p $CHAIN_DIR + else + echo -e "\tChain dir exists. Not creating." + fi + cd $CHAIN_DIR + echo -e "\tChain dir setup." +} + +write_config() { + cat <<EOF > config.toml +[chain] +assert_chain_id = "$CHAIN_ID" +major_version = 0 +minor_version = 12 +genesis_file = "genesis.json" + [chain.consensus] + name = "tendermint" + major_version = 0 + minor_version = 6 + relative_root = "tendermint" + [chain.manager] + name = "erismint" + major_version = 0 + minor_version = 12 + relative_root = "erismint" +[servers] + [servers.bind] + address = "" + port = $CHAIN_API_PORT + [servers.tls] + tls = false + cert_path = "" + key_path = "" + [servers.cors] + enable = false + allow_origins = [] + allow_credentials = false + allow_methods = [] + allow_headers = [] + expose_headers = [] + max_age = 0 + [servers.http] + json_rpc_endpoint = "/rpc" + [servers.websocket] + endpoint = "/socketrpc" + max_sessions = 50 + read_buffer_size = 4096 + write_buffer_size = 4096 + [servers.tendermint] + rpc_local_address = "0.0.0.0:$CHAIN_RPC_PORT" + endpoint = "/websocket" +[tendermint] +private_validator_file = "priv_validator.json" + [tendermint.configuration] + moniker = "$CHAIN_NAME-$ORG_NAME-validator-$CHAIN_NODE_NUMBER" + seeds = "$CHAIN_SEEDS" + fast_sync = false + db_backend = "leveldb" + log_level = "$CHAIN_LOG_LEVEL" + node_laddr = "0.0.0.0:$CHAIN_PEER_PORT" + rpc_laddr = "0.0.0.0:$CHAIN_RPC_PORT" + proxy_app = "tcp://127.0.0.1:46658" + [tendermint.configuration.p2p] + dial_timeout_seconds = 3 + handshake_timeout_seconds = 20 + max_num_peers = 20 + authenticated_encryption = true + send_rate = 512000 + recv_rate = 512000 + fuzz_enable = false # use the fuzz wrapped conn + fuzz_active = false # toggle fuzzing + fuzz_mode = "drop" # eg. drop, delay + fuzz_max_delay_milliseconds = 3000 + fuzz_prob_drop_rw = 0.2 + fuzz_prob_drop_conn = 0.00 + fuzz_prob_sleep = 0.00 +[erismint] +db_backend = "leveldb" +tendermint_host = "0.0.0.0:$CHAIN_RPC_PORT" +EOF + echo -e "\tConfig file written." +} + +write_key_file() { + cat <<EOF > priv_validator.json +{ + "address": "$KEY_ADDRESS", + "pub_key": [ + 1, + "$KEY_PUBLIC" + ], + "priv_key": [ + 1, + "$KEY_PRIVATE" + ], + "last_height": 0, + "last_round": 0, + "last_step": 0 +} +EOF + echo -e "\tKey file written." +} + +write_genesis_file() { + [ -z "$CHAIN_GENESIS" ] && echo -e "\tUsing preloaded genesis file." && return 0 + echo -e "\tWriting genesis file from environment variables." + echo $CHAIN_GENESIS > genesis.json +} + +main() { + echo "Running pre-boot checks." + check + + echo "Setting up chain directory." + setup_dir + + echo "Writing config file." + write_config + + echo "Writing key file." + write_key_file + + echo "Writing genesis file." + write_genesis_file + + sleep 2 # hack to let the cluster provision echo "Starting eris-db" + eris-db serve +} + +main $@ \ No newline at end of file -- GitLab