Създаваме и настройваме свой CDN

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

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

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

Създаваме и настройваме свой CDN
Източник: Infographic vector created by pikisuperstar — www.freepik.com

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

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

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

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

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

Прекрасно, ако имате своя автономна система (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 услуги включват незаменимата услуга — DNS Failover, необходима за изграждането на CDN. С нея може да се настрои мониторинг на работата на сървърите и в случай на липса на признаци на живот автоматично да се заменят в 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 scriptКлиентът е удобен и лесен за настройка, а най-важното е, че позволява валидация на домейн/субдомейн по 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 Тб трафик: по 1 Тб на всяка локация.

Проверяваме работата на 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