Зачем нужен 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 инвалидаций/месяц бесплатно
- Безопасность -- шифрование трафика между браузером и CDN
- SEO -- Google ранжирует HTTPS-сайты выше
- Доверие -- браузеры показывают "Not Secure" для HTTP
- Современные API -- многие браузерные API работают только по HTTPS
- CRC требование -- шаг 5 спецификации