3. [Kubernetes deployment on AWS](#deploy-on-aws-cloud-amazon-web-services)
4. [Kubernetes deployment on GCP](#deploy-on-gcp-google-cloud-platform)
5. [Kubernetes deployment on AliCloud](#deploy-on-ali-cloud)
6. [Troubleshooting](#troubleshooting)
## Prerequisites
The TON node, whether it is validator or fullnode, requires a public IP address.
If your server is within an internal network or kubernetes you have to make sure that the required ports are available from the outside.
Also pay attention at [hardware requirements](https://docs.ton.org/participate/run-nodes/full-node) for TON fullnodes and validators. Pods and StatefulSets in this guide imply these requirements.
It is recommended to everyone to read Docker chapter first in order to get a better understanding about TON Docker image and its parameters.
| PUBLIC_IP | This will be a public IP address of your TON node. Normally it is the same IP address as your server's external IP. This also can be your proxy server or load balancer IP address. | yes | |
| GLOBAL_CONFIG_URL | TON global configuration file. Mainnet - https://ton.org/global-config.json, Testnet - https://ton.org/testnet-global.config.json | no | https://api.tontech.io/ton/wallet-mainnet.autoconf.json |
| DUMP_URL | URL to TON dump. Specify dump from https://dump.ton.org. If you are using testnet dump, make sure to download global config for testnet. | no | |
| VALIDATOR_PORT | UDP port that must be available from the outside. Used for communication with other nodes. | no | 30001 |
| CONSOLE_PORT | This TCP port is used to access validator's console. Not necessarily to be opened for external access. | no | 30002 |
| LITE_PORT | Lite-server's TCP port. Used by lite-client. | no | 30003 |
| LITESERVER | true or false. Set to true if you want up and running lite-server. | no | false |
| STATE_TTL | Node's state will be gc'd after this time (in seconds). | no | 86400 |
| ARCHIVE_TTL | Node's archived blocks will be deleted after this time (in seconds). | no | 86400 |
| THREADS | Number of threads used by validator-engine. | no | 8 |
| VERBOSITY | Verbosity level. | no | 3 |
| CUSTOM_ARG | validator-engine might have some undocumented arguments. This is reserved for the test purposes.<br/>For example you can pass **--logname /var/ton-work/log** in order to have log files. | no | |
### Run the node - the quick way
The below command runs docker container with a TON node, that will start synchronization process.
Notice **--network host** option, means that the Docker container will use the network namespace of the host machine.
In this case there is no need to map ports between the host and the container. The container will use the same IP address and ports as the host.
This approach simplifies networking configuration for the container, and usually is used on the dedicated server with assigned public IP.
Keep in mind that this option can also introduce security concerns because the container has access to the host's network interfaces directly, which might not be desirable in a multi-tenant environment.
Check your firewall configuration and make sure that at least UDP port 43677 is publicly available.
Find out your PUBLIC_IP:
```
curl -4 ifconfig.me
```
and replace it in the command below:
```
docker run -d --name ton-node -v /data/db:/var/ton-work/db \
last key block is [ w=-1 s=9223372036854775808 seq=34879845 rcEsfLF3E80PqQPWesW+rlOY2EpXd5UDrW32SzRWgus= C1Hs+q2Vew+WxbGL6PU1P6R2iYUJVJs4032CTS/DQzI= ]
getnextkey: [Error : 651 : not inited]
downloading state (-1,8000000000000000,38585739):9E86E166AE7E24BAA22762766381440C625F47E2B11D72967BB58CE8C90F7EBA:5BFFF759380097DF178325A7151E9C0571C4E452A621441A03A0CECAED970F57: total=1442840576 (71MB/s)downloading state (-1,8000000000000000,38585739):9E86E166AE7E24BAA22762766381440C625F47E2B11D72967BB58CE8C90F7EBA:5BFFF759380097DF178325A7151E9C0571C4E452A621441A03A0CECAED970F57: total=1442840576 (71MB/s)
finished downloading state (-1,8000000000000000,38585739):9E86E166AE7E24BAA22762766381440C625F47E2B11D72967BB58CE8C90F7EBA:5BFFF759380097DF178325A7151E9C0571C4E452A621441A03A0CECAED970F57: total=4520747390
getnextkey: [Error : 651 : not inited]
getnextkey: [Error : 651 : not inited]
```
As you noticed we have mounted docker volume to a local folder **/data/db**.
Go inside this folder on your server and check if its size is growing (```sudo du -h .*```)
Now connect to the running container:
```
docker exec -ti ton-node /bin/bash
```
and try to connect and execute **getconfig** command via validator-engine-console:
```
validator-engine-console -k client -p server.pub -a localhost:$(jq .control[].port <<<cat/var/ton-work/db/config.json)-cgetconfig
```
if you see a json output that means that validator-engine is up, now execute **last** command with a lite-client:
```
lite-client -a localhost:$(jq .liteservers[].port <<<cat/var/ton-work/db/config.json)-pliteserver.pub-clast
```
if you see the following output:
```
conn ready
failed query: [Error : 652 : adnl query timeout]
cannot get server version and time (server too old?)
server version is too old (at least 1.1 with capabilities 1 required), some queries are unavailable
fatal error executing command-line queries, skipping the rest
```
it means that the lite-server is up, but the node is not synchronized yet.
Once the node is synchronized, the output of **last** command will be similar to this one:
```
conn ready
server version is 1.1, capabilities 7
server time is 1719306580 (delta 0)
last masterchain block is (-1,8000000000000000,20435927):47A517265B25CE4F2C8B3058D46343C070A4B31C5C37745390CE916C7D1CE1C5:279F9AA88C8146257E6C9B537905238C26E37DC2E627F2B6F1D558CB29A6EC82
server time is 1719306580 (delta 0)
zerostate id set to -1:823F81F306FF02694F935CF5021548E3CE2B86B529812AF6A12148879E95A128:67E20AC184B9E039A62667ACC3F9C00F90F359A76738233379EFA47604980CE8
```
If you can't make it working, refer to the [Troubleshooting](#troubleshooting) section below.
### Use validator-engine-console
```docker exec -ti ton-node /bin/bash```
```validator-engine-console -k client -p server.pub -a 127.0.0.1:$(jq .control[].port <<<cat/var/ton-work/db/config.json)```
### Use lite-client
```docker exec -ti ton-node /bin/bash```
```lite-client -p liteserver.pub -a 127.0.0.1:$(jq .liteservers[].port <<<cat/var/ton-work/db/config.json)```
If you use lite-client outside the Docker container, copy the **liteserver.pub** from the container:
Often Kubernetes cluster is located in DMZ, is behind corporate firewall and access is controlled via proxy configuration.
In this case we can't use host's network stack (**hostNetwork: true**) within a Pod and must manually proxy the access to the pod.
A **LoadBalancer** service type automatically provisions an external load balancer (such as those provided by cloud providers like AWS, GCP, Azure) and assigns a public IP address to your service. In a non-cloud environment or in a DMZ setup, you need to manually configure the load balancer.
If you are running your Kubernetes cluster on-premises or in an environment where an external load balancer is not automatically provided, you can use a load balancer implementation like MetalLB.
#### Prepare
Select the node where persistent storage will be located for TON validator.
* Add a label to this particular node. By this label our pod will know where to be deployed:
#### After installing AWS LB, load balancer is still not available (pending):
```
kubectl get deployment -n kube-system aws-load-balancer-controller
```
Solution:
Try to install AWS LoadBalancer using ```Helm``` way.
---
#### After installing AWS LB and running ton node, service shows error:
```k describe service validator-engine-srv```
```log
Failed build model due to unable to resolve at least one subnet (0 match VPC and tags: [kubernetes.io/role/elb])
```
Solution:
You haven't labeled the AWS subnets with the correct resource tags.
* Public Subnets should be resource tagged with: kubernetes.io/role/elb: 1
* Private Subnets should be tagged with: kubernetes.io/role/internal-elb: 1
* Both private and public subnets should be tagged with: kubernetes.io/cluster/${your-cluster-name}: owned
* or if the subnets are also used by non-EKS resources kubernetes.io/cluster/${your-cluster-name}: shared
So create tags for at least one subnet:
```
kubernetes.io/role/elb: 1
kubernetes.io/cluster/<YOUR_CLUSTER_NAME>: owner
```
---
#### AWS Load Balancer works, but I still see ```[no nodes]``` in validator's log
It is required to add the security group for the EC2 instances to the load balancer along with the default security group.
It's a misleading that the default security group has "everything open."
Add security group (default name is usually something like 'launch-wizard-1').
And make sure you allow the ports you specified or default ports 30001/udp, 30002/tcp and 30003/tcp.
You can also set inbound and outbound rules of new security group to allow ALL ports and for ALL protocols and for source CIDR 0.0.0.0/0 for testing purposes.
---
#### Pending PersistentVolumeClaim ```Waiting for a volume to be created either by the external provisioner 'ebs.csi.aws.com' or manually by the system administrator.```
Solution:
Configure Amazon EBS CSI driver for working PersistentVolumes in EKS.
Warning LoadBalancerMixedProtocolNotSupported 7m8s g-cloudprovider LoadBalancers with multiple protocols are not supported.
Normal EnsuringLoadBalancer 113s (x7 over 7m8s) service-controller Ensuring load balancer
Warning SyncLoadBalancerFailed 113s (x7 over 7m8s) service-controller Error syncing load balancer: failed to ensure load balancer: mixed protocol is not supported for LoadBalancer