Събираме и настройваме своя CDN

Мрежите за доставка на съдържание (CDN) се използват на сайтове и в приложения предимно за ускоряване на зареждането на статични елементи. Това става чрез кеширане на файлове на CDN-сървъри, разположени в различни географски региони. При заявка за данни през CDN, потребителят ги получава от най-близкия сървър.

Принципът на работа и функционалността на всички мрежи за доставка на съдържание са приблизително едни и същи. При получаване на заявка за зареждане на файл, CDN сървърът веднъж взима файла от оригиналния сървър и го предава на потребителя, като същевременно го кешира за предварително зададен период от време. На всички последващи заявки отговорът идва от кеша. Всички CDN разполагат с опции за предварително зареждане на файлове, почистване на кеша, настройка на срока на съхранение и много други.

Понякога по различни причини е необходимо да се организира собствена мрежа за доставка на съдържание, и тогава — нека да ни бъде в помощ инструкцията за сглобяване на поредния велосипед.

Събираме и настройваме своя CDN
Източник: Инфографика вектор, създадена от pikisuperstar — www.freepik.com

Кога е необходим собствен CDN

Нека разгледаме случаи, когато стартирането на собствен CDN има смисъл:

  • когато имате желание да спестите, а текущите разходи дори при използване на евтини CDN като BunnyCDN възлизат на няколко стотин долара на месец
  • ако искаме да получим постоянен кеш или кеш без съседи по сървъра и канала
  • в необходимия за вас регион, CDN услугите нямат точки на присъствие
  • необходими са специални настройки за доставка на съдържание
  • искаме да ускорим доставката на динамично съдържание, като разположим производствени сървъри по-близо до потребителите
  • има опасения, че външен CDN сервиз може неправомерно да събира или използва информация за поведението на потребителите (здрасти на услугите, които не отговарят на изискванията на GDPR) или да извършва други неправомерни действия

В повечето останали случаи е по-разумно да се използват съществуващите готови решения.

Какво е необходимо за стартиране

Чудесно е, ако имате собствена автономна система (AS). С нея можете да зададете един и същ IP на няколко сървъра и според тази инструкция на ниво мрежа да насочва потребителите към най-близкия. Трябва да се каже, че дори с блок от адреси /24 има възможност да се изгради мрежа за доставка на съдържание. Някои сървърни доставчици позволяват да се направи анонс за използване във всички налични региони.

Ако не разполагате с блок IP адреси, то за стартиране на проста CDN ще ви трябват:

  • домен или субдомен
  • поне два сървъра в различни региони. Сървърът може да бъде както физически, така и виртуален
  • geoDNS инструмент. С него потребителят, адресирайки домейна, ще бъде насочен към най-близкия сървър

Регистрираме домейн и поръчваме сървъри

С регистрацията на домейна е лесно — регистрирате в която и да е зона при всеки регистратор. Също така за CDN можете да използвате субдомен, например нещо като cdn.именадомейна.com. Всъщност в нашия пример ще постъпим точно така.

Що се отнася до поръчването на сървъри — те е добре да се наемат в региони и страни, където се намира вашата потребителска аудитория. Ако проектът е интерконтинентален, удобно е да се изберат хостинг доставчици, които предлагат сървъри в цял свят. Примери: OVH, Leaseweb и 100Tb — за выделени сървъри, Vultr и DigitalOcean — за виртуални облаци*.

За нашия частен CDN ще наемем 3 виртуални сървъра на различни континенти. На Vultr сървъра за 5 $/мес ще получим 25GB SSD места и 1TB трафик. При инсталирането ще изберем последния Debian. Нашите сървъри:

Събираме и настройваме своя CDN Франкфурт, ip: 199.247.18.199

Събираме и настройваме своя CDN Чикаго, ip: 149.28.121.123

Събираме и настройваме своя CDN Сингапур, ip: 157.230.240.216

* Vultr и DigitalOcean обещават $100 кредит на потребителите, регистрирани по линкове в статията, веднага след добавяне на начин на плащане. Авторът също така получава малък комплимент от подобно, което в момента е много значимо за него. Моля, отнесете се с разбиране.

Настройване на geoDNS

За да се насочва потребителят към правилния (най-близкия до него) сървър при достъп до домейн или субдомен на CDN, ще ни е нужен DNS сървър с функция geoDNS.

Принципът и редът на работа на geoDNS е следният:

  1. Определя IP адреса на клиента, отправил DNS запитване, или IP адреса на рекурсивния DNS-сървър, който се използва при обработката на клиентската заявка. Такива рекурсивни сървъри обикновено са DNS-ите на доставчиците.
  2. По IP адреса на клиента установява неговата страна или регион. За целта се използват GeoIP бази данни, които в днешно време са много на брой. Има добри безплатни варианти.
  3. В зависимост от местоположението на клиента, му се присвоява IP адрес на най-близкия CDN сървър.

DNS сървър с функция geoDNS може да бъде създаден самостоятелно, но е по-добре да се използват готови решения с мрежа от DNS сървъри по целия свят и Anycast от кутията:

  • СlouDNS от $9.95/мес, тариф GeoDNS, по подразбиране има един DNS Failover
  • Zilore от $25/мес, включен DNS Failover
  • Amazon Route 53 от $35/мес за 50М гео-запроси. DNS Failover се таксува отделно
  • DNS Made Easy от $125/мес, има 10 DNS Failover
  • Cloudflare, функцията „Geo Steering“ е достъпна в Enterprise тарифите

При поръчка на geoDNS следва да се обърне внимание на броя на включените в тарифата запитвания и да се вземе предвид, че реалният брой на обращението към домейна може многократно да надвиши очакванията. Милиони ботове, скенери, спамери и друга нежелана активност работят неуморно.

Практически всички DNS услуги включват в цената незаменимата услуга за изграждане на CDN – DNS Failover. С нея може да се настрои мониторинг на работата на собствените сървъри и в случай на липса на признаци за работа автоматично да се заменя в DNS отговорите адреса на неработещия сървър с резервен.

За изграждане на нашето CDN ще се възползваме от ClouDNS, тариф GeoDNS.

Добавяме нова DNS зона в личния кабинет, като посочваме своя домейн. Ако CDN ще бъде конфигуриран на субдомейн, а основният домейн вече се използва, веднага след добавянето на зоната не забравяйте да добавите съществуващите работещи DNS записи. Следващото действие е създаването на няколко A записа за домейна/субдомейна на CDN, всеки от които ще се използва за зададения от нас регион. Като региони можем да посочим континенти или държави, за САЩ и Канада са налични субрегиони.

В нашия случай CDN ще бъде активиран на субдомейн cdn.sayt.in. След добавянето на зоната sayt.in, ще създадем първия A запис за субдомейна и ще насочим цяла Северна Америка към сървър в Чикаго:

Събираме и настройваме своя CDN
Повтаряме действието за други региони, не забравяйки да създадем един запис за регионите по подразбиране. Ето какво ще се получи в крайна сметка:

Събираме и настройваме своя CDN

Последният дефолт запис на екрана означава, че всички незадани региони (като Европа, Африка, потребители на сателитен интернет и т.н.) ще бъдат насочвани към сървър във Франкфурт.

С основните настройки на DNS е приключено. Остава да влезете в сайта на регистратора на домейна и да замените текущите NS записи на домейна с тези, предоставени от ClouDNS. Докато NS записите се актуализират, ще подготвим сървърите.

Инсталиране на SSL сертификати

Нашият CDN ще работи по HTTPS, така че ако вече разполагате с SSL сертификати за домейна или поддомейна, - качете ги на всички сървъри, например в директорията /etc/ssl/вашдомен/

Ако нямате сертификати, можете да получите безплатен от Let’s Encrypt. За целта отлично подхожда ACME Shell скрипт. Клиентът е удобен и лесен за настройка, а най-важното е, че позволява валидиране на домейна/поддомейна по DNS през API на ClouDNS.

Ще инсталираме acme.sh само на един от сървърите - европейския 199.247.18.199, от който сертификатите ще се копират на всички останали. За инсталирането изпълняваме:

root@cdn:~# wget -O - https://get.acme.sh | bash; source ~/.bashrc

По време на инсталацията на скрипта ще бъде създадена задача CRON за последващо обновление на сертификатите без нашето участие.

Проверката на домена при издаване на сертификат ще се извършва по DNS с използване на API, затова в личния кабинет на ClouDNS в менюто Reseller API трябва да създадете нов API потребител и да му зададете парола. Полученият auth-id с паролата ще запишем в файла ~/.acme.sh/dnsapi/dns_cloudns.sh (не бъркайте с файла dns_clouddns.sh). Ето редовете, които трябва да разкоментирате и редактирате:

CLOUDNS_AUTH_ID=
CLOUDNS_AUTH_PASSWORD=""

Сега ще поискате издаване на SSL сертификат за cdn.sayt.in

root@cdn:~# acme.sh --issue --dns dns_cloudns -d cdn.sayt.in --reloadcmd "service nginx reload"

В параметрите, за в бъдеще, указахме команда за автоматично презареждане на конфигурацията на уеб сървъра след всяко обновление на срока на действие на сертификата.

Целият процес по получаване на сертификата може да отнеме до 2 минути, не го прекъсвайте. Ако възникне грешка валидация на домена, опитайте да стартирате командата отново. В края ще видим къде са заредени сертификатите:

Събираме и настройваме своя CDN

Нека запомним тези пътища, те ще бъдат необходими при копирането на сертификата на други сървъри, а също така в настройките на уеб сървъра. Не обърнете внимание на грешката при перезареждане на конфигурациите на Nginx - на напълно настроен сървър при обновяването на сертификатите тя няма да се появи.

Всичко, което оставя за нас по SSL, е да копираме получен сертификат на два други сървъра с запазване на пътя към файловете. Ще създадем същите директории на всеки от тях и ще направим копие:

root@cdn:~# mkdir -p /root/.acme.sh/cdn.sayt.in/
root@cdn:~# scp -r root@199.247.18.199:/root/.acme.sh/cdn.sayt.in/* /root/.acme.sh/cdn.sayt.in/

За да обновленията на сертификатите да бъдат редовни, ще създадем ежедневно CRON задание на двата сървъра с командата:

scp -r root@199.247.18.199:/root/.acme.sh/cdn.sayt.in/* /root/.acme.sh/cdn.sayt.in/ && service nginx reload

При това достъпът до отдалечения сървър-източник трябва да бъде настроен с ключ, т.е. без въвеждане на парола. Не забравяйте да го направите.

Инсталиране и настройка на Nginx

За предоставяне на статично съдържание ще използваме Nginx, конфигуриран в режим на кеширащ прокси-сървър. Нека актуализираме списъците с пакети и да го инсталираме на трите сървъра:

root@cdn:~# apt update
root@cdn:~# apt install nginx

Вместо стандартния конфиг използваме конфигурацията от спойлера по-долу:
nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log off;
    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_disable "msie6";
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_vary on;
    gzip_types text/plain application/javascript text/javascript text/css application/json application/xml text/xml application/rss+xml;
    gunzip on;            

    proxy_temp_path /var/cache/tmp;
    proxy_cache_path /var/cache/cdn levels=1:2 keys_zone=cdn:64m max_size=20g inactive=7d;
    proxy_cache_bypass $http_x_update;

server {
  listen 443 ssl;
  server_name cdn.sayt.in;

  ssl_certificate /root/.acme.sh/cdn.sayt.in/cdn.sayt.in.cer;
  ssl_certificate_key /root/.acme.sh/cdn.sayt.in/cdn.sayt.in.key;

  location / {
    proxy_cache cdn;
    proxy_cache_key $uri$is_args$args;
    proxy_cache_valid 90d;
    proxy_pass https://sayt.in;
  }
}
}

В конфигурацията редактираме:

  • max_size — максимален размер на кеша, който не надвишава наличното място на диска
  • inactive — времето за съхранение на кешираните данни, към които никой не е имал достъп
  • ssl_certificate и ssl_certificate_key — пътища до файловете на SSL сертификата и ключа
  • proxy_cache_valid — времето за съхранение на кешираните данни
  • proxy_pass — адресът на оригиналния сървър, от който CDN ще поиска файлове за кеширане. В нашия пример това е sayt.in

Както виждаме, всичко е просто. Трудността може да се появи само в настройката на времето за кеширане поради сходството на директивите. inactive и proxy_cache_validНека ги разгледаме на нашия пример. Ето какво се случва при inactive=7d и proxy_cache_valid 90d:

  • ако заявката не бъде повторена в рамките на 7 дни, данните ще бъдат изтрити от кеша след изтичане на този период.
  • ако заявката бъде повторена поне веднъж в 7 дни, данните в кеша ще се считат за остарели след 90 дни и при следваща заявка Nginx ще ги актуализира, взимайки ги от оригиналния сървър.

След като приключим с редактирането nginx.conf, презаредете конфигурацията:

root@cdn:~# service nginx reload

Нашият CDN е напълно готов. За $15/мес. получихме точки на присъствие на три континента и 3 TB трафик: по 1 TB във всяка локация.

Проверяваме работата на CDN

Нека разгледаме пингите към нашия CDN от различни географски локации. За това подхождат всякакви пинг услуги.

Точка на стартиране
Хост
IP
Средно време, мсек

Германия, Берлин
cdn.sayt.in
199.247.18.199
9.6

Нидерландия, Амстердам
cdn.sayt.in
199.247.18.199
10.1

Франция, Париж
cdn.sayt.in
199.247.18.199
16.3

Великобритания, Лондон
cdn.sayt.in
199.247.18.199
14.9

Канада, Торонто
cdn.sayt.in
149.28.121.123
16.2

САЩ, Сан Франциско
cdn.sayt.in
149.28.121.123
52.7

САЩ, Далас
cdn.sayt.in
149.28.121.123
23.1

САЩ, Чикаго
cdn.sayt.in
149.28.121.123
2.6

САЩ, Ню Йорк
cdn.sayt.in
149.28.121.123
19.8

Сингапур
cdn.sayt.in
157.230.240.216
1.7

Япония, Токио
cdn.sayt.in
157.230.240.216
74.8

Австралия, Сидни
cdn.sayt.in
157.230.240.216
95.9

Резултатите са добри. Сега ще поставим тестово изображение в корена на основния сайт. test.jpg и ще проверим скоростта на зареждане през CDN. Казано е, — направено. Съдържанието се предоставя бързо.

Ще напишем кратък скрипт, в случай че искаме да изчистим кеша на CDN-точката.
purge.sh

#!/bin/bash
if [ -z "$1" ]
then
    echo "Purging all cache"
    rm -rf /var/cache/cdn/*
else
    echo "Purging $1"
    FILE=`echo -n "$1" | md5sum | awk '{print $1}'`
    FULLPATH=/var/cache/cdn/${FILE:31:1}/${FILE:29:2}/${FILE}
    rm -f "${FULLPATH}"
fi

За да изтриете целия кеш, е достатъчно просто да го стартирате, а отделен файл може да се изчисти така:

root@cdn:~# ./purge.sh /test.jpg

Вместо заключения

Накрая искам да дам няколко полезни съвета, за да избегнете капаните, които навремето ми създаваха главоболия:

  • За повишаване на отказоустойчивостта на CDN се препоръчва да се настрои DNS Failover, който помага бързо да се смени A записа в случай на повреда на сървъра. Това става в панела за управление на DNS записите на домейна.
  • Сайтовете с широк географски обхват без съмнение изискват голям брой точки на CDN, но да не прекаляваме. Най-вероятно потребителят няма да забележи съществена разлика в сравнение с платен CDN, ако разположите сървъри на 6-7 места: Европа, Северна Америка (изток), Северна Америка (запад), Сингапур, Австралия, Хонг Конг или Япония.
  • Понякога хостинг доставчиците не позволяват да се използват наеманите сървъри за CDN цели. Затова, ако решите да внедрите мрежа за доставка на съдържание като услуга, не забравяйте да прочетете правилата на конкретния хостинг доставчик.
  • Изучете картата на подводните комуникации, за да разберете как са свързани континентите и да вземете това предвид при изграждането на мрежата за доставка на съдържание.
  • Опитайте да проверите пинг на различни места към вашите сървъри. По този начин можете да видите регионите, най-близки до точките на CDN и по-правилно да настроите GeoDNS.
  • В зависимост от задачите, не би било лошо да донастроите Nginx според конкретните изисквания за кеширане и с оглед на натоварването на сървъра. В това много ми помогнаха статиите за кеша на Nginx — тук и ускоряването на работата при големи натоварвания: тук и тук

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster