Co to buduje
Dwie maszyny. Instancja Ryzen uruchamia Nextcloud, PHP-FPM, Postgres i Redis, wszystko na lokalnym Gen4 NVMe, gdzie mieszka praca wrażliwa na opóźnienia. Węzeł magazynujący obok trzyma faktyczną zawartość plików w zasobniku obiektowym, gdzie mieszkają tanie terabajty. Pomiędzy nimi znajduje się tunel WireGuard, więc nic w tym układzie nie jest wystawione na nic innego.
Ten podział ma znaczenie, ponieważ Nextcloud z podstawowym magazynem obiektów całkowicie przestaje zapisywać dane użytkowników na lokalnym dysku. Twój NVMe trzyma bazę danych i kod; zasobnik trzyma każdy bajt, który ktoś wgra. Wzrost z dwustu gigabajtów do dwudziestu terabajtów staje się wtedy aktualizacją węzła magazynującego, a nie migracją.
Zanim zaczniesz
- R-8 dla aplikacji i S-50 dla zasobnika, najlepiej w tym samym mieście, aby czas w obie strony tunelu był poniżej milisekundy.
- Tunel między nimi. Przewodnik WireGuard buduje dokładnie to; użyj
10.9.0.1dla aplikacji i10.9.0.2dla węzła magazynującego. - Nazwa hosta wskazująca na instancję aplikacji,
cloud.example.componiżej.
1. Magazyn obiektów na węźle magazynującym
MinIO to pojedynczy plik binarny i nie potrzebuje niczego więcej. Pobierz go, zweryfikuj, zainstaluj:
cd /usr/local/bin
wget https://dl.min.io/server/minio/release/linux-amd64/minio
wget https://dl.min.io/server/minio/release/linux-amd64/minio.sha256sum
sha256sum -c minio.sha256sum
chmod +x minio
useradd -r -s /sbin/nologin minio
install -d -o minio -g minio /srv/objectsPojemność masowa na węźle magazynującym jest montowana oddzielnie od NVMe. Umieść zasobnik na pojemności masowej, a NVMe zostaw na cache zapisu, do czego on służy. Potem unit, w /etc/systemd/system/minio.service:
[Unit]
Description=MinIO
After=network-online.target [email protected]
Wants=network-online.target
[Service]
User=minio
Group=minio
Environment=MINIO_ROOT_USER=nextcloud
Environment=MINIO_ROOT_PASSWORD=<forty random characters>
ExecStart=/usr/local/bin/minio server /srv/objects --address 10.9.0.2:9000
Restart=always
LimitNOFILE=65535
NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=/srv/objects
[Install]
WantedBy=multi-user.targetWiązanie z adresem tunelu zamiast ze wszystkim jest ważną linią. Magazyn obiektów nie ma prawa odpowiadać na publicznym interfejsie, a w ten sposób błąd w zaporze nie może go wystawić.
systemctl daemon-reload && systemctl enable --now minio
ss -ltn | grep 90002. Host aplikacji: pakiety
Na instancji Ryzen:
apt update && apt install -y nginx postgresql redis-server unzip \
php8.4-fpm php8.4-pgsql php8.4-gd php8.4-curl php8.4-zip php8.4-xml \
php8.4-mbstring php8.4-intl php8.4-bcmath php8.4-gmp php8.4-imagick \
php8.4-redis php8.4-apcu3. Baza danych
sudo -u postgres psql -c "CREATE USER nextcloud WITH PASSWORD '<a long password>';"
sudo -u postgres psql -c "CREATE DATABASE nextcloud OWNER nextcloud TEMPLATE template0 ENCODING UTF8;"Domyślne ustawienia Postgresa są dobre w tej skali. Jeśli to Nextcloud ma obsługiwać kilkaset osób, przewodnik po strojeniu Postgresa ma zastosowanie, a liczby w nim są warte godziny.
4. Nextcloud, skonfigurowany przed instalacją
cd /var/www
wget https://download.nextcloud.com/server/releases/latest.zip
unzip -q latest.zip && rm latest.zip
chown -R www-data:www-data /var/www/nextcloudTeraz część, która musi się wydarzyć przed uruchomieniem instalatora, ponieważ podstawowego magazynu obiektów nie można dodać do istniejącej instancji bez ręcznego przenoszenia każdego pliku. Utwórz /var/www/nextcloud/config/config.php:
<?php
$CONFIG = array(
"objectstore" => array(
"class" => "\\OC\\Files\\ObjectStore\\S3",
"arguments" => array(
"bucket" => "nextcloud",
"autocreate" => true,
"key" => "nextcloud",
"secret" => "<the same forty characters>",
"hostname" => "10.9.0.2",
"port" => 9000,
"use_ssl" => false,
"use_path_style" => true,
"region" => "local",
),
),
);use_ssl jest fałszywe celowo. Ruch przechodzi przez tunel WireGuard, który jest już uwierzytelniony i zaszyfrowany, a kończenie TLS po raz drugi na węźle magazynującym daje tylko cykle procesora i certyfikat do zapomnienia o odnowieniu. Gdyby te dwie maszyny kiedykolwiek znalazły się w różnych miastach, włącz to.
chown www-data:www-data /var/www/nextcloud/config/config.php
chmod 640 /var/www/nextcloud/config/config.php
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:install --database pgsql \
--database-name nextcloud --database-user nextcloud \
--database-pass "<a long password>" \
--admin-user admin --admin-pass "<another long password>"5. Cache, cron i ostatnie ustawienia
sudo -u www-data php occ config:system:set memcache.local --value "\\OC\\Memcache\\APCu"
sudo -u www-data php occ config:system:set memcache.distributed --value "\\OC\\Memcache\\Redis"
sudo -u www-data php occ config:system:set memcache.locking --value "\\OC\\Memcache\\Redis"
sudo -u www-data php occ config:system:set redis host --value /run/redis/redis-server.sock
sudo -u www-data php occ config:system:set redis port --value 0
sudo -u www-data php occ config:system:set trusted_domains 0 --value cloud.example.com
sudo -u www-data php occ config:system:set overwrite.cli.url --value https://cloud.example.com
sudo -u www-data php occ background:cronRedis przez unix socket zamiast TCP oszczędza jedno okrążenie syscall przy każdej operacji blokady, a Nextcloud wykonuje dużo blokad. Dodaj www-data do grupy redis, aby mógł dotrzeć do socketa, potem podłącz zadanie w tle do timera:
usermod -aG redis www-data
systemctl restart php8.4-fpm redis-server
echo "*/5 * * * * php -f /var/www/nextcloud/cron.php" | crontab -u www-data -Domyślne ustawienia PHP-FPM zakładają współdzieloną maszynę. Twoja nie jest współdzielona, więc w /etc/php/8.4/fpm/pool.d/www.conf ustaw pm = dynamic, pm.max_children = 60, pm.start_servers = 12, pm.min_spare_servers = 8 i pm.max_spare_servers = 20, a memory_limit podnieś do 1G w /etc/php/8.4/fpm/php.ini. Wgrywanie chce upload_max_filesize i post_max_size na 16G, chyba że lubisz tłumaczyć, dlaczego wideo nie powiodło się w dziewięćdziesięciu procentach.
Zweryfikuj to
Sednem tej konstrukcji jest to, że pliki użytkowników nie znajdują się na serwerze aplikacji. Udowodnij to trzema poleceniami.
sudo -u www-data php occ status
du -sh /var/www/nextcloud/dataStatus powinien zgłaszać zainstalowany i nie w trybie konserwacji. Katalog danych powinien mieć kilka megabajtów i taki pozostać na zawsze; trzyma logi i nic więcej, gdy magazyn obiektów jest podstawowy.
Teraz wgraj coś i obserwuj, gdzie to ląduje:
head -c 50M /dev/urandom > /tmp/test.bin
curl -u admin -T /tmp/test.bin https://cloud.example.com/remote.php/dav/files/admin/test.bin
du -sh /var/www/nextcloud/dataWgrywanie się udaje, a katalog danych nie urósł o pięćdziesiąt megabajtów. Na węźle magazynującym obiekt jest widoczny bezpośrednio:
ls -R /srv/objects/nextcloud | tail -5
du -sh /srv/objects/nextcloudObiekty są nazwane urn:oid: po którym następuje id pliku, dlatego zasobnik nie jest przeglądarkową kopią folderów użytkownika i dlatego tworzysz kopię zapasową bazy danych i zasobnika razem albo wcale.
Potem
Weź dodatek do kopii zapasowej poza węzłem dla zrzutu Postgresa i zasobnika, albo zrób własną do trzeciej lokalizacji. Zasobnik bez bazy danych to sterta ponumerowanych blobów, a baza danych bez zasobnika to indeks plików, które już nie istnieją. Utrata jednego oznacza utratę obu.