MidПрактика3 min

DNS и CDN

Настройка CloudFront, Azure CDN и GCP Cloud CDN, кастомные домены, HTTPS и кэширование

Зачем нужен CDN

CDN (Content Delivery Network) -- это сеть серверов по всему миру, которая кэширует и раздаёт ваш контент из ближайшей к пользователю точки (edge location). Без CDN пользователь из Токио будет загружать файлы из us-east-1 (Вирджиния) -- задержка 200+ мс. С CDN -- из ближайшей edge location в Токио: 10-20 мс.

Преимущества CDN для CRC

Преимущество Описание
Скорость Контент раздаётся из ближайшей точки
HTTPS Бесплатный SSL/TLS сертификат
Custom domain Собственное доменное имя
Кэширование Снижает нагрузку на origin
DDoS защита Базовая защита от атак

AWS: CloudFront + Route53

Шаг 1: Создание CloudFront Distribution

# Создаём CloudFront distribution с S3 origin
aws cloudfront create-distribution \
  --distribution-config '{
    "CallerReference": "crc-2026",
    "Comment": "Cloud Resume Challenge",
    "DefaultCacheBehavior": {
      "TargetOriginId": "S3-ivan-petrov-resume",
      "ViewerProtocolPolicy": "redirect-to-https",
      "AllowedMethods": ["GET", "HEAD"],
      "CachedMethods": ["GET", "HEAD"],
      "ForwardedValues": {
        "QueryString": false,
        "Cookies": {"Forward": "none"}
      },
      "MinTTL": 0,
      "DefaultTTL": 86400,
      "MaxTTL": 31536000,
      "Compress": true
    },
    "Origins": {
      "Quantity": 1,
      "Items": [
        {
          "Id": "S3-ivan-petrov-resume",
          "DomainName": "ivan-petrov-resume.s3.amazonaws.com",
          "S3OriginConfig": {
            "OriginAccessIdentity": ""
          }
        }
      ]
    },
    "Enabled": true,
    "DefaultRootObject": "index.html",
    "PriceClass": "PriceClass_100"
  }'

PriceClass_100 -- наименее дорогой вариант, покрывает Северную Америку и Европу. Достаточно для CRC.

Шаг 2: Настройка OAC (Origin Access Control)

OAC заменяет публичный доступ к S3 -- бакет доступен только через CloudFront:

# Создаём OAC
aws cloudfront create-origin-access-control \
  --origin-access-control-config '{
    "Name": "crc-oac",
    "Description": "OAC for CRC S3 bucket",
    "SigningProtocol": "sigv4",
    "SigningBehavior": "always",
    "OriginAccessControlOriginType": "s3"
  }'

# Обновляем bucket policy
# Теперь только CloudFront может читать из S3
aws s3api put-bucket-policy --bucket ivan-petrov-resume --policy '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontServicePrincipal",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::ivan-petrov-resume/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/EDXXXXXXX"
        }
      }
    }
  ]
}'

Шаг 3: SSL-сертификат через ACM

# Запрашиваем сертификат (ОБЯЗАТЕЛЬНО в us-east-1 для CloudFront!)
aws acm request-certificate \
  --domain-name resume.ivanpetrov.com \
  --validation-method DNS \
  --region us-east-1

# ACM создаст CNAME-запись для валидации
# Добавьте её в DNS и дождитесь подтверждения

Шаг 4: DNS через Route53

# Создаём хостинговую зону
aws route53 create-hosted-zone \
  --name ivanpetrov.com \
  --caller-reference "crc-$(date +%s)"

# Создаём A-запись (Alias) на CloudFront
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890 \
  --change-batch '{
    "Changes": [
      {
        "Action": "UPSERT",
        "ResourceRecordSet": {
          "Name": "resume.ivanpetrov.com",
          "Type": "A",
          "AliasTarget": {
            "HostedZoneId": "Z2FDTNDATAQYW2",
            "DNSName": "d1234567890.cloudfront.net",
            "EvaluateTargetHealth": false
          }
        }
      }
    ]
  }'

Z2FDTNDATAQYW2 -- это фиксированный Hosted Zone ID для CloudFront. Он одинаков для всех distributions.

Azure: CDN + Custom Domain

Шаг 1: Создание CDN Profile и Endpoint

# Создаём CDN Profile
az cdn profile create \
  --resource-group crc-resources \
  --name crc-cdn-profile \
  --sku Standard_Microsoft

# Создаём CDN Endpoint
az cdn endpoint create \
  --resource-group crc-resources \
  --profile-name crc-cdn-profile \
  --name ivanpetrov-resume \
  --origin ivanpetrovresume.z6.web.core.windows.net \
  --origin-host-header ivanpetrovresume.z6.web.core.windows.net \
  --enable-compression

Шаг 2: Custom Domain

# Добавляем custom domain (предварительно создайте CNAME в DNS)
# CNAME: resume.ivanpetrov.com -> ivanpetrov-resume.azureedge.net

az cdn custom-domain create \
  --resource-group crc-resources \
  --profile-name crc-cdn-profile \
  --endpoint-name ivanpetrov-resume \
  --hostname resume.ivanpetrov.com \
  --name resume-domain

Шаг 3: HTTPS для Custom Domain

# Включаем HTTPS (Azure бесплатно предоставляет сертификат)
az cdn custom-domain enable-https \
  --resource-group crc-resources \
  --profile-name crc-cdn-profile \
  --endpoint-name ivanpetrov-resume \
  --name resume-domain

GCP: Cloud CDN + Load Balancer

Шаг 1: Создание бэкенд-бакета

# Создаём backend bucket
gcloud compute backend-buckets create crc-backend \
  --gcs-bucket-name=ivan-petrov-resume \
  --enable-cdn

# Создаём URL map
gcloud compute url-maps create crc-url-map \
  --default-backend-bucket=crc-backend

# Создаём HTTP(S) proxy
gcloud compute target-https-proxies create crc-https-proxy \
  --url-map=crc-url-map \
  --ssl-certificates=crc-cert

# Создаём forwarding rule (это IP-адрес)
gcloud compute forwarding-rules create crc-https-rule \
  --target-https-proxy=crc-https-proxy \
  --ports=443 \
  --global

Шаг 2: SSL-сертификат

# Google-managed SSL certificate
gcloud compute ssl-certificates create crc-cert \
  --domains=resume.ivanpetrov.com \
  --global

Шаг 3: DNS

# Создаём DNS-зону
gcloud dns managed-zones create ivanpetrov-zone \
  --dns-name=ivanpetrov.com \
  --description="CRC DNS zone"

# A-запись на Load Balancer IP
gcloud dns record-sets create resume.ivanpetrov.com \
  --zone=ivanpetrov-zone \
  --type=A \
  --ttl=300 \
  --rrdatas=34.120.XX.XX  # IP из forwarding rule

Стоимость GCP: Load Balancer стоит ~$18/месяц -- это значительно дороже, чем CloudFront и Azure CDN. Для CRC используйте $300 кредитов или рассмотрите Firebase Hosting как альтернативу.

Сравнение CDN-решений

Параметр CloudFront Azure CDN GCP Cloud CDN
Настройка Средняя Простая Сложная (нужен LB)
Бесплатный SSL Да (ACM) Да Да
Стоимость Free Tier: 1TB/мес Free Tier: 15GB/мес ~$18/мес (LB)
Edge locations 400+ 100+ 100+
Время инвалидации 5-10 минут 10 минут 5-10 минут
Wildcard SSL Да Да Да

Инвалидация кэша

После обновления файлов нужно очистить CDN-кэш:

Инвалидация всех файлов

aws cloudfront create-invalidation
--distribution-id EDXXXXXXX
--paths "/*"

Инвалидация конкретного файла

aws cloudfront create-invalidation
--distribution-id EDXXXXXXX
--paths "/index.html" "/style.css"

Первые 1000 инвалидаций/месяц бесплатно

## HTTPS: почему это обязательно
  1. Безопасность -- шифрование трафика между браузером и CDN
  2. SEO -- Google ранжирует HTTPS-сайты выше
  3. Доверие -- браузеры показывают "Not Secure" для HTTP
  4. Современные API -- многие браузерные API работают только по HTTPS
  5. CRC требование -- шаг 5 спецификации

Проверь себя

Почему GCP Cloud CDN значительно дороже для CRC, чем CloudFront или Azure CDN?

В каком регионе AWS ОБЯЗАТЕЛЬНО нужно запрашивать SSL-сертификат через ACM для CloudFront?

Зачем нужна инвалидация кэша CDN после обновления файлов?

Что такое OAC (Origin Access Control) в контексте CloudFront и S3?

Что такое CDN и зачем он нужен для Cloud Resume?

Связанные темы