262 lines
8.9 KiB
Plaintext
262 lines
8.9 KiB
Plaintext
Step 002: Plan wdrozenia Solana RPC (Agave mainnet, non-voting, private RPC + Geyser->Postgres + monitoring + NOC tmux)
|
|
|
|
Zalozenia (default):
|
|
- WG iface: wg0, WG subnet: 10.66.66.0/24, WG IP baremetala: 10.66.66.1
|
|
- Public iface: eth0, public IP: 149.50.116.219
|
|
- RPC: 8899 (HTTP), WS: 8900 (WS = RPC_PORT+1)
|
|
- Postgres (lokalnie): 5432 (DB: geyser, user: geyser)
|
|
- (Optional) Yellowstone gRPC: 10000 (tylko po WG)
|
|
- Prometheus: 9090, Grafana: 3000, node_exporter: 9100 (tylko po WG)
|
|
- Dynamic port range (cluster): 8000-8020/udp (public eth0)
|
|
- User: solana
|
|
- Dirs:
|
|
- /var/lib/solana (ledger/accounts)
|
|
- /etc/solana (configs)
|
|
- /var/log/solana (logs)
|
|
|
|
0) Preconditions (check)
|
|
# WG dziala
|
|
ip -4 a show wg0
|
|
wg show
|
|
|
|
# SSH po WG dziala (z laptop/VPS):
|
|
# ssh user@10.66.66.1
|
|
|
|
1) Packages
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
tmux btop \
|
|
sysstat iotop \
|
|
ethtool nstat \
|
|
chrony curl jq git ca-certificates \
|
|
ripgrep \
|
|
smartmontools nvme-cli \
|
|
build-essential pkg-config libssl-dev \
|
|
clang llvm-dev libclang-dev \
|
|
cmake protobuf-compiler libudev-dev zlib1g-dev
|
|
|
|
2) Users/Dirs
|
|
sudo getent group solana >/dev/null || sudo groupadd --system solana
|
|
sudo id -u solana >/dev/null 2>&1 || sudo useradd --system --gid solana \
|
|
--home-dir /var/lib/solana --create-home --shell /bin/bash solana
|
|
|
|
sudo install -d -o root -g root -m 0755 /etc/solana /opt/solana/bin
|
|
sudo install -d -o solana -g solana -m 0750 \
|
|
/var/lib/solana /var/lib/solana/ledger /var/lib/solana/accounts /var/log/solana
|
|
|
|
# identity permissions (po utworzeniu pliku):
|
|
# sudo chown solana:solana /var/lib/solana/identity.json
|
|
# sudo chmod 600 /var/lib/solana/identity.json
|
|
|
|
2A) Storage (rekomendowane)
|
|
# Variant A: jesli /dev/nvme0n1 jest wolny i chcesz go podzielic 50/50:
|
|
# doc/step-002a-storage-nvme0n1-xfs.txt
|
|
#
|
|
# Variant B (mpabi): masz juz 2x NVMe z XFS:
|
|
# - SOLACCT na accounts (nvme0n1p1)
|
|
# - SOLLEDG na ledger (nvme1n1p1)
|
|
# doc/step-002a-storage-existing-solacct-solledg-xfs.txt
|
|
|
|
3) Firewall/WG binding (private-only)
|
|
# UFW: deny everything inbound by default
|
|
sudo ufw default deny incoming
|
|
sudo ufw default allow outgoing
|
|
|
|
# WireGuard (public)
|
|
sudo ufw allow 51820/udp
|
|
|
|
# SSH only via WG
|
|
sudo ufw allow in on wg0 to any port 22 proto tcp
|
|
sudo ufw deny in on eth0 to any port 22 proto tcp
|
|
|
|
# RPC/WS only via WG
|
|
sudo ufw allow in on wg0 to any port 8899 proto tcp
|
|
sudo ufw allow in on wg0 to any port 8900 proto tcp
|
|
sudo ufw deny in on eth0 to any port 8899 proto tcp
|
|
sudo ufw deny in on eth0 to any port 8900 proto tcp
|
|
|
|
# Yellowstone gRPC only via WG
|
|
sudo ufw allow in on wg0 to any port 10000 proto tcp
|
|
sudo ufw deny in on eth0 to any port 10000 proto tcp
|
|
|
|
# Monitoring only via WG
|
|
sudo ufw allow in on wg0 to any port 9100 proto tcp
|
|
sudo ufw allow in on wg0 to any port 9090 proto tcp
|
|
sudo ufw allow in on wg0 to any port 3000 proto tcp
|
|
sudo ufw deny in on eth0 to any port 9100 proto tcp
|
|
sudo ufw deny in on eth0 to any port 9090 proto tcp
|
|
sudo ufw deny in on eth0 to any port 3000 proto tcp
|
|
|
|
# Cluster ports (public, inbound) for sync (UDP)
|
|
sudo ufw allow in on eth0 to any port 8000:8020 proto udp
|
|
# (opcjonalnie) jesli bedziesz mial problemy z reachability:
|
|
# sudo ufw allow in on eth0 to any port 8000:8020 proto tcp
|
|
|
|
sudo ufw enable
|
|
sudo ufw status verbose
|
|
|
|
4) Validator (Agave) config + systemd (non-voting RPC-only)
|
|
# sysctl baseline (Agave startup checks)
|
|
sudo tee /etc/sysctl.d/90-agave.conf >/dev/null <<'EOF'
|
|
net.core.rmem_max = 134217728
|
|
net.core.wmem_max = 134217728
|
|
EOF
|
|
sudo sysctl --system
|
|
|
|
# ulimit baseline
|
|
sudo tee /etc/security/limits.d/90-solana.conf >/dev/null <<'EOF'
|
|
* soft nofile 1000000
|
|
* hard nofile 1000000
|
|
EOF
|
|
|
|
# Agave tools (solana-keygen etc.) for solana user
|
|
sudo -u solana -H bash -lc 'sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"'
|
|
|
|
# Copy binaries to /opt/solana/bin (avoid symlink permission gotchas)
|
|
sudo cp -a /var/lib/solana/.local/share/solana/install/active_release/bin/. /opt/solana/bin/
|
|
sudo find /opt/solana/bin -maxdepth 1 -type f -exec chmod 0755 {} \;
|
|
|
|
/opt/solana/bin/solana --version || true
|
|
/opt/solana/bin/solana-keygen --version
|
|
|
|
# Build agave-validator (pin tag + toolchain)
|
|
# Uwaga: dla nowszych stable release'ow binarka moze nie byc publikowana,
|
|
# wiec build ze zrodel jest wymagany.
|
|
# doc/step-002f-agave-build-from-source-latest.txt
|
|
|
|
# Identity (create once)
|
|
if [ ! -f /var/lib/solana/identity.json ]; then
|
|
sudo -u solana -H /opt/solana/bin/solana-keygen new --no-passphrase -o /var/lib/solana/identity.json
|
|
sudo chown solana:solana /var/lib/solana/identity.json
|
|
sudo chmod 600 /var/lib/solana/identity.json
|
|
fi
|
|
|
|
# Genesis hash (mainnet)
|
|
GENESIS_HASH="$(curl -sS -H 'content-type: application/json' \
|
|
--data '{"jsonrpc":"2.0","id":1,"method":"getGenesisHash"}' \
|
|
https://api.mainnet-beta.solana.com | jq -r .result)"
|
|
echo "$GENESIS_HASH"
|
|
# Oczekiwane (mainnet): 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d
|
|
|
|
# systemd unit (bind RPC to WG/localhost only)
|
|
# UWAGA: w unit file NIE uzywaj `\\` na koncu linii w ExecStart.
|
|
# Jesli wpiszesz `\\`, agave-validator dostanie literalny argument `\` i padnie z:
|
|
# "error: The subcommand '\\' wasn't recognized"
|
|
#
|
|
# Najprosciej: ExecStart w 1 linii, bez "kontynuacji" backslashami.
|
|
# Ale: zeby uniknac problemow z wklejaniem/lamaniem linii, ponizej jest bezpieczna wersja wielolinijkowa.
|
|
sudo tee /etc/systemd/system/agave-validator.service >/dev/null <<'EOF'
|
|
[Unit]
|
|
Description=Agave validator (mainnet, RPC-only, non-voting)
|
|
After=network-online.target wg-quick@wg0.service
|
|
Wants=network-online.target wg-quick@wg0.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=solana
|
|
Group=solana
|
|
WorkingDirectory=/var/lib/solana
|
|
Environment=RUST_LOG=info
|
|
LimitNOFILE=1048576
|
|
Restart=always
|
|
RestartSec=5
|
|
TimeoutStopSec=120
|
|
ExecStart=/opt/solana/bin/agave-validator \
|
|
--identity /var/lib/solana/identity.json \
|
|
--no-voting \
|
|
--private-rpc \
|
|
--ledger /var/lib/solana/ledger \
|
|
--accounts /var/lib/solana/accounts \
|
|
--log /var/log/solana/validator.log \
|
|
--bind-address 0.0.0.0 \
|
|
--rpc-bind-address 10.66.66.1 \
|
|
--rpc-port 8899 \
|
|
--dynamic-port-range 8000-8020 \
|
|
--entrypoint entrypoint.mainnet-beta.solana.com:8001 \
|
|
--expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d \
|
|
--full-rpc-api \
|
|
--limit-ledger-size 50000000
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=full
|
|
ReadWritePaths=/var/lib/solana/ledger /var/lib/solana/accounts /var/log/solana /var/lib/solana
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now agave-validator
|
|
|
|
systemctl is-active agave-validator
|
|
journalctl -u agave-validator -n 80 --no-pager
|
|
|
|
# Jesli padnie na genesis (brak genesis.tar.bz2):
|
|
# doc/step-002c-genesis-download-mainnet.txt
|
|
#
|
|
# Jesli padnie na snapshot (mainnet wymaga snapshot):
|
|
# doc/step-002d-snapshot-download-mainnet.txt
|
|
#
|
|
# Jesli chcesz najpierw odpalic validator z CLI (test), zanim przepniesz na systemd:
|
|
# doc/step-002e-agave-validator-run-cli.txt
|
|
|
|
5) Geyser plugin -> Postgres
|
|
# Krok po kroku:
|
|
# doc/step-003-geyser-plugin-postgres.txt
|
|
#
|
|
# W skrocie:
|
|
# - budujesz plugin .so i wrzucasz do /opt/solana/plugins/
|
|
# - tworzysz /etc/solana/geyser-postgres.json
|
|
# - dopisujesz do ExecStart:
|
|
# --geyser-plugin-config /etc/solana/geyser-postgres.json
|
|
|
|
6) Drift DLOB (2 markets) (on VPS, not baremetal) (placeholder)
|
|
# VPS env:
|
|
# PERP_MARKETS_TO_LOAD=0,75
|
|
# USE_GRPC=true
|
|
# GRPC_ENDPOINT=http://10.66.66.1:10000
|
|
|
|
7) Monitoring (bind to WG only) (placeholder)
|
|
# node_exporter (prefer bind to WG):
|
|
# sudo apt-get install -y prometheus-node-exporter
|
|
# sudo systemctl enable --now prometheus-node-exporter
|
|
#
|
|
# Prometheus/Grafana (bind to 10.66.66.1):
|
|
# sudo apt-get install -y prometheus grafana
|
|
# sudo systemctl enable --now prometheus grafana-server
|
|
|
|
8) NOC tmux (btop) (placeholder)
|
|
# Create tmux session:
|
|
# btop
|
|
# iostat -x 1
|
|
# vmstat 1
|
|
# nstat -az
|
|
# ethtool -S eth0 | head -n 40 (wrap in watch)
|
|
# journalctl -fu agave-validator
|
|
# while true; do curl getHealth/getSlot; sleep 1; done
|
|
|
|
9) Troubleshooting checklist
|
|
# Services:
|
|
systemctl status agave-validator --no-pager
|
|
journalctl -u agave-validator -n 200 --no-pager
|
|
|
|
# Sockets and binds:
|
|
ss -lntp | egrep ':22\\b|:8899\\b|:8900\\b|:10000\\b|:9100\\b|:9090\\b|:3000\\b' || true
|
|
|
|
# Firewall:
|
|
sudo ufw status verbose
|
|
|
|
# RPC local:
|
|
curl -sS -H 'content-type: application/json' \
|
|
--data '{"jsonrpc":"2.0","id":1,"method":"getHealth"}' \
|
|
http://127.0.0.1:8899 | jq .
|
|
|
|
5-min quick verification checklist
|
|
wg show
|
|
sudo ufw status verbose
|
|
systemctl is-active agave-validator
|
|
ss -lntp | egrep ':8899\\b|:8900\\b|:10000\\b|:9090\\b|:3000\\b|:9100\\b' || true
|
|
curl -sS -H 'content-type: application/json' \
|
|
--data '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' \
|
|
http://10.66.66.1:8899 | jq .
|