Что нам стоит CDN построить?

в 10:00, , рубрики: CDN, DNS, iis, Блог компании RUVDS.com, Разработка веб-сайтов, Серверное администрирование, хостинг

Привет! В этой статье мы будем строить свой CDN. Почему не воспользоваться готовыми решениями? Потому что сайт автора полностью статический, сделанный на Jekyll, с большими картинками, которые нужно отдавать максимально быстро. Сервер не должен быть кэширующим, он должен хранить сайт целиком, поддерживать HTTP/2 и Brotli, а на всех серверах должен быть установлен один и тот же сертификат.

Ещё мы сделаем это всё на IIS, работающим под Windows Server 2019 Core.

Что нам стоит CDN построить? - 1

Кратко о реализации

На конечных узлах обойдёмся встроенными в операционную систему средствами, нам понадобятся:

  1. Active Directory
  2. DFS
  3. IIS
  4. WinAcme
  5. RSAT

Опционально, но рекомендуется:

  1. Windows Admin Center

На узлах с сайтами нужны только службы IIS и DFS, Active Directory нужна обязательно, она требуется для DFS, которая будет синхронизировать содержимое сайта между серверами. RSAT нужен, чтобы управлять компонентами, а Windows Admin Center — чтобы править реестр. Это можно сделать и через Powershell, о чём тоже расскажу. 

Домен автора называется ***.***.wtf (пожалуйста не пугайтесь), а серверы именованы по дата-центрам и имеют имена вида cache-zur1, cahe-ru и так далее. AD развёрнута, а серверы подключены к ней. Теперь по порядку.

Выбор точек

У RUVDS 8 дата-центров — 3 в Европе и 5 в России. Мой выбор пал на Rucloud в Москве и LD8 (тот что в Лондоне). Rucloud потому, что почти ничем не отличается от М9, а через Лондон идёт трансконтинентальный кабель до США, поэтому в Европе маст хэв. Для более плотного размещения по Европе можно выбрать Швейцарию или Германию — на этом, в целом, можно остановиться.

Выбор DNS GeoIP

Если клиент стучится до сайта, то как понять, какой сервер ему должен передать данные? С помощью DNS конечно. То есть в зависимости от ip-адреса того, кто обратился к DNS, будет дан релевантный ответ.

Мы можем использовать свой DNS (BIND с плагином для Maxmind) или готовое решение (Route53). Подписка на GeoIP-базы Maxmind стоит $25 в месяц, а Route53 стоит $0.50 за одну доменную зону, плюс копейки, если выйдешь за миллион запросов. К тому же, создавать ещё одну точку усиления DDoS-атак это последнее дело, поэтому мой выбор пал на Route53.

В этой статье речь идёт о CDN для Европы; если вам нужен CDN для России, то выбор в сторону своего DNS очевиден, потому что Route53 осуществляет роутинг по странам, а не по городам.
Сервисы подобного рода есть и у Майкрософт (Azure Traffic Manager).

1. Установка IIS

1.1. Установка IIS

Устанавливаем базовые компоненты IIS, компонент поддержки централизованных сертификатов, а на главном сервере дополнительно поддержку удалённого управления. Этот компонент нужен только для одного сервера — вы не сможете управлять другими серверами при включении общих конфигов, даже если удалённое управление было настроено.

Что нам стоит CDN построить? - 2

Через Powershell: 

Install-WindowsFeature Web-Server, Web-CertProvider

На главном сервере нужно дополнительно установить: 

Install-WindowsFeature Web-Mgmt-Service

1.1.1 Включаем удалённое управление

Чтобы мы могли удаленно управлять сервером IIS, нам нужно поднять службу удаленного управления IIS. На главном сервере запускаем службу:

start-service WMSVC
set-service -Name WMSVC -StartupType Automatic

И теперь включаем возможность управления как таковую через реестр.

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWebManagementServer

Проще всего управлять реестром, конечно, через Windows Admin Center. 

Что нам стоит CDN построить? - 3

Но это можно провернуть и через Powershell:

Set-Itemproperty -path "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWebManagementServer" -Name "EnableRemoteManagement" -value "1"

В Windows Server 2012 и 2016 правило фаерволла не поднимается само, нужно править фаерволл. 

Что нам стоит CDN построить? - 4

Set-NetFirewallRule -Name IIS-WebServerRole-WMSVC-In-TCP -Enabled True

Проверяем, поднялось ли:

Что нам стоит CDN построить? - 5

Test-NetConnection 8.8.8.8 -port 8172

Три правки в трёх разных местах и теперь мы можем подключаться через диспетчер IIS к нашему серверу, используя другой сервер с десктопом. Это нужно было лишь для удобства последующего управления.

1.2 Врубаем централизацию конфигов

Для установки централизованных конфигураций и сертификатов в диспетчере IIS нет кнопок, они есть только в диспетчере локального сервера, так что для Server Core делать всё придется через Powershell.

Централизация конфигов и сертификатов осуществляется через SMB. Поэтому я сделал двух бесправных пользователей (отдельно для конфигов и отдельно для сертификатов), которые имеют доступ на чтение только к своей папке и назвал их certadmin и configadmin.

Пользователям желательно быть локальными на главном сервере — если ваш контроллер домена умрёт, то умрут и приложения, которые конфиг и сертификаты цепляют по SMB от имени пользователя домена. Использование локальных пользователей исключает подобную ситуацию.

1.2.1 Делаем общую папку

На одном из серверов должны храниться две общие папки, откуда мы берём конфигурацию и сертификаты. В качестве пути к общей папки берём дефолтный путь до конфигов IIS:

New-SmbShare -ReadAccess configadmin@**.**wtf -Path C:windowsSystem32InetsrvConfig -Name sharedconfigs

А для сертификатов можем выбрать произвольный. Я помещаю их в папку с IIS.

New-SmbShare -Path C:inetpubcentralizedcerts -Name sharedconfigs -ReadAccess configadmin 

1.2.2 Подключаем узлы к конфигам

Настройку нужно проводить только для тех серверов, которые этот конфиг будут читать. Мой главный сервер под именем cache-ru будет головой, поэтому я осуществлял настройку на двух других.
Вводим пароль пользователя, имеющего доступ к папке:

$pass = Read-Host -AsSecureString
Enable-IISSharedConfig -PhysicalPath \cache-ru.**.**wtfSharedConfig -UserName configadmin@**.**wtf -Password $pass -DontCopyRemoteKeys

Сразу после ввода должен открыться новый сеанс. Чтобы проверить, что всё заработало, можно открыть RSAT → Управление компьютером → Общие папки → Сеансы. Мы увидим сеансы пользователя и ip-адрес сервера, который под этим пользователем читает общую папку. На строне клиента проверяется командлетом:

Get-IISSharedConfig

Вот так это выглядело у меня:

Что нам стоит CDN построить? - 6

1.2.2 Подключаем узлы к сертификатам

Следующую строку можно вводить только напрямую, имея прямое подключение к рабочему столу под управлением Server c GUI, на Server Core она не работает.

$pass = Read-Host -AsSecureString
Enable-IISCentralCertProvider -CertStoreLocation \cache-ru.**.**wtfcentralizedcerts -UserName certadmin@**.**wtf -Password $pass

Если попытаетесь ввести её через Winrm, то увидите такой вывод:

Что нам стоит CDN построить? - 7

Чтобы сделать это удалённо, нужно править реестр. Как удобно! Залетаем в:

HKLM:SOFTWAREMicrosoftIISCentralCertProvider

Создаём 32-битный DWORD «Enabled» с параметром «1»:

Что нам стоит CDN построить? - 8

Set-ItemProperty -Path HKLM:SOFTWAREMicrosoftIISCentralCertProvider -Name Enabled -Value 1

Потом создаём строковое значение CertStoreLocation с параметром \cache-ru.**.**wtfcentralizedcerts:

Set-ItemProperty -Path HKLM:SOFTWAREMicrosoftIISCentralCertProvider -Name CertStoreLocation -Value <a href="about:blank">\cache-ru.**.**wtfcentralizedcerts</a>

Чтобы проверить, всё ли в порядке, используем:

Get-IISCentralCertProvider

Аутпут должен быть таким:

Что нам стоит CDN построить? - 9

И только после этого вводим:

$pass = Read-Host -AsSecureString
Set-IISCentralCertProvider -UserName certadmin@**.**wtf -Password $pass

Ещё раз проверяем:

Get-IISCentralCertProvider

Всё из коробки, что называется. В отличие от общих конфигов, централизованные сертификаты не создают активную SMB-сессию.

1.2.3 Brotli

На каждый из серверов скачиваем и запускаем файл IIS Compression

Start-Process .iiscompression_amd64.msi -ArgumentList /quiet

Мы уже расшарили конфиги, поэтому конфигурировать что-либо нужно только в одном месте. С помощью диспетчера IIS переходим в редактор конфигураций на главном сервере.

Что нам стоит CDN построить? - 10

system.webServer/httpCompression

И устанавливаем StaticCompressionLevel на 11 для Brotli и на 9 для Gzip, это максимум, что они умеют.

1.2.4 MIME и заголовки

Из коробки IIS не передаёт заголовок о кодировке, из-за чего кириллица превращается в руны. Также в MIME отсутствует запись о формате webp, которую нужно добавить.

1. Идём в диспетчер → MIME. Находим .HTML и модифицируем его тип на: text/html; charset=UTF-8

Что нам стоит CDN построить? - 11

2. Не забываем про Webp — этот MIME нужно добавить вручную.

Что нам стоит CDN построить? - 12

2. Выпускаем сертификат

С помощью Winacme. Сначала, нужно забиндить домены к сайту — это можно сделать через диспетчер IIS. При построении CDN не выбирайте верификацию по хосту, т.к. сразу начинаются проблемы с подтверждением владения доменом, наш выбор — верификация по TXT-записи. Придётся вручную вбивать путь к папке с cертификатами, так же вручную копировать запись из челленджа. А теперь, наберите воздуха в грудь.

Чтобы не печатать всё вручную, включаем RDP на Server Core следующей командой:

cscript C:WindowsSystem32Scregedit.wsf /ar 0

Вот так выглядит RDP на Server Core:

Что нам стоит CDN построить? - 13

После выполнения челленджа сертификаты падают в папку, которая была указана в Winacme. Winacme ставит задачу в планировщик на обновление сертификата. Установили и забыли.

Что нам стоит CDN построить? - 14

Ну а как закончили, можем выключить RDP — не зря ставили Server Core, столько нюансов обнаружили.

cscript C:WindowsSystem32Scregedit.wsf /ar 1

3. Биндим сертификат к узлам

Теперь нужно настроить две другие ноды, чтобы наконец заработал HTTPS. В это время на сервере, где хранятся сертификаты, HTTPS уже работает. Чтобы и остальные начали работать по HTTPS, ну, вообщем, это делается через netsh. 

Как уже мы привыкли, подключаемся к Windows Server Core по RDP чтобы запустить эту оснастку. Не смотрите на сайт в майкрософт, особенно в это руководство. Шаги в нём описаны неправильно.

С помощью netsh http show sslcert, на мастер-ноде нужно получить appid, который вводим так, как написано ниже:

netsh http add sslcert ccs=443 appid= '{4dc3e181-e14b-4a21-b022-59fc669b0914}'

Значение appid должно быть в кавычках, иначе не сработает.

4. Установка DFS

Не синхронизируйте сертификаты и конфиги через DFS, специализированные инструменты придуманы не просто так. Я пытался и вышло плохо, по какой-то неясной причине конфигурации на серверах, которые конфиг брали, просто перестали читать изменения, хоть и по первому времени это всё работало. Причину сбоя я не выяснял и решил сделать по-другому.

Дальнейшая настройка производится исключительно через RSAT, командлеты которые указаны в документации, работают только под управлением Windows Server с GUI. Развернуть репликацию DFS, используя исключительно Server Core, невозможно. Нужен либо ещё один сервер с GUI, либо компьютер на Windows 10 Pro с установленным RSAT, присоединённым к домену.

2.1. Устанавливаем

На каждый из серверов нужно установить DFS Replication:

Что нам стоит CDN построить? - 15

Install-WindowsFeature FS-DFS-Replication, FS-DFS-Namespace

2.2. Делаем новую группу репликации

Что нам стоит CDN построить? - 16

Сперва нужно пошло назвать нашу группу репликации.

Что нам стоит CDN построить? - 17

Выбирайте топологию на свой вкус. Лично мне удобнее будет добавлять контент в одно место, поэтому я выбираю звезду.

Что нам стоит CDN построить? - 18

Что нам стоит CDN построить? - 19

Один из серверов должен быть главным, именно с него начинается репликация. Если заливать файлы на слушателей, то залитый файл не реплицируется.

Что нам стоит CDN построить? - 20

В качестве папки для репликации я выбрал дефолтную папку с сайтами: 

C:inetpubwwwroot

Эта папка — путь к каталогу конкретно этого, первого сервера. Реплицировать содержимое этой папки можно куда угодно, независимо от пути.

Что нам стоит CDN построить? - 21

В рамках одной группы мы можем реплицировать несколько папок, и в последующем можем расширить их список, если понадобится.

Что нам стоит CDN построить? - 22

Закончили.

5. Тестируем производительность

Чтобы понять, сколько посетители сайта реально выиграли, нужно провести замеры. Проводиться они будут из двух точек. ПК автора в Москве и виртуальный сервер во Франкфурте. Тестироваться будут отдельно все три точки. Вот краткое содержание.

Что нам стоит CDN построить? - 23

Заходим в Devtools и наблюдаем водопад. В среднем по больнице, CDN сократит около 200 миллисекунд до полной загрузки сайта. Картинка, самый большой объект на странице, загружается как только попадает во вьюпорт, поэтому обратите внимание на синюю вертикальную черту. CDN ускорил чистый HTML + стили и скрипты на 10-15 миллисекунд, а картинка загрузилась на 220 миллисекунд быстрее, это очень значительная разница.

Москва — Москва:

Что нам стоит CDN построить? - 24

Лондон — Москва:

Что нам стоит CDN построить? - 25

Цюрих — Москва:

Что нам стоит CDN построить? - 26

Также я замерял скорость Jekyll’a на локальном хосте:

Что нам стоит CDN построить? - 27

Переходим к лайтхаусу и видим странные результаты:

Москва — Москва:

Что нам стоит CDN построить? - 28

Лондон — Москва:

Что нам стоит CDN построить? - 29

Цюрих — Москва:

Что нам стоит CDN построить? - 30

Localhost — Jekyll:

Что нам стоит CDN построить? - 31

В этой синтетике сервер, который за тридевять земель обходит локального хоста. Но почему?
Давайте ради интереса избавимся от Google Fonts и перенесём их на наши серверы.

Москва — Москва:

Что нам стоит CDN построить? - 32

Лондон — Москва:

Что нам стоит CDN построить? - 33

Цюрих — Москва:

Что нам стоит CDN построить? - 34

Localhost — Jekyll:

Что нам стоит CDN построить? - 35

Результаты между дата-центрами выровнялись. Но это всё равно ничего не объясняет. Я переделывал тесты несколько раз, результаты абсолютно железные и воспроизводимые в любое время.

Теперь воспользуемся VPS с двумя ядрами и 4 гигабайтами ОЗУ, расположенную во Франкфурте и посмотрим, что скажет она. Водопады:

Москва — Франкфурт:

Что нам стоит CDN построить? - 36

Лондон — Франкфурт:

Что нам стоит CDN построить? - 37

Цюрих — Франкфурт:

Что нам стоит CDN построить? - 38

Тут, при правильно выбранной точке экономия времени лишь на стилях и HTML составила 200 миллисекунд. То есть в случае с клиентом из Франкфурта сайт просто будет быстрее на 200 миллисекунд. Это также отражается и в лайтхаусе. В подобных случаях CDN ускорит не только интернет-магазин, но и лёгкий блог.

Москва — Франкфурт:

Что нам стоит CDN построить? - 39

Лондон — Франкфурт:

Что нам стоит CDN построить? - 40

Цюрих — Франкфурт:

Что нам стоит CDN построить? - 41

А теперь включим Google Fonts и снова посмотрим на лайтхаус.

Москва — Франкфурт:

Что нам стоит CDN построить? - 42

Лондон — Франкфурт:

Что нам стоит CDN построить? - 43

Цюрих — Франкфурт:

Что нам стоит CDN построить? - 44

К сожалению у меня больше нет точек, на которых можно было бы провести тесты, поэтому и закончу.

Выводы

  • CDN для вывода всей статики необходим, особенно если речь идёт о тяжёлых картинках или длинных скриптах. 
  • Использовать Google Fonts можно и нужно, в тяжёлых сценариях это действительно ускоряет сайт.
  • Главный сервер, если решите делать всё это на Windows, желательно должен иметь GUI.
  • Пользователей, которые будут брать конфиги с главного сервера, лучше всего делать локальными — в случае выхода из строя контроллера домена, ноды могут потерять связь с конфигами и сертификатами, а Application Pool будет остановлен, т.к. не сможет прочитать конфиг.

Что нам стоит CDN построить? - 45

Автор: ru_vds

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js