docs(step2): add solana rpc (agave) install runbook
This commit is contained in:
215
doc/step-002-solana-rpc-install.txt
Normal file
215
doc/step-002-solana-rpc-install.txt
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
Step 002: Instalacja Solana RPC (Agave) na baremetalu (po WireGuard)
|
||||||
|
|
||||||
|
Stan startowy:
|
||||||
|
- Masz dzialajacy WireGuard: z laptopa/VPS pingujesz 10.66.66.1 i logujesz sie: `ssh user@10.66.66.1`
|
||||||
|
- SSH po publicznym eth0 jest odciete (UFW deny na eth0:22), SSH dziala tylko po wg0.
|
||||||
|
- RPC ma byc prywatny: porty 8899/8900 tylko po wg0, ale node ma miec publiczne porty klastra (UDP dynamic range) zeby syncowal.
|
||||||
|
|
||||||
|
UWAGA o bind:
|
||||||
|
- `agave-validator` praktycznie wymaga, zeby wszystkie sockety byly na tym samym IP.
|
||||||
|
- Dlatego w tym kroku bindujemy usluge na 0.0.0.0 i zabezpieczamy dostep firewall-em:
|
||||||
|
- eth0: blokujemy TCP 8899/8900
|
||||||
|
- wg0: pozwalamy TCP 8899/8900
|
||||||
|
- eth0: pozwalamy UDP dynamic port range (np. 8000-8020) dla klastra
|
||||||
|
|
||||||
|
Parametry (dostosuj, przyklad mainnet):
|
||||||
|
- PUBLIC_IFACE=eth0
|
||||||
|
- WG_IFACE=wg0
|
||||||
|
- WG_IP=10.66.66.1
|
||||||
|
- ENDPOINT_RPC_PORT=8899
|
||||||
|
- ENDPOINT_WS_PORT=8900
|
||||||
|
- DYNAMIC_PORT_RANGE="8000:8020"
|
||||||
|
|
||||||
|
1) Bazowe pakiety
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
chrony curl jq git \
|
||||||
|
smartmontools nvme-cli \
|
||||||
|
build-essential pkg-config libssl-dev \
|
||||||
|
clang llvm-dev libclang-dev \
|
||||||
|
cmake protobuf-compiler libudev-dev zlib1g-dev
|
||||||
|
|
||||||
|
2) Uzytkownik i katalogi
|
||||||
|
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
|
||||||
|
|
||||||
|
3) Sysctl + ulimit (baseline pod Agave)
|
||||||
|
sudo tee /etc/sysctl.d/90-agave.conf >/dev/null <<'EOF'
|
||||||
|
fs.file-max = 2000000
|
||||||
|
vm.max_map_count = 1000000
|
||||||
|
net.core.somaxconn = 65535
|
||||||
|
net.core.netdev_max_backlog = 250000
|
||||||
|
net.core.rmem_max = 134217728
|
||||||
|
net.core.wmem_max = 134217728
|
||||||
|
EOF
|
||||||
|
sudo sysctl --system
|
||||||
|
|
||||||
|
sudo tee /etc/security/limits.d/90-solana.conf >/dev/null <<'EOF'
|
||||||
|
* soft nofile 1000000
|
||||||
|
* hard nofile 1000000
|
||||||
|
EOF
|
||||||
|
|
||||||
|
4) Firewall (UFW): RPC prywatnie po wg0, porty klastra publicznie po eth0
|
||||||
|
sudo ufw default deny incoming
|
||||||
|
sudo ufw default allow outgoing
|
||||||
|
|
||||||
|
# WireGuard z internetu
|
||||||
|
sudo ufw allow 51820/udp
|
||||||
|
|
||||||
|
# SSH tylko po wg0 (zakladamy, ze tak chcesz)
|
||||||
|
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 tylko po wg0
|
||||||
|
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
|
||||||
|
|
||||||
|
# Porty klastra (inbound) na eth0 - 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
|
||||||
|
|
||||||
|
5) Narzedzia Solana/Anza (dla `solana`): solana-keygen itd.
|
||||||
|
sudo -u solana -H bash -lc 'sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"'
|
||||||
|
|
||||||
|
ACTIVE_RELEASE_BIN_DIR="/var/lib/solana/.local/share/solana/install/active_release/bin"
|
||||||
|
test -d "$ACTIVE_RELEASE_BIN_DIR" || { echo "Missing: $ACTIVE_RELEASE_BIN_DIR" >&2; exit 1; }
|
||||||
|
for bin in "$ACTIVE_RELEASE_BIN_DIR"/*; do
|
||||||
|
sudo ln -sfn "$bin" "/opt/solana/bin/$(basename "$bin")"
|
||||||
|
done
|
||||||
|
test -x /opt/solana/bin/solana-keygen
|
||||||
|
|
||||||
|
6) Build `agave-validator` ze zrodel i instalacja do /opt/solana/bin
|
||||||
|
AGAVE_VERSION_TAG="v2.3.13"
|
||||||
|
AGAVE_RUST_TOOLCHAIN="1.86.0"
|
||||||
|
AGAVE_SRC_DIR="/var/lib/solana/src/agave"
|
||||||
|
|
||||||
|
sudo -u solana -H bash -lc \
|
||||||
|
"curl -sSfL https://sh.rustup.rs | sh -s -- -y --default-toolchain '${AGAVE_RUST_TOOLCHAIN}'"
|
||||||
|
|
||||||
|
sudo -u solana -H bash -lc "
|
||||||
|
set -euo pipefail
|
||||||
|
export PATH=/var/lib/solana/.cargo/bin:\$PATH
|
||||||
|
rustup toolchain install '${AGAVE_RUST_TOOLCHAIN}'
|
||||||
|
|
||||||
|
mkdir -p '$(dirname "$AGAVE_SRC_DIR")'
|
||||||
|
if [ ! -d '${AGAVE_SRC_DIR}/.git' ]; then
|
||||||
|
git clone --depth 1 --branch '${AGAVE_VERSION_TAG}' https://github.com/anza-xyz/agave.git '${AGAVE_SRC_DIR}'
|
||||||
|
else
|
||||||
|
cd '${AGAVE_SRC_DIR}'
|
||||||
|
git fetch --tags --prune
|
||||||
|
git checkout '${AGAVE_VERSION_TAG}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd '${AGAVE_SRC_DIR}'
|
||||||
|
cargo +${AGAVE_RUST_TOOLCHAIN} build --release -p agave-validator
|
||||||
|
"
|
||||||
|
|
||||||
|
sudo install -o root -g root -m 0755 \
|
||||||
|
"${AGAVE_SRC_DIR}/target/release/agave-validator" \
|
||||||
|
/opt/solana/bin/agave-validator
|
||||||
|
|
||||||
|
test -x /opt/solana/bin/agave-validator
|
||||||
|
|
||||||
|
7) Identity (tylko raz) + backup poza hostem
|
||||||
|
if [ ! -f /var/lib/solana/identity.json ]; then
|
||||||
|
sudo -u solana -H bash -lc \
|
||||||
|
"/opt/solana/bin/solana-keygen new --no-passphrase -o /var/lib/solana/identity.json"
|
||||||
|
sudo chmod 0600 /var/lib/solana/identity.json
|
||||||
|
sudo chown solana:solana /var/lib/solana/identity.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo -u solana -H bash -lc \
|
||||||
|
"/opt/solana/bin/solana-keygen pubkey /var/lib/solana/identity.json"
|
||||||
|
|
||||||
|
8) (Opcjonalnie, rekomendowane) Genesis hash z publicznego RPC
|
||||||
|
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"
|
||||||
|
|
||||||
|
Testnet:
|
||||||
|
GENESIS_HASH="$(curl -sS -H 'content-type: application/json' \
|
||||||
|
--data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getGenesisHash\"}' \
|
||||||
|
https://api.testnet.solana.com | jq -r .result)"
|
||||||
|
echo "$GENESIS_HASH"
|
||||||
|
|
||||||
|
9) Systemd unit: /etc/systemd/system/solana-rpc.service
|
||||||
|
Minimalny unit (RPC node, non-voting). Bind na 0.0.0.0 + firewall robi prywatnosc RPC.
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/solana-rpc.service >/dev/null <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Solana RPC node (Agave)
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[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 \
|
||||||
|
--ledger /var/lib/solana/ledger \
|
||||||
|
--accounts /var/lib/solana/accounts \
|
||||||
|
--bind-address 0.0.0.0 \
|
||||||
|
--rpc-bind-address 0.0.0.0 \
|
||||||
|
--rpc-port 8899 \
|
||||||
|
--dynamic-port-range 8000-8020 \
|
||||||
|
--entrypoint entrypoint.mainnet-beta.solana.com:8001 \
|
||||||
|
--full-rpc-api \
|
||||||
|
--limit-ledger-size \
|
||||||
|
--log /var/log/solana/validator.log
|
||||||
|
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 solana-rpc
|
||||||
|
|
||||||
|
Jesli chcesz dodac genesis hash:
|
||||||
|
- dopisz w ExecStart linie:
|
||||||
|
--expected-genesis-hash <GENESIS_HASH>
|
||||||
|
|
||||||
|
10) Weryfikacja
|
||||||
|
systemctl is-active solana-rpc
|
||||||
|
journalctl -u solana-rpc -n 200 --no-pager
|
||||||
|
|
||||||
|
# z samego hosta:
|
||||||
|
curl -sS -H 'content-type: application/json' \
|
||||||
|
--data '{"jsonrpc":"2.0","id":1,"method":"getHealth"}' \
|
||||||
|
http://127.0.0.1:8899 | jq .
|
||||||
|
|
||||||
|
# z laptopa/VPS po WG:
|
||||||
|
curl -sS -H 'content-type: application/json' \
|
||||||
|
--data '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' \
|
||||||
|
http://10.66.66.1:8899 | jq .
|
||||||
|
|
||||||
|
Jesli cos nie dziala:
|
||||||
|
- `sudo wg show` (czy WG jest OK)
|
||||||
|
- `sudo ufw status verbose` (czy RPC nie jest blokowane po wg0)
|
||||||
|
- `journalctl -u solana-rpc -n 200 --no-pager` (logi Agave)
|
||||||
|
|
||||||
Reference in New Issue
Block a user