歡迎光臨
每天分享高質量文章

如何用EOS和OpenShift部署一個BaaS系統

現在區塊鏈技術很是熱門,很多大公司都紛紛開闢了自己關於區塊鏈的相關業務部門,比如數字金融,產品溯源等,那麼什麼是區塊鏈技術呢?區塊鏈是分散式資料儲存、點對點傳輸、共識機制、加密演演算法等計算機技術的新型應用樣式。在區塊鏈技術的迭代過程中,大家公認比特幣是區塊鏈1.0版本的應用,以太坊是2.0版本,現在在鏈圈炒的最為火熱的就是自稱是區塊鏈3.0版本的EOS。它以BFT+DPos的公式機制和石墨烯網路為基礎,號稱公網上線以後能夠達到3000-4000左右的TPS(比特幣為6-7筆,以太坊是30-40筆,但是筆者親測EOS的3.0版本是1000tps左右,可能是受環境和主機效能所限吧)。越來越多的人開始關註區塊鏈技術,越來越多的企業級應用開始搬上區塊鏈,現在我就帶領大家搭建一套最簡單的BaaS系統(block chain as a service:區塊鏈即服務)。
當人們一說到某某即服務的時候總是想到PaaS、SaaS或者IaaS,沒錯!這次搭建的BaaS也和前面幾個類似採用PaaS的設計架構,即用容器的方式搭建BaaS平臺。提到容器,就不得不想到現在最流行的Docker+Kubernetes的方式,Docker提供了單機條件下的容器執行環境,Kubernetes提供了一套高可用的容器編排管理系統。本次使用的就是在程式碼級對Kubernetes做了升級和改造的,由Red Hat公司推出的OpenShift,它使用Kuberenetes作為其核心,對它網路功能做了補充,增加了Web介面,又對原有的Ingress做了最佳化和升級,所以我們選擇它作為本次BaaS的基礎平臺。
BaaS平臺部署圖如下圖所示:

1、首先開始製作EOS映象
1)下麵是EOS程式碼獲取方法:
git clone https://github.com/EOSIO/eos --recursive
然後進入程式碼目錄執行:
cd eos
./eosio_build.sh
2)在程式碼的EOS目錄下會生成一個build目錄,把EOS的二進位制檔案NodeOS、keosd、cleos等複製到要製作映象的子目錄下,下麵是Dockerfile檔案的內容,其中基礎映象選用了CentOS,這個系統的版本好要和剛才編譯EOS的一致,否則可能會出現NodeOS無法執行的錯誤。
From docker.io/centos
ADD cleos /cleos
ADD nodeos /nodeos
ADD genesis.json /genesis.json
ADD config.ini /config.ini
ADD nodeosd.sh /opt/eosio/bin/
USER 0
CMD /opt/eosio/bin/nodeosd.sh
3)除了有必要的二進位制檔案外,我們還要為NodeOS啟動配置必要的啟動指令碼和兩個配置檔案。
下麵是啟動指令碼:
#!/bin/sh
mkdir -p /opt/eosio/config-dir
mkdir -p /opt/eosio/data-dir
mkdir -p /opt/eosio/bin
cp /config.ini /opt/eosio/config-dir
cp /genesis.json /opt/eosio/config-dir
cp /cleos /opt/eosio/bin
cp /nodeos /opt/eosio/bin
cp -r /contracts /opt/eosio/bin
CONFIG_DIR="--config-dir=/opt/eosio/config-dir"
DATA_DIR="--data-dir=/opt/eosio/data-dir"
#replace agent name
sed -i 's/AGENT-NAME/'$HOSTNAME'/g' /opt/eosio/config-dir/config.ini
#replace producer name
sed -i 's/EOSIO/'$BP'/g' /opt/eosio/config-dir/config.ini
#replace p2p-peer-address
sed -i 's/EOSIO/'$BP'/g' /opt/eosio/config-dir/config.ini
#replace p2p-server-address
sed -i 's/EOSIO/'$BP'/g' /opt/eosio/config-dir/config.ini
sed -i 's/P2P_PEER_ADDRESS/'${BP_LIST}'/g' /opt/eosio/config-dir/config.ini
sed -i 's/P2P_SERVER_ADDRESS/'${HOSTNAME}'/g' /opt/eosio/config-dir/config.ini
#replace keys
sed -i 's/PRIVATE-KEY/'${PRIVATE_KEY}'/g' /opt/eosio/config-dir/config.ini
sed -i 's/PUBLIC-KEY/'${PUBLIC_KEY}'/g' /opt/eosio/config-dir/config.ini
exec /opt/eosio/bin/nodeos -e $CONFIG_DIR $DATA_DIR $@
genesis.json檔案內容:
# cat genesis.json
{
 "initial_timestamp": "2018-03-02T12:00:00.000",
 "initial_key": "EOSxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
 "initial_configuration": {
   "max_block_net_usage": 1048576,
   "target_block_net_usage_pct": 1000,
   "max_transaction_net_usage": 524288,
   "base_per_transaction_net_usage": 12,
   "net_usage_leeway": 500,
   "context_free_discount_net_usage_num": 20,
   "context_free_discount_net_usage_den": 100,
   "max_block_cpu_usage": 100000,
   "target_block_cpu_usage_pct": 500,
   "max_transaction_cpu_usage": 50000,
   "min_transaction_cpu_usage": 100,
   "max_transaction_lifetime": 3600,
   "deferred_trx_expiration_window": 600,
   "max_transaction_delay": 3888000,
   "max_inline_action_size": 4096,
   "max_inline_action_depth": 4,
   "max_authority_depth": 6,
   "max_generated_transaction_count": 16
 },
 "initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000"
}
# cat config.ini
# File to read Genesis State from (eosio::chain_plugin)
genesis-json = "genesis.json"
# override the initial timestamp in the Genesis State file (eosio::chain_plugin)
# genesis-timestamp =
# the location of the block log (absolute path or relative to application data dir) (eosio::chain_plugin)
block-log-dir = "blocks"
# Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin)
# checkpoint =
# Override default WASM runtime (eosio::chain_plugin)
# wasm-runtime =
# Maximum size MB of database shared memory file (eosio::chain_plugin)
shared-memory-size-mb = 1024
# Track only transactions whose scopes involve the listed accounts. Default is to track all transactions. (eosio::history_plugin)
# filter_on_accounts =
# The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin)
http-server-address = 0.0.0.0:8888
# The local IP and port to listen for incoming https connections; leave blank to disable. (eosio::http_plugin)
# https-server-address =
# Filename with the certificate chain to present on https connections. PEM format. Required for https. (eosio::http_plugin)
# https-certificate-chain-file =
# Filename with https private key in PEM format. Required for https (eosio::http_plugin)
# https-private-key-file =
# Specify the Access-Control-Allow-Origin to be returned on each request. (eosio::http_plugin)
# access-control-allow-origin =
# Specify the Access-Control-Allow-Headers to be returned on each request. (eosio::http_plugin)
# access-control-allow-essay-headers =
# Specify if Access-Control-Allow-Credentials: true should be returned on each request. (eosio::http_plugin)
access-control-allow-credentials = false
# The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin)
p2p-listen-endpoint = 0.0.0.0:9876
# An externally accessible host:port for identifying this node. Defaults to p2p-listen-endpoint. (eosio::net_plugin)
p2p-peer-address = P2P_PEER_ADDRESS:9876
# The public endpoint of a peer node to connect to. Use multiple p2p-peer-address options as needed to compose a network. (eosio::net_plugin)
p2p-server-address = P2P_SERVER_ADDRESS
# The name supplied to identify this node amongst the peers. (eosio::net_plugin)
agent-name = "AGENT-NAME"
# Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined. (eosio::net_plugin)
allowed-connection = any
# Optional public key of peer allowed to connect.  May be used multiple times. (eosio::net_plugin)
# peer-key =
# Tuple of [PublicKey, WIF private key] (may specify multiple times) (eosio::net_plugin)
# peer-private-key =
# Maximum number of clients from which connections are accepted, use 0 for no limit (eosio::net_plugin)
max-clients = 25
# number of seconds to wait before cleaning up dead connections (eosio::net_plugin)
connection-cleanup-period = 30
# True to require exact match of peer network version. (eosio::net_plugin)
network-version-match = 0
# number of blocks to retrieve in a chunk from any individual peer during synchronization (eosio::net_plugin)
sync-fetch-span = 100
# maximum sizes of transaction or block messages that are sent without first sending a notice (eosio::net_plugin)
max-implicit-request = 1500
# Enable block production, even if the chain is stale. (eosio::producer_plugin)
enable-stale-production = false
# Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid (eosio::producer_plugin)
max-transaction-time = 30
# Percent of producers (0-100) that must be participating in order to produce blocks (eosio::producer_plugin)
required-participation = 33
# ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin)
producer-name = EOSIO
# Tuple of [public key, WIF private key] (may specify multiple times) (eosio::producer_plugin)
private-key = ["PUBLIC-KEY","PRIVATE-KEY"]
# Lag in number of blocks from the head block when selecting the reference block for transactions (-1 means Last Irreversible Block) (eosio::txn_test_gen_plugin)
txn-reference-block-lag = 0
# The path of the wallet files (absolute path or relative to application data dir) (eosio::wallet_plugin)
wallet-dir = "."
# Timeout for unlocked wallet in seconds (default 900 (15 minutes)). Wallets will automatically lock after specified number of seconds of inactivity. Activity is defined as any wallet command e.g. list-wallets. (eosio::wallet_plugin)
unlock-timeout = 900
# eosio key that will be imported automatically when a wallet is created. (eosio::wallet_plugin)
# eosio-key =
# Plugin(s) to enable, may be specified multiple times
# plugin =
plugin = eosio::producer_plugin
plugin = eosio::chain_api_plugin
plugin = eosio::wallet_api_plugin
plugin = eosio::http_plugin
plugin = eosio::history_api_plugin
plugin = eosio::history_plugin}}}
4)執行下麵命令生成image並推送到私有的Registry。
{{{docker build . -t registryhost:5000/eos/eos
docker push registryhost:5000/eos/eos
2、EOS節點部署
1)當映象推送到Registry後,我們就可以進行Yaml檔案的編寫並且配置了,下麵是Yaml檔案的內容:
at nodeos.yaml 
apiVersion: v1
kind: Template
metadata:
 name: nodeos
 annotations:
   openshift.io/display-name: nodeos
   description: nodeos of eos.
   iconClass: icon-wildfly
   tags: nodeos
objects:
- apiVersion: v1
 kind: Service
 metadata:
   annotations:
     description: Exposes and load balances the application pods
   name: ${BP}
 spec:
   ports:
   - name: http-8888-tcp
     port: 8888
     protocol: TCP
     targetPort: 8888
   - name: admin-9876-tcp
     port: 9876
     protocol: TCP
     targetPort: 9876
   selector:
     name: ${BP}
   type: ClusterIP
- apiVersion: v1
 kind: Route
 metadata:
   name: nodeos-http
 spec:
   host: nodeos
   to:
     kind: Service
     name: ${BP}
   port:
     targetPort: http-8888-tcp
- apiVersion: v1
 kind: DeploymentConfig
 metadata:
   annotations:
     description: Defines how to deploy the nodeos
   name: ${BP}
 spec:
   replicas: 1
   selector:
     name: ${BP}
   strategy:
     type: Rolling
   template:
     metadata:
       labels:
         name: ${BP}
     spec:
       containers:
       - image: "192.168.20.2:5000/eosio/eos"
         env:
         - name: BP
           value: ${BP}
         - name: PUBLIC_KEY
           value: ${PUBLIC_KEY}
         - name: PRIVATE_KEY
           value: ${PRIVATE_KEY}
         - name: BP_LIST
           value: ${BP_LIST}
         imagePullPolicy: Always
         name: nodeos-bp
         ports:
         - containerPort: 8888
           protocol: "TCP"
         - containerPort: 9876
           protocol: "TCP"    
         resources:
           requests:
             memory: 4096Mi
             cpu: 2000m
       dnsPolicy: ClusterFirst
       restartPolicy: Always
       securityContext:
       - runAsUser: 0
parameters:
- name: BP
 description: Block Producer
 displayName: Block Producer
 value: eosio
- name: PUBLIC_KEY
 description: PUBLIC_KEY.
 displayName: PUBLIC_KEY
 value: EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
- name: PRIVATE_KEY
 description: PRIVATE_KEY.
 displayName: PRIVATE_KEY
 value: 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
- name: BP_LIST
 description: A IP list of Block Producer
 displayName: A IP list of Block Producer
 value: bp's hostname and port
2)有了Yaml檔案,我們就可以把我們的Yaml檔案推送到OpenShift中當成模版,然後透過模版進行EOS節點的實體化,這裡面有一個問題需要註意,所有節點的公私鑰不可能一樣,需要透過模版的引數在實體化的時候傳入容器裡,然後啟動NodeOS的時候,呼叫NodeOS啟動指令碼把傳入的變數(每一個傳入變數都會生成一個環境變數)替換到config.ini檔案中,然後啟動EOS的主行程NodeOS。當然,這裡還有一個問題也需要註意,那就是4.1的EOS配置檔案裡需要配置兩個引數,一個是自己自身的IP(p2p-server-address),和對端IP(p2p-peer-address)第一個地址可以用這個Pod的hostname代替,第二個可以透過指定之前節點的hostname來填充。
3)使用oc create -f eos.yaml 進行模版的部署,然後透過Web介面,選擇剛才的模版,輸入變數的內容,最後點選生成,如下圖所示:

3、既然環境已經設定完成,現在我們來初始化整個EOS的環境。
1)首先透過cleos wallet create建立一個預設的錢包,如果-n可以指定錢包的名字,這個錢包預設的儲存路徑是/root/eosio-wallet/目錄下,看下麵的輸出:
# cleos wallet create 
"/usr/local/bin/keosd" launched
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5J2SGNDmhZFiVnbZY6V669XLEksGs13KnhCnkuqQZScj5ieNV5j"
其中下麵的是這個錢包的密碼,需要記住,因為現在4.1版本的錢包900秒後就會自動上鎖,需要這個密碼來解鎖。
2)建立一對公私鑰,建立賬戶,並部署合約。
建立私鑰公鑰:
# cleos create key 
"/usr/local/bin/keosd" launched Private key: 5Kgh744izqDCNyuRZcBu4nMjgJbBwWBdqQZuQi53qPB9L69Cj9X Public key: EOS6CYWY1q4AAsVV3rzcT1GGQmZcg7yDnA6jZx2KUjHvmZWPv8DQg
建立代幣賬戶:
#cleos -u http://nodeos:80 create account eosio eosio.token EOS6CYWY1q4AAsVV3rzcT1GGQmZcg7yDnA6jZx2KUjHvmZWPv8DQg EOS6CYWY1q4AAsVV3rzcT1GGQmZcg7yDnA6jZx2KUjHvmZWPv8DQg
部署代幣合約:
#cleos -u http://nodeos:80  set contract eosio.token  eos/build/contracts/eosio.token/
Reading WAST/WASM from /eos_code/dawn-v4.1.0/eos/build/contracts/eosio.token/eosio.token.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 9ff87dffe3eb2eeac29a4afd8eec8faa563f6be43cf5142e71cd61d0c4b66244  8072 bytes  976 us
#         eosio <= eosio::setcode               {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d01000000017f1560037f7e7f0060057f7e...
#         eosio <= eosio::setabi                {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30010c6163636f756e745f6e616d65046e616d65...
warning: transaction executed locally, but may not be confirmed by the network yet
建立代幣:
#cleos -u http://nodeos:80  push action eosio.token create '["eosio","1000000000.0000 SYS",0,0,0]' -p eosio.token
executed transaction: 8d7e472fa7309abfa051eed367c552e3e3e8f283530dc3375761d7da2cb298e9  120 bytes  453 us
#   eosio.token <= eosio.token::create          {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"}
>> warning: transaction executed locally, but may not be confirmed by the network yet
釋出代幣:
#cleos -u http://nodeos:80 push action eosio.token issue '["eosio","1000000000.0000 SYS","issue"]' -p eosio
cleos -u http://nodeos:80 push action eosio.token issue '["eosio","1000000000.0000 SYS","issue"]' -p eosio
executed transaction: bdf099816554de5849f030a1d26cc40ade29b74c87aff4180796c7c26507d677  128 bytes  343 us
#   eosio.token <= eosio.token::issue           {"to":"eosio","quantity":"1000000000.0000 SYS","memo":"issue"}
warning: transaction executed locally, but may not be confirmed by the network yet
查詢代幣餘額:
#cleos -u http://nodeos:80 get currency balance eosio.token eosio
1000000000.0000 SYS
建立賬號:
#cleos -u http://nodeos:80  create account eosio alex EOS6CYWY1q4AAsVV3rzcT1GGQmZcg7yDnA6jZx2KUjHvmZWPv8DQg EOS6CYWY1q4AAsVV3rzcT1GGQmZcg7yDnA6jZx2KUjHvmZWPv8DQg
EOS轉賬 :
#cleos -u http://nodeos:80  push action eosio.token transfer '["eosio", "alex", "10000.0000 SYS", ""]' -p eosio
3)建立BP,所謂BP就是EOS上的出塊節點(block producer),到6月2日 EOS主網上線,全網應該一共21個BP節點,每個節點都要經過EOS的投票選舉產生,現在我們的環境裡還沒有一個被選舉的BP節點,所以需要透過抵押EOS的方式進行投票,當投票超過150M個EOS的時候,得票最多的前21個節點就是BP節點了,當然我們的BaaS受部署規模限制,不一樣定要到21個節點,所以我們選舉4個BP節點,執行如下命令:
部署系統合約
# cleos -u http://nodeos:80 set contract eosio eos/build/contracts/eosio.system
Reading WAST/WASM from ./build/contracts/eosio.system/eosio.system.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: cd1975d3628c1306f1fb58e49d5474d61c829bad42bffb4aeca7488bb041bd4d  40488 bytes  3969 us
#         eosio <= eosio::setcode               {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ba022f60027f7e0060067f7e7e7f7f...
#         eosio <= eosio::setabi                {"account":"eosio","abi":"0e656f73696f3a3a6162692f312e30050c6163636f756e745f6e616d65046e616d650f7065...
>> warning: transaction executed locally, but may not be confirmed by the network yet
建立賬戶bp1作為出塊節點:
cleos -u http://nodeos:80 system newaccount eosio bp1 EOS7FNpU6P3yhT7bkf3fs7aNUxb3yNbMXPbn4nsYgh3ZkEhtchEAH EOS7FNpU6P3yhT7bkf3fs7aNUxb3yNbMXPbn4nsYgh3ZkEhtchEAH --stake-net '500.00 SYS' --stake-cpu '500.00 SYS'
1697946ms thread-0   main.cpp:419                  create_action        ] result: {"binargs":"0000000000ea3055000000000000423d00200000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"bp1","bytes":8192}}
1697948ms thread-0   main.cpp:419                  create_action        ] result: {"binargs":"0000000000ea3055000000000000423d404b4c00000000000453595300000000404b4c0000000000045359530000000000"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"bp1","stake_net_quantity":"500.0000 SYS","stake_cpu_quantity":"500.0000 SYS","transfer":false}}
executed transaction: bbdeb7aa13953746e93c47b53729ce36ca2d89f16d87b872ebbacd71c2f4fc6b  336 bytes  1831 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"bp1","owner":{"threshold":1,"keys":[{"key":"EOS7FNpU6P3yhT7bkf3fs7aNUxb3y...
>>
#         eosio <= eosio::buyrambytes           {"payer":"eosio","receiver":"bp1","bytes":8192}
>>
#         eosio <= eosio::delegatebw            {"from":"eosio","receiver":"bp1","stake_net_quantity":"500.0000 SYS","stake_cpu_quantity":"500.0000 ...
>> warning: transaction executed locally, but may not be confirmed by the network yet
匯入剛才bp1的私鑰:
# cleos -u http://nodeos:80 wallet import 5Je4PsFWinBPXgWQasz7usbv8MLu5AbkcjU41JQr4Suhh34yKPu
imported private key for: EOS7FNpU6P3yhT7bkf3fs7aNUxb3yNbMXPbn4nsYgh3ZkEhtchEAH
註冊bp1為bp節點:
# cleos -u http://nodeos:80 system regproducer bp1 EOS7FNpU6P3yhT7bkf3fs7aNUxb3yNbMXPbn4nsYgh3ZkEhtchEAH http://bp1:8888
2155333ms thread-0   main.cpp:419                  create_action        ] result: {"binargs":"000000000000423d000336d1c7309f8c40f9a2d7bf11b6ba3f6b1c699a67d2ad26c003e5313ff1ce1c940f687474703a2f2f6270313a383838380000"} arg: {"code":"eosio","action":"regproducer","args":{"producer":"bp1","producer_key":"EOS7FNpU6P3yhT7bkf3fs7aNUxb3yNbMXPbn4nsYgh3ZkEhtchEAH","url":"http://bp1:8888","location":0}}
executed transaction: 294568630bd6c733db853ba2aac2245ffeb199d47767b80ddadc1cbf421c6d46  152 bytes  623 us
#         eosio <= eosio::regproducer           {"producer":"bp1","producer_key":"EOS7FNpU6P3yhT7bkf3fs7aNUxb3yNbMXPbn4nsYgh3ZkEhtchEAH","url":"http...
>> warning: transaction executed locally, but may not be confirmed by the network yet
eosio抵押EOS,投票給bp1:
#cleos -u http://nodeos:80 system delegatebw bp1 bp1 '100000000.0000 SYS' '50000000.0000 SYS' --transfer
460701ms thread-0   main.cpp:1083                 operator()           ] act_payload: {"from":"eosio","receiver":"bp1","stake_net_quantity":"100000000.0000 SYS","stake_cpu_quantity":"50000000.0000 SYS","transfer":true}
2460702ms thread-0   main.cpp:419                  create_action        ] result: {"binargs":"0000000000ea3055000000000000423d0010a5d4e800000004535953000000000088526a74000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"bp1","stake_net_quantity":"100000000.0000 SYS","stake_cpu_quantity":"50000000.0000 SYS","transfer":true}}
executed transaction: 98314189243cf8a38619e9f887c5430d9285f19a6a2977eccc07d838611dd17a  144 bytes  676 us
#         eosio <= eosio::delegatebw            {"from":"eosio","receiver":"bp1","stake_net_quantity":"100000000.0000 SYS","stake_cpu_quantity":"500...
>> warning: transaction executed locally, but may not be confirmed by the network yet}
用抵押的EOS投票給bp1:
#cleos -u http://nodeos:80 system voteproducer prods bp1 bp1
2531150ms thread-0   main.cpp:419                  create_action        ] result: {"binargs":"000000000000423d000000000000000001000000000000423d"} arg: {"code":"eosio","action":"voteproducer","args":{"voter":"bp1","proxy":"","producers":["bp1"]}}
executed transaction: 15c7cd6bd19f41654abb2d4f52f23953f80fd76b2698ef2a713d67c6fa022ee7  120 bytes  905 us
#         eosio <= eosio::voteproducer          {"voter":"bp1","proxy":"","producers":["bp1"]}
>> warning: transaction executed locally, but may not be confirmed by the network yet
到這一步一個最最基本的EOS BaaS就算部署完畢了。
此時你就可以在你的終端上看到類似如下輸出:
3302000ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 00000d279a442987... #3367 @ 2018-05-22T15:55:02.000 signed by bp1 [trxs: 0, lib: 3366, confirmed: 0]

Kubernetes入門與進階實戰培訓

本次培訓內容包括:Docker基礎、容器技術、Docker映象、資料共享與持久化、Docker三駕馬車、Docker實踐、Kubernetes基礎、Pod基礎與進階、常用物件操作、服務發現、Helm、Kubernetes核心元件原理分析、Kubernetes服務質量保證、排程詳解與應用場景、網路、基於Kubernetes的CI/CD、基於Kubernetes的配置管理等,點選瞭解具體培訓內容
6月22日正式上課,點選閱讀原文連結即可報名。
贊(0)

分享創造快樂