Build a Cloud Provider

Prerequisites of an Akash Provider

Wallet Funding - Minimum of 5 AKT

Placing a bid on an order requires a 5 AKT deposit. This deposit is fully refunded after the bid is won/lost.
The steps to create an Akash account are covered in the Provider setup section of this document.

Kubernetes Cluster

  • A full Kubernetes cluster is required.
  • The cluster must have outbound internet access and be reachable from the internet.
  • Please use this guide for ALL Kubernetes related configurations. This guide covers a full cluster build, should it be needed, AND important details for new/pre-existing cluster configurations of custom resource definitions and ingress controllers for the Akash provider.

Custom Kubernetes Cluster Settings

Akash Providers are deployed in many environments and we will make additions to these sections as when nuances are discovered.

Quickstart Guides

Create a Kubernetes cluster and start your first provider
Already have a Kubernetes cluster? Start here!

Akash Provider Setup

Provider Setup Overview

The following sections will explore each step of the Akash provider setup in detail.

STEP1 - Select a Host to Run the Akash Provider

The Akash provider can be installed on any Kubernetes master or worker node. Or if preferred the provider may be installed on a separate host outside of the Kubernetes cluster.
  • NOTE - if the Provider is installed on a Kubernetes host - ensure that it does not reside on the same host as the Ingress Controller as this could cause TCP port 8443 conflicts.

STEP2 - Install Akash Software

The Akash software install process on a Linux server is shown in this step.
Specify the Akash Version
  • These commands will retrieve the latest, stable version of the Akash software, store the version in a local variable, and install that version.
1
AKASH_VERSION="$(curl -s "https://raw.githubusercontent.com/ovrclk/net/master/mainnet/version.txt")"
2
3
curl https://raw.githubusercontent.com/ovrclk/akash/master/godownloader.sh | sh -s -- "v$AKASH_VERSION"
Copied!
Add Akash Install Location to User’s Path
Add the software’s install location to the user’s path for easy use of Akash commands.
NOTE - below we provide the steps to add the Akash install directory to a user’s path on a Linux Ubuntu server. Please take a look at a guide for your operating system and how to add a directory to a user’s path.
Open the user’s path file in an editor:
1
vi /etc/environment
Copied!
View within text editor prior to the update:
1
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
Copied!
Add the following directory, which is the Akash install location, to PATH:
1
/root/bin
Copied!
View within the text editor following the update:
1
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/bin"
Copied!
Make the new path active in the current session:
1
​​source /etc/environment
Copied!
Display the version of Akash software installed. This confirms the software installed and that the new user path addition worked.
1
akash version
Copied!
Expected result:
1
[email protected]:~# akash version
2
v0.14.1
Copied!

STEP3 - Create/Import Akash Account

For a Provider to bid on leases an account is needed with minimum funding of 5 AKT. An account can be created by using the commands of this section. Alternatively an existing account could be imported for provider use.
Specify a key with your choice of name:
1
AKASH_KEY_NAME=<name>
Copied!
Specify the location of the keyring on the provider:
1
AKASH_KEYRING_BACKEND=file
Copied!
Create the new account and store the encrypted private key in the keyring
  • Enter a passphrase of your choice when prompted
1
akash --keyring-backend "$AKASH_KEYRING_BACKEND" keys add "$AKASH_KEY_NAME"
Copied!
Expected results:
1
[email protected]:~# AKASH_KEY_NAME=providerkey
2
[email protected]:~# ​​AKASH_KEYRING_BACKEND=file
3
[email protected]:~# akash --keyring-backend "$AKASH_KEYRING_BACKEND" keys add "$AKASH_KEY_NAME"
4
Enter keyring passphrase:
5
Re-enter keyring passphrase:
6
7
- name: providerkey
8
type: local
9
address: akash16hxyzpwgp9elpl52yvll9gczr3vyanfgmdvh4x
10
pubkey: akashpub1addwnpepqwz556cp568gk6tj9yxmqshmqad6pj0nnfnqzfufez2fd2jh94fr6y763nc
11
mnemonic: ""
12
threshold: 0
13
pubkeys: []
14
15
16
**Important** write this mnemonic phrase in a safe place.
17
It is the only way to recover your account if you ever forget your password.
18
19
escape dry gate <redacted> prosper human
Copied!

STEP4 - Verify Account Balance

We should verify the minimum account balance for the provider now that the account has been set up. As mentioned, the account needs slightly more than 5 AKT at a minimum.
Specify the Akash network to query (in this case the mainnet):
1
AKASH_NET="https://raw.githubusercontent.com/ovrclk/net/master/mainnet"
Copied!
Query the network for an available node to communicate with:
1
export AKASH_NODE="$(curl -s "$AKASH_NET/rpc-nodes.txt" | shuf -n 1)"
Copied!
Store the account created in the previous step. Replace the variable portion with your account address (I.e. account such as akash1wpfyf47tzu70q3vu893mghz657gk2kgkuaj5zq):
1
AKASH_ACCOUNT_ADDRESS=<account-address>
Copied!
Get your account balance:
1
akash --node "$AKASH_NODE" query bank balances "$AKASH_ACCOUNT_ADDRESS"
Copied!
Example output:
1
[email protected]:~# akash --node "$AKASH_NODE" query bank balances "$AKASH_ACCOUNT_ADDRESS"
2
balances:
3
- amount: "15000000"
4
denom: uakt
5
pagination:
6
next_key: null
7
total: "0"
Copied!

STEP5 - Create the Provider

Use the host that the Akash software was installed on for this section.
Deployment Domain
  • Create the environment variable of PROVIDER_AKASH_DOMAIN
  • This domain is used whenever a lease owner needs to speak directly with the provider to send a manifest or get a lease status
1
export PROVIDER_AKASH_DOMAIN=<provider-host-domain-name>
Copied!
Create provider.yaml File
  • Create a file with the name of provider.yaml and add the contents below
  • NOTE - Please replace <PROVIDER_AKASH_DOMAIN> variable with your akash domain (i.e. provider.<yourdomain>.com)
  • Attributes - a thorough discussion of provider attributes can be found here.
1
host: https://<PROVIDER_AKASH_DOMAIN>:8443
2
attributes:
3
- key: host
4
value: <nameOfYourOrganization>
Copied!
Create the Akash Provider
  • Register the provider on the Akash Network
  • Three new environment variables are added that the provider create command will use
  • Replace the AKASH_PROVIDER_KEY with the name of the key created earlier (I.e. providerkey in the example)
  • Replace the AKASH_HOME with the location of the keychain (I.e. /root/.akash in the example)
1
export AKASH_CHAIN_ID="$(curl -s "$AKASH_NET/chain-id.txt")"
2
AKASH_PROVIDER_KEY=<key-name>
3
AKASH_HOME=<keyring-location>
4
5
export AKASH_GAS_PRICES=0.025uakt
6
export AKASH_GAS=auto
7
export AKASH_GAS_ADJUSTMENT=1.3
Copied!
1
akash tx provider create provider.yaml --from $AKASH_PROVIDER_KEY --home=$AKASH_HOME --keyring-backend=$AKASH_KEYRING_BACKEND --node=$AKASH_NODE --chain-id=$AKASH_CHAIN_ID
Copied!
Example of Creating the Provider
1
export AKASH_CHAIN_ID="$(curl -s "$AKASH_NET/chain-id.txt")"
2
AKASH_PROVIDER_KEY=providerkey
3
AKASH_HOME=/root/.akash
Copied!
1
[email protected]:~# akash tx provider create provider.yaml --from $AKASH_PROVIDER_KEY --home=$AKASH_HOME --keyring-backend=$AKASH_KEYRING_BACKEND --node=$AKASH_NODE --chain-id=$AKASH_CHAIN_ID
2
3
Enter keyring passphrase:
4
5
{"body":{"messages":[{"@type":"/akash.provider.v1beta1.MsgCreateProvider","owner":"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx","host_uri":"https://$DEPLOYMENT_HOSTNAME:8443","attributes":[{"key":"host","value":"chainzero"}],"info":{"email":"","website":""}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[{"denom":"uakt","amount":"5000"}],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
6
7
confirm transaction before signing and broadcasting [y/N]: y
8
9
{"height":"3413672","txhash":"E9CA2D1ED5FF449E132531C9F6CCBD41F95F01D71C745005E00432852204C564","codespace":"","code":0,"data":"0A110A0F6372656174652D70726F7669646572","raw_log":"[{\"events\":[{\"type\":\"akash.v1\",\"attributes\":[{\"key\":\"module\",\"value\":\"provider\"},{\"key\":\"action\",\"value\":\"provider-created\"},{\"key\":\"owner\",\"value\":\"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"create-provider\"},{\"key\":\"sender\",\"value\":\"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"akash17xpfvakm2amg962yls6f84z3kell8c5lazw8j8\"},{\"key\":\"sender\",\"value\":\"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx\"},{\"key\":\"amount\",\"value\":\"5000uakt\"}]}]}]","logs":[{"msg_index":0,"log":"","events":[{"type":"akash.v1","attributes":[{"key":"module","value":"provider"},{"key":"action","value":"provider-created"},{"key":"owner","value":"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx"}]},{"type":"message","attributes":[{"key":"action","value":"create-provider"},{"key":"sender","value":"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx"}]},{"type":"transfer","attributes":[{"key":"recipient","value":"akash17xpfvakm2amg962yls6f84z3kell8c5lazw8j8"},{"key":"sender","value":"akash1xmz9es9ay9ln9x2m3q8dlu0alxf0ltce7ykjfx"},{"key":"amount","value":"5000uakt"}]}]}],"info":"","gas_wanted":"200000","gas_used":"64055","tx":null,"timestamp":""}
10
Copied!

STEP6 - Create a TLS Certificate

Generate Server Certificate

  • Note: If it errors with Error: certificate error: cannot overwrite certificate, then add --overwrite should you want to overwrite the cert. Normally you can ignore that error and proceed with publishing the cert (next step).
1
akash tx cert generate server $PROVIDER_AKASH_DOMAIN --chain-id $AKASH_CHAIN_ID --keyring-backend $AKASH_KEYRING_BACKEND --from $AKASH_PROVIDER_KEY --home=$AKASH_HOME --node=$AKASH_NODE --gas-prices="0.025uakt" --gas="auto" --gas-adjustment=1.15
Copied!

Publish Certificate

1
akash tx cert publish server --chain-id $AKASH_CHAIN_ID --keyring-backend $AKASH_KEYRING_BACKEND --from $AKASH_PROVIDER_KEY --home=$AKASH_HOME --node=$AKASH_NODE --gas-prices="0.025uakt" --gas="auto" --gas-adjustment=1.15
Copied!

STEP7 - Configure Kubectl

If the provider is on a non-Kubernetes master node, kubectl and the kubeconfig file might not be present. In this step we will create the kubeconfig file on the provider host which is necessary when we try to start the provider.
Verify Kubeconfig File
  • On the provider host, verify if the kubeconfig file is present
  • We are looking for the presence of the .kube directory within the user’s home directory
1
cd ~
2
ls -al
Copied!
Example output of directory contents
  • In this example the .kube directory does not exist and we will need to create it
  • If the directory does exist and you are able to conduct kubectl commands (I.e. “kubectl get nodes”), feel free to skip forward to STEP8
2
total 56
3
drwx------ 8 root root 4096 Nov 8 21:23 .
4
drwxr-xr-x 19 root root 4096 Nov 1 14:53 ..
5
drwx------ 5 root root 4096 Nov 8 21:06 .akash
6
drwx------ 3 root root 4096 Nov 2 18:49 .ansible
7
-rw------- 1 root root 74 Nov 2 16:38 .bash_history
8
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
9
drwx------ 2 root root 4096 Nov 2 16:38 .cache
10
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
11
drwx------ 2 root root 4096 Nov 1 14:53 .ssh
12
-rw------- 1 root root 7349 Nov 8 21:03 .viminfo
13
drwxr-xr-x 2 root root 4096 Nov 8 20:38 bin
14
-rw-r--r-- 1 root root 118 Nov 8 21:03 provider.yaml
15
drwxr-xr-x 4 root root 4096 Nov 1 14:53 snap
Copied!
Create a .kube Directory
1
mkdir .kube
Copied!
Copy Kubeconfig to the Provider
  • We will use the following command to copy the config file from the Kubernetes master to the provider host
  • Replace the username and IP address parts of the command
1
scp <username>@<ipaddress>:/root/.kube/config /root/.kube/config
Copied!
Install Kubectl on the Provider
1
stable=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
2
3
curl -LO https://storage.googleapis.com/kubernetes-release/release/${stable}/bin/linux/amd64/kubectl
4
5
chmod +x ./kubectl
6
7
sudo mv ./kubectl /usr/local/bin/kubectl
Copied!
Verify Kubectl
  • Following the copy of the kubeconfig file and the kubectl install, you should be able to execute commands like “kubectl get nodes” as shown in example below
1
[email protected]:~# kubectl get nodes
2
NAME STATUS ROLES AGE VERSION
3
node1 Ready control-plane,master 6d2h v1.22.3
4
node2 Ready control-plane,master 6d2h v1.22.3
5
node3 Ready <none> 6d2h v1.22.3
Copied!

STEP8 - Start the Provider

In our final step the provider is started. We will run the provider process as a service to ensure it remains active across server reboots.
Domain Name Notes
  • The variable used as the value for --cluster-public-hostname during provider start up and is the publicly accessible hostname of the Kubernetes cluster.
  • If multiple master nodes exist in the Kubernetes cluster, either the DNS record should point to the IP addresses of all master nodes or an alternative load balancing strategy should be used.
Store Keyring Passphrase
1
echo "mypassword" | tee /root/akash/key-pass.txt
Copied!
Create Script
1
cat > /root/akash/start-provider.sh << 'EOF'
2
#!/usr/bin/env bash
3
4
export AKASH_NET="https://raw.githubusercontent.com/ovrclk/net/master/mainnet"
5
export AKASH_NODE="$(curl -s "$AKASH_NET/rpc-nodes.txt" | shuf -n 1)"
6
export AKASH_HOME=/root/.akash
7
export AKASH_CHAIN_ID="$(curl -s "$AKASH_NET/chain-id.txt")"
8
export AKASH_PROVIDER_KEY=<REPLACE-WITH-PROVIDER-KEY>
9
export PROVIDER_INGRESS_DOMAIN=<REPLACE-WITH-PUBLIC-DOMAIN>
10
export PROVIDER_AKASH_DOMAIN=<REPLACE-WITH-PUBLIC-DOMAIN>
11
12
cd /root/akash
13
( sleep 2s; cat key-pass.txt; cat key-pass.txt ) | \
14
/root/bin/akash provider run \
15
--home $AKASH_HOME \
16
--chain-id $AKASH_CHAIN_ID \
17
--node $AKASH_NODE \
18
--keyring-backend=file \
19
--from $AKASH_PROVIDER_KEY \
20
--fees 1000uakt \
21
--kubeconfig $KUBECONFIG \
22
--cluster-k8s true \
23
--deployment-ingress-domain $PROVIDER_INGRESS_DOMAIN \
24
--deployment-ingress-static-hosts true \
25
--bid-price-strategy scale \
26
--bid-price-cpu-scale 0.001 \
27
--bid-price-memory-scale 0.001 \
28
--bid-price-storage-scale 0.00001 \
29
--bid-price-endpoint-scale 0 \
30
--bid-deposit 5000000uakt \
31
--cluster-node-port-quantity 1000 \
32
--cluster-public-hostname $PROVIDER_AKASH_DOMAIN
33
34
EOF
Copied!
Make Script Executable
1
chmod +x /root/akash/start-provider.sh
Copied!
Create Service
1
cat > /etc/systemd/system/akash-provider.service << 'EOF'
2
[Unit]
3
Description=Akash Provider
4
After=network.target
5
6
[Service]
7
User=root
8
Group=root
9
ExecStart=/root/akash/start-provider.sh
10
KillSignal=SIGINT
11
Restart=on-failure
12
RestartSec=15
13
StartLimitInterval=200
14
StartLimitBurst=10
15
#LimitNOFILE=65535
16
17
[Install]
18
WantedBy=multi-user.target
19
EOF
Copied!
Start and Persist the Provider Service
1
systemctl daemon-reload
2
systemctl start akash-provider
3
systemctl enable akash-provider
Copied!
Confirm the Provide Status
1
journalctl -u akash-provider --since '5 min ago' -f
Copied!

STEP9 - Create the Hostname Operator Service

1
cat /etc/systemd/system/akash-hostname-operator.service
2
[Unit]
3
Description=Akash Hostname Operator
4
After=network.target
5
6
[Service]
7
User=root
8
Group=root
9
ExecStart=akash provider hostname-operator
10
KillSignal=SIGINT
11
Restart=on-failure
12
RestartSec=15
13
StartLimitInterval=200
14
StartLimitBurst=10
15
#LimitNOFILE=65535
16
17
[Install]
18
WantedBy=multi-user.target
Copied!

STEP10- Start the Hostname Operator Service

1
systemctl start akash-hostname-operator
2
systemctl enable akash-hostname-operator
Copied!