Kubernetes на нескольких континентах: высокодоступные k3s и k8s в дата-центрах по всему миру
Kubernetes в США, Европе и Азии, в котором допустим отказ целого континента: почему etcd не переносит больших расстояний, кластер k3s в каждом регионе, GitOps с Flux, failover через Geo-DNS, данные между регионами и отличия от kubeadm.
Если приложения должны работать отказоустойчиво и автоматически масштабироваться, стандартом служит Kubernetes. Однако очевидная идея растянуть один-единственный кластер Kubernetes на серверы в США, Европе и Азии разбивается об одну деталь: об etcd, базу данных, в которой Kubernetes хранит всё своё состояние. В этой статье показано, как Kubernetes на нескольких континентах всё же работает, причём так, что допустим отказ целого континента: с одним кластером на регион, единым развёртыванием через GitOps и Geo-DNS, который направляет пользователей в ближайший исправный регион.
Архитектуру мы строим на k3s, лёгком, полностью сертифицированном дистрибутиве Kubernetes, который устанавливается за считаные минуты, а в конце показываем, что меняется с классическим Kubernetes, развёрнутым через kubeadm. Основы доступности, кворума и failover на нескольких площадках подробно разобраны в статье Docker Swarm на трёх континентах; здесь речь идёт о том, что в Kubernetes устроено иначе.
Один кластер на все континенты или по кластеру на регион?
Для Kubernetes на нескольких континентах правильной архитектурой является один кластер на регион, а не единый кластер на все континенты. Каждый кластер работает сам по себе, все они выкатываются из одного и того же Git-репозитория, а Geo-DNS с проверками доступности распределяет пользователей. Если регион выходит из строя, работу берут на себя остальные, и никакое общее состояние кластера не нужно согласовывать через океан.
Почему etcd не переносит больших расстояний
Kubernetes хранит всё состояние, каждую настройку и каждое изменение в etcd, хранилище «ключ-значение» с консенсусом Raft. Каждая операция записи требует подтверждения от большинства всех участников etcd. По умолчанию etcd работает с интервалом heartbeat 100 миллисекунд и тайм-аутом выборов в одну секунду, а время прохождения пакетов между Европой, Северной Америкой и Азией составляет от 80 до 250 миллисекунд. Эти значения можно увеличить, но тогда медленной становится любая запись в кластере, от планирования пода до сохранения секрета. Документация k3s здесь однозначна: встроенный etcd не поддерживается в кластерах, распределённых по нескольким сетям, и все серверы должны находиться на одной площадке. Да и сам Kubernetes рассчитан на то, что кластер охватывает несколько зон внутри одного региона, а не несколько континентов.
Сравнение трёх схем
| Схема | Как это работает | Оценка |
| Один кластер на все континенты | Управляющий слой и etcd распределены по нескольким континентам | Не рекомендуется: медленная запись, нестабильный etcd, в k3s со встроенным etcd не поддерживается |
| Управляющий слой в одном регионе, рабочие узлы по всему миру | Серверы на одной площадке, агенты на других континентах | Технически работает, но если регион с управляющим слоем выходит из строя, нигде в мире больше ничего нельзя запланировать заново |
| Один кластер на регион | Три независимых кластера, которые вместе выкатываются через GitOps, перед ними Geo-DNS | Рекомендуется: каждый регион переживает отказ остальных, сбои не выходят за пределы одного региона |
У подхода «один кластер на регион» есть второе, часто недооцениваемое преимущество: ошибка в управляющем слое, неудачное изменение в кластере или обновление, которое пошло не так, всегда затрагивают только один регион. Пользователи других регионов ничего не замечают.
k3s или k8s?
Оба варианта представляют собой настоящий Kubernetes с тем же API, теми же манифестами и теми же инструментами. Разница заключается в устройстве и в трудозатратах:
| Характеристика | k3s | k8s с kubeadm |
| Установка | Одна команда, один бинарный файл | Среда выполнения контейнеров, kubeadm, kubelet и сетевой плагин настраиваются по отдельности |
| Ресурсы для серверного узла | Минимум 2 ядра и 2 ГБ ОЗУ | Заметно больше, в зависимости от компонентов |
| В комплекте | Ingress-контроллер (Traefik), сеть (Flannel), провижинер хранилища, балансировщик нагрузки для сервисов | Только ядро, всё остальное вы выбираете сами |
| Высокая доступность | Встроенный etcd на трёх серверах | Три узла control plane с балансировщиком нагрузки перед API |
| Подходит для | Большинства приложений, небольших команд, одиночных узлов в регионах | Команд, которые хотят сами выбирать каждый компонент |
Для архитектуры «один кластер на регион» мы рекомендуем k3s: эксплуатировать три кластера удобно лишь тогда, когда каждый из них прост. Если у вас уже есть опыт работы с kubeadm, вы можете применить эту архитектуру без изменений, а различия показаны в разделе о kubeadm ниже.
Архитектура: три региона, три кластера, одна точка входа
| Компонент | Задача | От какого отказа защищает |
| Кластер k3s в каждом регионе | Запускает приложение рядом с пользователями | Отказ целого региона |
| Три сервера на регион (этап расширения) | Обеспечивает высокую доступность etcd и управляющего слоя внутри региона | Отказ отдельных серверов в регионе |
| Git-репозиторий и Flux в каждом кластере | Каждый кластер сам забирает своё желаемое состояние из Git | Нет центрального сервера развёртывания, который стал бы точкой отказа |
| Ingress с сертификатами через DNS-challenge | Принимает запросы пользователей | Сертификаты работают независимо от переключения DNS |
| Geo-DNS с проверками доступности | Направляет пользователей в ближайший исправный регион | Недоступные регионы |
| Реплицируемое хранение данных и резервные копии | Хранит данные в нескольких регионах | Потеря данных при отказе региона |
Начальный этап и расширение
На начальном этапе нужны три сервера, по одному в США, Европе и Азии, и каждый работает как отдельный кластер из одного узла. Если сервер выходит из строя, вместе с ним отказывает и его регион, а Geo-DNS направляет пользователей этого региона в соседний. Уже этот этап рассчитан на отказ целого континента. При расширении каждый регион получает три сервера на одной площадке; тогда каждый регион и сам по себе переживает отказ одного сервера, без перенаправления пользователей.
Какие локации KernelHost подходят
KernelHost эксплуатирует серверы в дата-центре maincubes во Франкфурте-на-Майне и предлагает виртуальные серверы в других локациях в Европе, Северной Америке и Азиатско-Тихоокеанском регионе, в том числе в трёх локациях в США, а также в Канаде, Лондоне, Страсбурге, Варшаве, Хельсинки, Сингапуре, Японии, Сиднее и Мумбаи. Полный список приведён на странице Локации серверов. В примере этой статьи используются Франкфурт-на-Майне для Европы, восточное побережье США для Северной Америки и Сингапур для Азии.
Руководство: Kubernetes на k3s в трёх регионах
В примере используются три сервера с Debian 12 или 13: k3s-eu, k3s-us и k3s-asia. Публичные адреса взяты из диапазона для документации 203.0.113.0/24, в качестве домена выступает example.com. Замените и то, и другое своими значениями.
Шаг 1: подготовить серверы в трёх регионах
Закажите три сервера в трёх регионах, минимум с 2 vCPU и 4 ГБ ОЗУ, чтобы помимо k3s хватило места и для вашего приложения. Выполните базовую защиту по чек-листу для новых root-серверов и задайте понятные имена хостов. etcd заметно выигрывает от быстрых SSD, и NVMe-накопители серверов KernelHost этому требованию отвечают.
Шаг 2: установить k3s
На каждый из трёх серверов установите k3s одной командой. После этого каждый сервер становится полноценным кластером Kubernetes из одного узла:
curl -sfL https://get.k3s.io | sh -
kubectl get nodes
Примерно через минуту kubectl get nodes покажет узел в состоянии Ready. В комплект входят Traefik в качестве Ingress-контроллера, Flannel для сети и провижинер для локальных томов.
Шаг 3: расширение до трёх серверов на регион
Если высокодоступным должен стать и сам регион, разместите три сервера на одной площадке. Первый сервер запускает встроенный etcd, два других присоединяются к нему с общим токеном. etcd требует нечётного числа серверов, и при трёх серверах регион выдерживает отказ одного из них:
curl -sfL https://get.k3s.io | K3S_TOKEN=СЕКРЕТНЫЙ_ТОКЕН sh -s - server \
--cluster-init \
--tls-san=api.eu.example.com
curl -sfL https://get.k3s.io | K3S_TOKEN=СЕКРЕТНЫЙ_ТОКЕН sh -s - server \
--server https://203.0.113.21:6443 \
--tls-san=api.eu.example.com
Всем серверам одного региона нужны одинаковые настройки сетевых диапазонов и функций. Между ними должны быть открыты порты от 2379 до 2380/TCP для etcd, 6443/TCP для API, 10250/TCP для kubelet и 8472/UDP для сети Flannel, а снаружи они остаются закрытыми. Токен является секретом: тот, кто его знает, может подключить к кластеру собственные серверы.
Шаг 4: настроить доступ ко всем трём кластерам
k3s сохраняет данные для доступа в файле /etc/rancher/k3s/k3s.yaml. Скопируйте этот файл из каждого кластера на свой рабочий компьютер, замените в нём 127.0.0.1 адресом сервера и назовите контексты по регионам:
kubectl config rename-context default eu
kubectl config use-context eu
kubectl --context us get nodes
API на порту 6443 открывает самый мощный доступ к кластеру. Разрешайте его в файрволе только со своего адреса или через VPN и никогда для всего интернета. Файл k3s.yaml содержит сертификат администратора, и хранить его нужно так же бережно, как пароль root.
Шаг 5: GitOps с Flux в каждом кластере
Чтобы во всех трёх регионах работало одно и то же приложение одной и той же версии, желаемое состояние хранится в Git-репозитории, а в каждом кластере работает Flux, который самостоятельно приводит кластер к этому состоянию. Таким образом, каждый кластер сам забирает свою конфигурацию, и центрального сервера развёртывания, который мог бы выйти из строя, нет. Проверенная структура репозитория:
apps/
web/ общие манифесты приложения
clusters/
eu/ настройки и версия для Европы
us/ настройки и версия для Северной Америки
asia/ настройки и версия для Азии
flux bootstrap git --url=ssh://git@git.example.com/infra/fleet.git --branch=main --path=clusters/eu
Ту же команду выполните с --path=clusters/us и --path=clusters/asia в соответствующем контексте. Поскольку у каждого региона свой каталог, новую версию можно сначала выкатить в одном регионе и лишь затем в остальных.
Шаг 6: описать приложение с учётом отказоустойчивости
Внутри региона пережить обслуживание и отказы серверов приложению помогают три вещи: несколько реплик, распределённых по разным узлам, проверки, которые распознают неисправные поды, и бюджет, который не даёт обслуживанию убрать все поды одновременно:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: web
containers:
- name: web
image: registry.example.com/web:1.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 10
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web
spec:
minAvailable: 1
selector:
matchLabels:
app: web
Readiness-проба исключает под из обработки трафика, пока он не отвечает, а liveness-проба перезапускает его, если он завис. В кластере из одного узла распределение по нескольким узлам пока не действует, оно включается автоматически, как только в регионе появятся три сервера.
Шаг 7: Ingress и сертификаты
Входящий трафик принимает встроенный Traefik. Поскольку все три региона обслуживают один и тот же домен, получайте TLS-сертификаты с помощью cert-manager через DNS-challenge: такая проверка работает в любом регионе, независимо от того, куда в данный момент указывает DNS-запись. HTTP-challenge, напротив, не проходит в каждом регионе, на который запись в данный момент не указывает. Если вы работаете без Kubernetes Ingress, основы найдёте в статье Настройка nginx как reverse proxy.
Шаг 8: настроить Geo-DNS с failover
DNS-сервис с геомаршрутизацией и проверками доступности направляет пользователей из Европы во Франкфурт-на-Майне, из Америки на восточное побережье США, а из Азии в Сингапур и с интервалом от 30 до 60 секунд проверяет, отвечает ли точка входа каждого региона. Если регион выходит из строя, сервис перестаёт выдавать его адрес. Задайте для записей TTL 60 секунд, тогда переключение обычно завершается через одну-две минуты. Если вы хотите управлять записями прямо из кластера, для этого можно использовать external-dns.
Шаг 9: выкатывать регион за регионом и тестировать отказ
Новую версию сначала пропишите в каталоге одного региона, понаблюдайте за этим регионом несколько минут и только затем перенесите версию в остальные. Так ошибка, которую не распознаёт ни одна проверка, затронет самое большее один регион. Чтобы отрепетировать отказ региона, остановите k3s на его сервере и проверьте, убирает ли Geo-DNS этот регион из своих ответов и берёт ли соседний регион нагрузку на себя:
systemctl stop k3s
systemctl start k3s
В регионе с тремя серверами дополнительно отрепетируйте обслуживание отдельного сервера. kubectl drain переносит поды с учётом бюджета из шага 6, а kubectl uncordon снова вводит сервер в работу:
kubectl drain k3s-eu-2 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon k3s-eu-2
Данные между регионами
Kubernetes распределяет поды, а не данные. PersistentVolume встроенного провижинера находится ровно на одном узле, а общего хранения данных между кластерами из коробки нет вовсе. Поэтому для всего, что связано с данными, действуют те же правила, что и для любого кластера на нескольких площадках:
- Базы данных реплицируются собственными средствами. Хорошо зарекомендовала себя схема с основным экземпляром в одном регионе и репликами в остальных; операторы баз данных вроде CloudNativePG для PostgreSQL поддерживают такие реплики и через границы кластеров. Между континентами репликация идёт асинхронно, и в случае аварии записи за последние секунды могут быть потеряны. Для записи без потерь по всему миру существуют мультирегиональные базы данных, например CockroachDB или YugabyteDB.
- Файлы и загрузки должны храниться в S3-совместимом объектном хранилище с репликацией во второй регион.
- Сессии хранятся в реплицируемой базе данных или реплицируемом кэше, либо приложение использует подписанные токены.
- Резервные копии остаются обязательными, потому что репликация распространяет ошибки точно так же, как корректные данные. Для объектов и томов Kubernetes подходит Velero, а основы описаны в стратегии резервного копирования для серверов.
Kubernetes с kubeadm вместо k3s
С kubeadm архитектура остаётся прежней: один кластер на регион, GitOps, Geo-DNS. Отличается устройство каждого кластера. На все узлы вы устанавливаете среду выполнения контейнеров вроде containerd, а также kubeadm, kubelet и kubectl, ставите перед API региона балансировщик нагрузки или виртуальный адрес, например с помощью kube-vip, и инициализируете первый узел control plane:
kubeadm init --control-plane-endpoint "api.eu.example.com:6443" --upload-certs
Вывод содержит две команды присоединения: одну с --control-plane --certificate-key для двух дополнительных узлов control plane и одну для рабочих узлов. После этого вы устанавливаете сетевой плагин, например Calico или Cilium, и Ingress-контроллер, который в k3s уже есть в комплекте. Дополнительные усилия оправданы, если вам нужно целенаправленно выбирать отдельные компоненты или держаться как можно ближе к upstream-версии.
Почему KernelHost для Kubernetes на нескольких континентах
| Требование | Почему это важно | В KernelHost |
| Локации на нескольких континентах | Схеме «один кластер на регион» нужны серверы в каждом регионе | Франкфурт-на-Майне, а также локации в Европе, Северной Америке и Азиатско-Тихоокеанском регионе у одного провайдера |
| Безлимитный трафик | Загрузка образов, репликация баз данных и резервное копирование постоянно создают трафик | VPS с безлимитным трафиком без ограничения объёма |
| Быстрые накопители | etcd чувствителен к медленным дискам | NVMe SSD в RAID |
| Защита от DDoS | Каждый Ingress доступен из интернета | Включена в каждой локации, на основной площадке во Франкфурте-на-Майне с фильтрацией Arbor в реальном времени на 3,2 Тбит/с, без null-routing |
| Полный root-доступ | Для k3s, файрвола и настроек ядра нужен полный контроль | На каждом KVM root-сервере и выделенном сервере |
| Без долгосрочного договора | Узлы и тестовые кластеры появляются и исчезают | PrePaid, без минимального срока, без платы за подключение |
| Автоматизация | Новые узлы должны создаваться скриптом | Заказ и управление через KernelHost API |
Обзор всех облачных тарифов и сравнение стоимости с крупными облачными провайдерами вы найдёте на странице Аренда облачного сервера.
Частые ошибки и как их избежать
- etcd растянут на несколько континентов. Следствием становятся медленная запись и нестабильные выборы лидера, а в k3s со встроенным etcd такая схема не поддерживается. Решение: один кластер на регион.
- Два сервера в одном регионе. etcd нужно большинство, и два сервера не выдерживают ни одного отказа. Решение: один или три.
- API открыт для всего интернета. Порт 6443 служит мастер-ключом к кластеру. Решение: доступ только со своего адреса или через VPN.
- Центральный сервер развёртывания. Если он выходит из строя, выкатить больше ничего нельзя. Решение: Flux в каждом кластере, самостоятельно забирающий всё необходимое из Git.
- Обновление во всех регионах одновременно. Тогда ошибка затрагивает всех пользователей. Решение: регион за регионом через каталоги в репозитории.
- Сертификаты через HTTP-challenge. В регионах, на которые DNS-запись в данный момент не указывает, продление не проходит. Решение: DNS-challenge.
- База данных на локальном томе без репликации. Если узел выходит из строя, данные недоступны. Решение: репликация через оператор базы данных.
- Ни проб, ни бюджета. Неисправные поды продолжают получать трафик, а обслуживание снимает с сети все поды одновременно. Решение: readiness- и liveness-пробы плюс PodDisruptionBudget.
Коротко о главном
- Для Kubernetes на нескольких континентах правильно строить по одному кластеру на регион, а единый кластер на все континенты упирается в задержки, которые не переносит etcd.
- Для начала нужны три сервера, по одному в США, Европе и Азии; уже этот этап переживает отказ целого континента.
- При расширении каждый регион получает три сервера на одной площадке, и тогда каждый регион переживает также отказы отдельных серверов.
- Flux в каждом кластере выкатывает приложение из одного и того же Git-репозитория, регион за регионом.
- Geo-DNS с проверками доступности и коротким TTL направляет пользователей в ближайший исправный регион, а сертификаты выпускаются через DNS-challenge.
- Kubernetes распределяет поды, а не данные: базам данных нужна собственная репликация, резервные копии остаются обязательными.
- Для этой архитектуры k3s обычно подходит лучше, чем kubeadm, потому что три простых кластера эксплуатировать легче, чем три сложных.
Частые вопросы
Может ли кластер Kubernetes работать на нескольких континентах?
Как построить высокодоступный Kubernetes в нескольких регионах?
Чем k3s отличается от k8s?
Сколько серверов нужно высокодоступному кластеру k3s?
Какие порты нужны k3s?
Как выкатывать приложения в несколько кластеров Kubernetes?
Как работает failover между регионами Kubernetes?
Как сохранить данные при отказе региона?
Kubernetes или Docker Swarm для нескольких континентов?
Какие локации KernelHost подходят для Kubernetes на нескольких континентах?
Сколько стоит Kubernetes на трёх континентах?
2026 KernelHost GmbH. Все права защищены. Эта инструкция охраняется авторским правом. Публикация на других сайтах, в том числе частично или в изменённом виде, без нашего письменного согласия не разрешается. Цитирование с указанием источника и активной ссылкой мы приветствуем.

