【译文】如何在Akash网络上部署Solana

原文地址:Solana on Akashnet
本文将指导您如何在Akash网络上部署Solana节点。我会尽量用简洁的文字,从头到尾一步步的指导大家。
我必须说明的一点是,这仅仅是Solana开发节点而非正式产品节点。文末会有详细解释。
我使用了Ubuntu 20.04.2 LTS Linux 发行版和以下软件

  1. Akash: V0.12.1(在Akash网络上运行)
  2. Solana:V1.6.10(将其部署在Akash 网络上)
    简单介绍一下Akash和Solana。
    Akash是一个面向将来的去中心化的云
    Solana是一个高性能的区块链。它支持世界各地的开发者在其开发可扩展的加密应用。
    其实本文的想法非常简单,就是利用去中心化云-Akashnet去部署Solana应用。
    在Akashnet上运行一个实际的应用会比亚马逊AWS上便宜86%。Akashlytics
    其实,我不是很擅长说这些。为了节省大家的时间,让我们直接从命令行界面开始吧
  3. 安装akash客户端
    AKASH_NET=“https://raw.githubusercontent.com/ovrclk/net/master/mainnet
    AKASH_VERSION="$(curl -s “$AKASH_NET/version.txt”)"
    curl https://raw.githubusercontent.com/ovrclk/akash/master/godownloader.sh | sh -s – “v$AKASH_VERSION”

请一并安装jq工具,我们接下来会用到它。
2. 创建个人akash钱包
akash keys add default

该命令将会输出主几次,请确保将其保存到安全的地方。
它还会输出你的akash地址,在本文的例子中地址是:
akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h
export AKASH_ACCOUNT_ADDRESS=akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h

更多关于Akash钱包的信息可以在一下链接查看:Keplr Wallet - Akash Guidebook
3. 向钱包充值
开始之前,至少需要向该地址充值10 AKT(Akash 代币)
你可以在以下交易所购买(其实现在很多CEX/DEX都可以购买AKT)
THE AKT TOKEN
充值后即可查询钱包余额
export AKASH_NET=“https://raw.githubusercontent.com/ovrclk/net/master/mainnet
export AKASH_NODE="$(curl -s “$AKASH_NET/rpc-nodes.txt” | shuf -n 1)"

akash
–node “$AKASH_NODE”
query bank balances “$AKASH_ACCOUNT_ADDRESS”

汇率:1AKT=1000000UAKT(AKT*10^6).你也可以增加如下代码到你的指令行,
-o json | jq -r ‘(.balances[0].amount | tonumber / pow(10; 6))’
我是用的是akashnet-2 网络,具体有什么不同请到以下网址查询
Page not found - Akash Guidebook.
4. 创建证书
要创建任意部署之前,必须要首先创建证书文件。
运行下图命令。
export AKASH_CHAIN_ID="$(curl -s “$AKASH_NET/chain-id.txt”)"
akash tx cert create client
–from default
–chain-id $AKASH_CHAIN_ID
–node $AKASH_NODE
–gas-prices=“0.025uakt” --gas=“auto” --gas-adjustment=1.15

每个账户只需要创建一次证书,即可在说有部署中使用。有关证书的更多信息,请查询以下地址,
Page not found - Akash Guidebook
5. 准备部署清单文件
创建一个文件夹,命名为solana.yml,具体文件内容如下图所示。

version: “2.0”

services:
solana:
image: solanalabs/solana:v1.6.10
expose:
- port: 8899
as: 8899
proto: tcp
to:
- global: true

profiles:
compute:
solana:
resources:
cpu:
units: 0.1
memory:
size: 512Mi
storage:
size: 512Mi
placement:
akash:
attributes:
host: akash
signedBy:
anyOf:
- “akash1365yvmc4s7awdyj3n2sav7xfx76adc6dnmlx63”
pricing:
solana:
denom: uakt
amount: 10

deployment:
solana:
akash:
profile: solana
count: 1

定价:请注意会有多个不同的服务提供商出价。这种情况下会有两个不同的提供商碰巧都愿意接受1uAKT的价格。这意味着每个区块仅需1uAKT或者0.000001AKT就可以创建租用合约来执行任何部署。
定价设置了限制,也就是你设定用多少uAKT来支付每个区块的租金(每6秒产生一个区块)。各个提供商们就知道如何对你的部署进行投标了。
如果每个区块1uAKT的话,按照2021.5.31的AKT实时价格3.28USDT来计算,你需要每月支付((1*((60/6)6024*30.436875))/10^6)*3.28 = $1.44。
注意solana.yml文件里面的signed by 必须是akash1365yvmc4s7awdyj3n2sav7xfx76adc6dnmlx63。
原因请查看如下链接的文档

Signed by 是一个“验证”的事情。在提供商确认报价并被AKASH 网络批准后,他们会得到AKASH的签名,以其确保安全性和可靠性。
更多关于使用SDL(堆栈定义语言)来编写AKASH清单请查询以下地址

6. 创建部署
akash tx deployment create solana.yml
–from default
–node $AKASH_NODE
–chain-id $AKASH_CHAIN_ID
–gas-prices=“0.025uakt” --gas=“auto” --gas-adjustment=1.15

如果指令以Error: RPC error -32603 - Internal error: timed out waiting for tx to be included in a block结束的话,请不用担心。你可以从AKASH区块链上查询并找到你的部署ID
$ akash query txs
–events “message.sender=$AKASH_ACCOUNT_ADDRESS&message.action=create-deployment”
–page 1 --limit 999999
| jq -r ‘.txs | [ .tx.body.messages.id ] | @csv’ |
tail -5
“akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h”,“1172777”

查询部署:
我明确不会导出以下3个“SEQ”变量,以免执行信息失败。
如果你碰到以下这个错误提示,简单的执行“unset AKASH_DESQ”即可
信息索引: 0: Deployment closed’ error on ‘akash tx deployment create’ later(部署已关闭,船舰akash tx部署时出错)。
$ AKASH_DSEQ=1172777
$ AKASH_GSEQ=1
$ AKASH_OSEQ=1

$ akash query deployment get
–owner $AKASH_ACCOUNT_ADDRESS
–node $AKASH_NODE
–dseq $AKASH_DSEQ

deployment:
created_at: “1172779”
deployment_id:
dseq: “1172777”
owner: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h
state: active
version: R+bMsK3+N7Wtf8MWmUqoIJTgagXPunxFJqV4EXZahYE=
escrow_account:
balance:
amount: “5000000”
denom: uakt
id:
scope: deployment
xid: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h/1172777
owner: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h
settled_at: “1172791”
state: open
transferred:
amount: “0”
denom: uakt
groups:

  • created_at: “1172779”
    group_id:
    dseq: “1172777”
    gseq: 1
    owner: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h
    group_spec:
    name: akash
    requirements:
    attributes:
    - key: host
    value: akash
    signed_by:
    all_of:
    any_of:
    - akash1365yvmc4s7awdyj3n2sav7xfx76adc6dnmlx63
    resources:
    • count: 1
      price:
      amount: “10”
      denom: uakt
      resources:
      cpu:
      attributes:
      units:
      val: “100”
      endpoints:
      • kind: RANDOM_PORT
        memory:
        attributes:
        quantity:
        val: “536870912”
        storage:
        attributes:
        quantity:
        val: “536870912”
        state: open

你或许已经注意到了,5AKT代币现在在escrow_account这个账户里并且你的akash钱包里面也相应的减少了5AKT。
一旦你创建租约,这些代币会由改部署使用。当你结束相应租约或者部署后这些代币会很快返回你的钱包(当然时减去租赁本身的费用)。
更多部署信息请查看,

7. 获取市场报价
我们现在需要查看各个提供商的市场报价,接受那些我们觉得满意的报价。然后创建租约并发送我们的部署清单,让我们的部署真正的运行起来。
$ akash query market bid list
–owner=$AKASH_ACCOUNT_ADDRESS
–node $AKASH_NODE
–dseq $AKASH_DSEQ
–state open

bids:

  • bid:
    bid_id:
    dseq: “1172777”
    gseq: 1
    oseq: 1
    owner: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h
    provider: akash10cl5rm0cqnpj45knzakpa4cnvn5amzwp4lhcal
    created_at: “1172780”
    price:
    amount: “1”
    denom: uakt
    state: open
    escrow_account:
    balance:
    amount: “50000000”
    denom: uakt
    id:
    scope: bid
    xid: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h/1172777/1/1/akash10cl5rm0cqnpj45knzakpa4cnvn5amzwp4lhcal
    owner: akash10cl5rm0cqnpj45knzakpa4cnvn5amzwp4lhcal
    settled_at: “1172780”
    state: open
    transferred:
    amount: “0”
    denom: uakt
  • bid:
    bid_id:
    dseq: “1172777”
    gseq: 1
    oseq: 1
    owner: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h
    provider: akash1f6gmtjpx4r8qda9nxjwq26fp5mcjyqmaq5m6j7
    created_at: “1172780”
    price:
    amount: “1”
    denom: uakt
    state: open
    escrow_account:
    balance:
    amount: “50000000”
    denom: uakt
    id:
    scope: bid
    xid: akash1h24fljt7p0nh82cq0za0uhsct3sfwsfu9w3c9h/1172777/1/1/akash1f6gmtjpx4r8qda9nxjwq26fp5mcjyqmaq5m6j7
    owner: akash1f6gmtjpx4r8qda9nxjwq26fp5mcjyqmaq5m6j7
    settled_at: “1172780”
    state: open
    transferred:
    amount: “0”
    denom: uakt
    pagination:
    next_key: null
    total: “0”

将AKASH_PROVEIDER环境变量设置为你从市场上挑选价格合适的服务提供商。
AKASH_PROVIDER=akash10cl5rm0cqnpj45knzakpa4cnvn5amzwp4lhcal

如果akash query market bid list没有显示任何的报价,请确保你删除AKASH_PROVIDER 环境变量。
8. 创建租约/接受投标
通过运行以下命令来为上述所选的提供商的投标创建租约。
akash tx market lease create
–chain-id $AKASH_CHAIN_ID
–node $AKASH_NODE
–owner $AKASH_ACCOUNT_ADDRESS
–dseq $AKASH_DSEQ
–gseq $AKASH_GSEQ
–oseq $AKASH_OSEQ
–provider $AKASH_PROVIDER
–from default
–gas-prices=“0.025uakt” --gas=“auto” --gas-adjustment=1.15

请注意:一旦租约创建,提供商将开始借记你不熟的托管账户,即使你还没有通过下文的上传清单步骤来完成部署。
9. 发送清单用以部署Solana节点
现在你需要将清单发送给提供商,从而让Solana节点部署启动。
akash provider send-manifest solana.yml
–node $AKASH_NODE
–dseq $AKASH_DSEQ
–provider $AKASH_PROVIDER
–from default

过一会,你就会看到你的部署如下图所示。
$ akash provider lease-status
–node $AKASH_NODE
–dseq $AKASH_DSEQ
–provider $AKASH_PROVIDER
–from default
{
“services”: {
“solana”: {
“name”: “solana”,
“available”: 1,
“total”: 1,
“uris”: null,
“observed_generation”: 1,
“replicas”: 1,
“updated_replicas”: 1,
“ready_replicas”: 1,
“available_replicas”: 1
}
},
“forwarded_ports”: {
“solana”: [
{
“host”: “cluster.sjc1p0.mainnet.akashian.io”,
“port”: 8899,
“externalPort”: 32509,
“proto”: “TCP”,
“available”: 1,
“name”: “solana”
}
]
}
}

最后的URL是cluster.sjc1p0.mainnet.akashian.io:32509, 为什么现在的端口是32509而不是8899呢?在本文的末尾会找到相应的答案(参见节点端口)
10. 在Akashnet上查看Solana的日志
在这里,你可以看到Solana节点的助记词
$ akash
–node “$AKASH_NODE”
provider lease-logs
–dseq “$AKASH_DSEQ”
–gseq “$AKASH_GSEQ”
–oseq “$AKASH_OSEQ”
–provider “$AKASH_PROVIDER”
–from default
–follow
[solana-648bbc8979-hrjq6] solana-faucet 1.6.10 (src:5d4654d2; feat:3533521759)
[solana-648bbc8979-hrjq6] solana-genesis 1.6.10 (src:5d4654d2; feat:3533521759)
[solana-648bbc8979-hrjq6] solana-keygen 1.6.10 (src:5d4654d2; feat:3533521759)
[solana-648bbc8979-hrjq6] solana-validator 1.6.10 (src:5d4654d2; feat:3533521759)
[solana-648bbc8979-hrjq6] + solana address
[solana-648bbc8979-hrjq6] Error: No such file or directory (os error 2)
[solana-648bbc8979-hrjq6] + echo Generating default keypair
[solana-648bbc8979-hrjq6] Generating default keypair
[solana-648bbc8979-hrjq6] + solana-keygen new --no-passphrase
[solana-648bbc8979-hrjq6] Generating a new keypair
[solana-648bbc8979-hrjq6] Wrote new keypair to /root/.config/solana/id.json
[solana-648bbc8979-hrjq6] ==============================================================================
[solana-648bbc8979-hrjq6] pubkey: 2tpqeMBuqQNd2F6pmQmb2Dyj1A6k2yqqCnWXuWh2pX14
[solana-648bbc8979-hrjq6] ==============================================================================
[solana-648bbc8979-hrjq6] Save this seed phrase to recover your new keypair:
[solana-648bbc8979-hrjq6] wagon layer regret misery divorce wild noodle rent actress reflect sister lift
[solana-648bbc8979-hrjq6] ==============================================================================

[solana-648bbc8979-hrjq6] [2021-05-31T13:06:27.045978808Z INFO solana_core::cluster_info]
[solana-648bbc8979-hrjq6] IP Address |Age(ms)| Node identifier | Version |Gossip| TPU |TPUfwd| TVU |TVUfwd|Repair|ServeR|ShredVer
[solana-648bbc8979-hrjq6] ------------------±------±---------------------------------------------±--------±-----±-----±-----±-----±-----±-----±-----±-------
[solana-648bbc8979-hrjq6] 127.0.0.1 me| 4558 | 3QDTDmtqV3rLDdkLVPzP5RLg9TdXLFA7QPzv6Eeo72fi | 1.6.10 | 8001 | 8003 | 8004 | 8000 | 8002 | 8006 | 8007 | 48122
[solana-648bbc8979-hrjq6] Nodes: 1
[solana-648bbc8979-hrjq6]
[solana-648bbc8979-hrjq6] RPC Address |Age(ms)| Node identifier | Version | RPC |PubSub|ShredVer
[solana-648bbc8979-hrjq6] ------------------±------±---------------------------------------------±--------±-----±-----±-------
[solana-648bbc8979-hrjq6] 127.0.0.1 me| 4558 | 3QDTDmtqV3rLDdkLVPzP5RLg9TdXLFA7QPzv6Eeo72fi | 1.6.10 | 8899 | 8900 | 48122
[solana-648bbc8979-hrjq6] RPC Enabled Nodes: 1

  1. 在Akashnet上查询你的Solana 节点
    如下图使用Solana’s json PRC API,你可以查询到相应的Solana节点。
    $ curl -s http://cluster.sjc1p0.mainnet.akashian.io:32509 -X POST -H “Content-Type: application/json” -d ’
    {“jsonrpc”:“2.0”,“id”:1, “method”:“getBlockTime”,“params”:[5]}
    ’ | jq -r ‘.result | todate’
    2021-05-31T13:05:39Z

$ curl -s http://cluster.sjc1p0.mainnet.akashian.io:32509 -X POST -H “Content-Type: application/json” -d ’
{“jsonrpc”:“2.0”,“id”:1, “method”:“getIdentity”}

{“jsonrpc”:“2.0”,“result”:{“identity”:“3QDTDmtqV3rLDdkLVPzP5RLg9TdXLFA7QPzv6Eeo72fi”},“id”:1}

$ curl -s http://cluster.sjc1p0.mainnet.akashian.io:32509 -X POST -H “Content-Type: application/json” -d ’
{“jsonrpc”:“2.0”, “id”:1, “method”:“getClusterNodes”}
’ | jq .
{
“jsonrpc”: “2.0”,
“result”: [
{
“featureSet”: 3533521759,
“gossip”: “127.0.0.1:8001”,
“pubkey”: “3QDTDmtqV3rLDdkLVPzP5RLg9TdXLFA7QPzv6Eeo72fi”,
“rpc”: “127.0.0.1:8899”,
“shredVersion”: 48122,
“tpu”: “127.0.0.1:8003”,
“version”: “1.6.10”
}
],
“id”: 1
}

  1. 终止部署
    当测试完成后,你可以按照如下图所示终止你的部署。
    akash tx deployment close
    –node $AKASH_NODE
    –chain-id $AKASH_CHAIN_ID
    –dseq $AKASH_DSEQ
    –owner $AKASH_ACCOUNT_ADDRESS
    –from default
    –gas-prices=“0.025uakt” --gas=“auto” --gas-adjustment=1.15

  2. 为部署存放更多的AKT代币
    如果你还不像终止这个部署的话,可以考虑存放更多的AKT代币到托管账户里。
    akash tx deployment deposit
    –from default
    –chain-id $AKASH_CHAIN_ID
    –node $AKASH_NODE 1000000uakt
    –dseq $AKASH_DSEQ
    –gas-prices=“0.025uakt” --gas=“auto” --gas-adjustment=1.15

  3. 正式solana验证器节点
    对于正式的solana验证器节点部署,你需要将清单文件做如下修改。有可能还会按照建议一并提高CPU内存和存储限制。


version: “2.0”

services:
solana:
image: solanalabs/solana:v1.6.10
expose:
- port: 8899
as: 8899
proto: tcp
to:
- global: true
- port: 8001
as: 8001
proto: tcp
to:
- global: true
- port: 8900
as: 8900
proto: tcp
to:
- global: true
- port: 8010
as: 8010
proto: udp
to:
- global: true
- port: 8011
as: 8011
proto: udp
to:
- global: true
- port: 8012
as: 8012
proto: udp
to:
- global: true
- port: 8013
as: 8013
proto: udp
to:
- global: true
- port: 8014
as: 8014
proto: udp
to:
- global: true
- port: 8015
as: 8015
proto: udp
to:
- global: true
- port: 8016
as: 8016
proto: udp
to:
- global: true
- port: 8017
as: 8017
proto: udp
to:
- global: true
- port: 8018
as: 8018
proto: udp
to:
- global: true
- port: 8019
as: 8019
proto: udp
to:
- global: true
- port: 8020
as: 8020
proto: udp
to:
- global: true
env:
- SOLANA_RUN_SH_CLUSTER_TYPE=mainnet-beta
- |
SOLANA_RUN_SH_VALIDATOR_ARGS=
–trusted-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2
–trusted-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ
–trusted-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ
–trusted-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S
–no-untrusted-rpc
–private-rpc
–entrypoint entrypoint.mainnet-beta.solana.com:8001
–entrypoint entrypoint2.mainnet-beta.solana.com:8001
–entrypoint entrypoint3.mainnet-beta.solana.com:8001
–entrypoint entrypoint4.mainnet-beta.solana.com:8001
–entrypoint entrypoint5.mainnet-beta.solana.com:8001
–expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d
–wal-recovery-mode skip_any_corrupted_record
–limit-ledger-size
–dynamic-port-range 8010-8020

profiles:
compute:
solana:
resources:
cpu:
units: 0.1
memory:
size: 512Mi
storage:
size: 512Mi
placement:
akash:
attributes:
host: akash
signedBy:
anyOf:
- “akash1365yvmc4s7awdyj3n2sav7xfx76adc6dnmlx63”
pricing:
solana:
denom: uakt
amount: 10

deployment:
solana:
akash:
profile: solana
count: 1

你可能需要公开更多的端口,例如在—dynamic-port-range 8010-8020参数中指定的端口。
唯一需要注意的是,不能按照原样直接导出非http/https(80/443)TCP端口,也就是所谓的节点端口比如说8899/tcp,8010:8020/udp等。
Akashnet的提供商在后台使用Kubernetes来运行你的部署。Kubernetes控制从—service-node-port-range指定的范围内分配端口(default:30000-32767)。
这意味着操作者首先需要部署Solana节点,然后检查提供商的Kubernetes为你的Akash 部署分配了哪些端口。
然后使用一些负载均衡器/反向代理(比如nginx/haprorxy/traefik)转发到这些端口。
你还需要告知Solana验证器使用负载平衡器的主机名。方法是通过Solana验证器节点的—public-rpc-addressHOST:PORT参数指定它。
然而,我们的目标仅仅是展示以下如何使用Akashnet 部署开发板而不是真的部署完整的Solana节点。
Solana的官方文档并没有推荐Docker用于正式部署
Solana正式节点推荐运行在12核,128Gi 内存,500Gi+固态硬盘上。而Akashnet是一个很新的网络并没有那么多提供商能满足这些硬件要求。
这不是一个投资建议!
如果你喜欢这篇文章,请在以下链接投它一票

附:
给我自己或者任何看到文章且想要继续推动的人几条备注
Solana docker 运行solana-run.sh
solana/build.sh at v1.6.10 · solana-labs/solana · GitHub, solana/run.sh at v1.6.10 · solana-labs/solana · GitHub
在实际运行Solana验证器之前,看一下solana-sys-tuner的可行性如何。
Starting a Validator | Solana Docs
设置 ulimit nofile=700000(好像Akash SDL在2021.5.31还不支持这一点)

格式可以优化一下, markdown编辑好, code的部分格式化下。