Изначальная структура сети и почему мы решили от неё отказаться.
Так получилось, что АО «АльфаСтрахование» был одним из первых клиентов, которые начали использовать облачную платформу Яндекс.Облако. Множество фич и функционала, которые сейчас присутствуют в платформе тогда отсутствовали, а перед нами стояла задача организовать крупную сеть с множеством изолированных сегментов.
Поскольку в облаке, в тот момент времени, отсутствовал необходимый функционал, мы решили построить архитектуру с использованием CSR.
Как видно из схемы на CSR-2 был развернут IPSEC-туннель, который соединял Яндекс.Облако с нашей инфраструктурой. У каждого из CSR были основные и дополнительные интерфейсы, сабнеты которых были развернуты в отдельных VPC-фолдерах. Таким образом осуществлялась сетевая связность и сетевая фильтрация, дополнительная фильтрация осуществлялась, в том числе на пограничном межсетевом экране в нашей инфраструктуре.
Причины отказа от старой схемы и IPSEC-туннеля.
Изменения были очень болезненны и вызывали downtime, так как для добавления новых сабнетов необходимо было проводить технические работы на CSR с IPSEC-туннелем, а также на CSR в котором был добавлен новый сабнет. Новые сабнеты были необходимы для горизонтального масштабирования облачной инфраструктуры.
IPSEC-туннель являлся для нас «узким местом» при реализации ресурсоемких задач, а связанные с этим процессы приводили к нестабильной работе CSR-2. Соединение осуществлялось через сеть Интернет, а значит провайдеры становились точками отказа. При сбоях в зоне «A» CSR-2 вел себя нестабильно и сбрасывал туннель, терялась связность облака и нашей инфраструктуры. Все это очень мешало нашим разработчикам нормально работать.
Подготовка и переезд на Interconnect.
По прошествии времени, часть функционала в облаке, который нам требовался был реализован командой Яндекс.Облака (за что им огромное спасибо) и мы, с удовольствием, двинулись дальше в использовании более технологичных подходов, которые требовали глобальное изменение архитектуры применяемых решений.
Yandex Cloud Interconnect - позволяет установить приватное выделенное оптическое соединение между локальной сетевой инфраструктурой компании и Яндекс.Облаком.
После появления в «preview» групп безопасности мы стали использовать этот инструмент для осуществления фильтрации трафика. На данный момент в нашем облаке используется более 100 групп безопасности.
Во время подготовки к переезду на Interconnect перед нами возник ряд задач по оптимизации работы инфраструктуры. В этот момент возникла идея отказа от CSR для обеспечения маршрутизации трафика внутри облака, при этом IPSEC-туннель по-прежнему оставался на CSR-2.
Необходимо было перенести виртуальные машины из текущих сабнетов в новые с аналогичной адресацией, так как сетевые доступы были настроены на межсетевом экране внутри нашей инфраструктуры.
Переназначение сабнетов необходимо было осуществлять для всех ресурсов в фолдере за один раз, так как при создании дублирующей сети, она автоматически “выигрывала” у существующей, и маршрутизация начинала осуществляться через нее. Это происходило в связи существованием статического маршрута, который создали коллеги из Яндекс.Облака на своем оборудовании для реализации схемы с CSR.
Перенос виртуальных машин производился при помощи инструментов Yandex.Cloud CLI и Terraform:
Создание сети:
resource "yandex_vpc_subnet" "имя ресурса" {
name = "имя сабнета"
v4_cidr_blocks = ["cidr сабнета"]
zone = "ru-central1-b" //зона сабнета
network_id = "id VPC в default фолдере"
description = null folder_id = "id целевого фолдера"
labels = null route_table_id = "необходимая таблица маршрутизации"
dhcp_options {
domain_name = null domain_name_servers = ["8.8.8.8", "8.8.8.8"]
ntp_servers = ["8.8.8.8", "8.8.8.8"]
}
}
Перенос ВМ в новый сабнет:
yc compute instance update-network-interface id-вм --subnet-id=id-сабнета --ipv4-address=ip-вм --network-interface-index=0 --security-group-id=группа безопасности.
yc compute instance add-one-to-one-nat --id=fhm27r0odfkn5kjcv6lr --network-interface-index=0 --nat-address=0.0.0.0 - назначение public-ip на ВМ (уточню что перед назначением все public ip-адреса были переключены в статические через консоль управления в облаке.)
Если для виртуальных машинами схема переключения была достаточно прозрачной, то в переключении кластерных решений оказалось больше “подводных камней”.
Для того, чтобы осуществить перенос K8S-кластеров, необходимо было пересоздать их с восстановлением из бекапа при помощи Velero.
В этот же момент возникла проблема: имеющиеся в работе кластеры были deprecated-версий (снятых с поддержки в Яндекс.Облаке). Для осуществления и последующей развертки бекапа необходимо было обновить текущие кластеры на новую версию, и только после этого осуществить резервное копирование и развертку нового кластера.
После переключения кластеров, их Сервисным аккаунтам потребовались новые роли (vpc.user, vpc.admin) на главный фолдер (default) в котором находилась основная VPC и это стало для нас неожиданностью. В итоге проблему с доступом мы решали во время запланированных работ. Появилась необходимость создать особые группы безопасности, но на тот момент их ещё не было в официальной документации Яндекс.Облака, и мы получили их через нашего менеджера от Яндекс.Облака:
resource "yandex_vpc_security_group" "k8s-main-sg" {
name = "k8s-main-sg"
description = "Правила группы обеспечивают базовую работоспособность кластера. Примените ее к кластеру и группам узлов."
network_id = "<идентификатор облачной сети>"
ingress {
protocol = "TCP"
description = "Правило разрешает проверки доступности с диапазона адресов балансировщика нагрузки. Нужно для работы отказоустойчивого кластера и сервисов балансировщика."
v4_cidr_blocks = ["198.18.235.0/24", "198.18.248.0/24"]
from_port = 0
to_port = 65535
}
ingress {
protocol = "ANY"
description = "Правило разрешает взаимодействие master-to-node и node-to-node внутри группы безопасности."
predefined_target = "self_security_group"
from_port = 0
to_port = 65535
}
ingress {
protocol = "ANY"
description = "Правило разрешает взаимодействие pod-to-pod и service-to-service. Укажите подсети вашего кластера и сервисов."
v4_cidr_blocks = ["10.129.0.0/24"]
from_port = 0
to_port = 65535
}
ingress {
protocol = "ICMP"
description = "Правило разрешает отладочные ICMP-пакеты из внутренних подсетей."
v4_cidr_blocks = ["172.16.0.0/12"]
}
egress {
protocol = "ANY"
description = "Правило разрешает весь исходящий трафик. Узлы могут связаться с Yandex Object Storage, Yandex Container Registry, Docker Hub и т. д."
v4_cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 65535
}
}
resource "yandex_vpc_security_group" "k8s-public-services" {
name = "k8s-public-services"
description = "Правила группы разрешают подключение к сервисам из интернета. Примените правила только для групп узлов."
network_id = "<идентификатор облачной сети>"
ingress {
protocol = "TCP"
description = "Правило разрешает входящий трафик из интернета на диапазон портов NodePort. Добавьте или измените порты на нужные вам."
v4_cidr_blocks = ["0.0.0.0/0"]
from_port = 30000
to_port = 32767
}
}
resource "yandex_vpc_security_group" "k8s-nodes-ssh-access" {
name = "k8s-nodes-ssh-access"
description = "Правила группы разрешают подключение к узлам кластера через SSH. Примените правила только для групп узлов."
network_id = "<идентификатор облачной сети>"
ingress {
protocol = "TCP"
description = "Правило разрешает подключение к узлам по SSH с указанных IP-адресов."
v4_cidr_blocks = ["85.32.32.22/32"]
port = 22
}
}
resource "yandex_vpc_security_group" "k8s-master-whitelist" {
name = "k8s-master-whitelist"
description = "Правила группы разрешают доступ к Kubernetes API из интернета. Примените правила только к кластеру."
network_id = "<идентификатор облачной сети>”
ingress {
protocol = "TCP"
description = "Правило разрешает подключение к Kubernetes API через порт 6443 из указанной сети."
v4_cidr_blocks = ["203.0.113.0/24"]
port = 6443
}
ingress {
protocol = "TCP"
description = "Правило разрешает подключение к Kubernetes API через порт 443 из указанной сети."
v4_cidr_blocks = ["203.0.113.0/24"]
port = 443
}
}
Подробнее можно посмотреть тут: https://cloud.yandex.ru/docs/managed-kubernetes/operations/security-groups
Перенос MDB-кластеров осуществлялся через резервную копию и пересоздание в новых сабнетах с последующей разверткой бекапа. Проблем с этими операциями не возникло. Группы виртуальных машин были развернуты в новых сетях, и их сервисным аккаунтам понадобилась новая роль в фолдере default (vpc.user). Без этой роли группа виртуальных машин не разворачивалась в новом сабнете при автоматическом пересоздании ноды. К счастью, данную проблему, мы обнаружили на этапах тестирования.
Новая структура сети, работа через интерконнект.
Новая структура сети позволила легко создавать новые фолдеры и привязывать к ним сети. При использовании Interconnect появилась необходимость анонсировать новые сети через техническую поддержку Яндекс.Облака. Так же нахождение всех сетей в одном VPC позволило отказаться от использования Таблиц Маршрутизации для сабнетов. Самым большим плюсом стала возможность отделить права доступа на использование сетей и Групп безопасности от остальных фолдеров. Основным недостатком данной схемы являются недокументированные проблемы с нехваткой прав доступа.
Для перехода на новую сетевую маршрутизацию была проделана огромная совместная работа подразделений Информационной безопасности и Разработки.
В итоге, Коллеги из разработки были обеспечены надежным каналом связи, а мы контролем сетевых подключений как внутри Яндекс.Облака на конечных точках управления, так и в разрезе Облако-Инфраструктура компании.
Список источников:
Общие концепции Групп Безопасности
Комментарии (8)
chemtech
18.09.2021 14:28+2Спасибо за интересный пост.
имеющиеся в работе кластеры были deprecated-версий (снятых с поддержки в Яндекс.Облаке).
Какие именно версии Kubernetes у вас были? Какие главные причины не обновления Kubernetes? Спасибо.
innomaker Автор
18.09.2021 16:17Версия 1.15. Там находился специфический софт, при обновлении кластера необходимо было обновить и его, это и было временным стоппером.
achekalin
Хочется узнать, с вашего позволения: каковы причины переезда в облако (любое), в котором отсутствуют на момент переезда многие важные фичи. К тому моменту «стабильных» облаков базе той же вмвари было достаточно много, что заставило компанию масштаба Альфы становиться первопроходцем и испытателем preview решений и строить костыли на своей стороне, чтобы получить отсутствующие еще в оьлаке функции?
Не буду говорить, что в Альфе словно бы нет других проблем, кроме как таким лихим образом тестировать новинку - компании виднее. Надеюсь, от все этих переездов и перенастроек туннелей не очень страдали операции для клиентов.
В общем, если бы вы дописали абзац-другой о том, почему ушли в облако, и почему ушли именно в это облако, статья бы выиграла!
innomaker Автор
Облака на базе vmware безусловно были и являются стабильным решением. На момент пилотирования Яндекс.Облака в нем было больше возможностей, гибкости и технического потенциала, чем в нашем текущем на тот момент облачном провайдере.
Причины переезда в облако это удешевление и повышение скорости разработки, хороший уровень SLA, гибкость, точечное планирование бюджета и безопасность.
Почему именно Яндекс.Облако? Так как это достаточно молодой сервис у нас была и остаётся возможность влияния на его развитие путем формирования запросов на определенные фичи, индивидуальная тарифная сетка и содействие команды Яндекс.Облака так же играют не последнюю роль.
ky0
Очень интересную фразу вы оборонили про индивидуальные тарифы, потому что, по опыту, инфраструктуры таких масштабов, как АБ (я точно, разумеется, не знаю, но подозреваю, что она у вас достаточно крупная) в облаках обходятся существенно дороже, чем развёрнутые на своём железе.
Стоимость разработки, может, и уменьшилась — но обычно это с лихвой компенсируется увеличившимся счётом за обслуживание всего остального.
Ещё интересно, как переезд в облако поспособствовал точному планированию бюджета? Имхо, куда проще расчитывать расходы, располагаясь на собственном железе, чем в облаке, чья «гибкость», являющаяся преимуществом с одной стороны, с другой продуцирует как раз-таки меньшую предсказуемость затрат.
Разумеется, эти «индивидуальные тарифы» теоретически могут быть настолько привлекательны, что перевешивают всё, описанное выше :) Но применимы ли они к общему случаю — компании не столь крупной и известной, просто зашедшей в Я.О «с улицы»?
IsaninAV
зависит от времени амортизации , своя инфраструктура тоже амортизируется + кроме инфраструктуры есть ещё софт, многие облачный провайдеры забывают про софт , а soft does matter. Например, нужно S3 хранилище , а в компании его нет , где его взять ? да можно нанять свой саппорт купить железяк и сделать свой S3, но это потеря 1 год времени - > полгода всех убеждать , что нужен S3 , насчитать там какой-то большой бюджет года на три вперёд , потом "нанимаем людей и строим S3". Железки в ЯО норм , но основное это софт ,плюс каналы взаимодействия , например есть Amazon и он очевидно по функционалу богаче , но как и к кому тыкнуться в случае чего там , как построить ландшафт так , чтобы его там внезапно не заблокировали - гораздо большая проблема, поэтому ЯО
IsaninAV
можно было конечно, например, "замутить" небольшое своё S3 "опытно-промышленное", чтобы год не ждать , но тоже так всё везде сразу не сделаешь , поэтому облако добавляет возможностей . Сильно ресурсоёмкие вещи ( по ядрам процессоров) в облако пока не тащим , плюс есть различные механизмы оптимизации стоимости при работе с облачной инфраструктурой , поэтому расходы зависят больше от архитектуры продуктов в облаке и качества контроля за расходами
chemtech
Кстати, на счет "своё S3". Говорят, что Seaweedfs получше чем Minio на повышенной нагрузке.