Изначальная структура сети и почему мы решили от неё отказаться.

Так получилось, что АО «АльфаСтрахование» был одним из первых клиентов, которые начали использовать облачную платформу Яндекс.Облако. Множество фич и функционала, которые сейчас присутствуют в платформе тогда отсутствовали, а перед нами стояла задача организовать крупную сеть с множеством изолированных сегментов.

Поскольку в облаке, в тот момент времени, отсутствовал необходимый функционал, мы решили построить архитектуру с использованием 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 позволило отказаться от использования Таблиц Маршрутизации для сабнетов. Самым большим плюсом стала возможность отделить права доступа на использование сетей и Групп безопасности от остальных фолдеров. Основным недостатком данной схемы являются недокументированные проблемы с нехваткой прав доступа.

Новая структура сети
Новая структура сети

Для перехода на новую сетевую маршрутизацию была проделана огромная совместная работа подразделений Информационной безопасности и Разработки.

В итоге, Коллеги из разработки были обеспечены надежным каналом связи, а мы контролем сетевых подключений как внутри Яндекс.Облака на конечных точках управления, так и в разрезе Облако-Инфраструктура компании.

Список источников:

Общие концепции Групп Безопасности

Группы Безопасности для k8s

Яндекс Interconnect

 

Комментарии (8)


  1. achekalin
    18.09.2021 09:37
    +2

    Хочется узнать, с вашего позволения: каковы причины переезда в облако (любое), в котором отсутствуют на момент переезда многие важные фичи. К тому моменту «стабильных» облаков базе той же вмвари было достаточно много, что заставило компанию масштаба Альфы становиться первопроходцем и испытателем preview решений и строить костыли на своей стороне, чтобы получить отсутствующие еще в оьлаке функции?

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

    В общем, если бы вы дописали абзац-другой о том, почему ушли в облако, и почему ушли именно в это облако, статья бы выиграла!


    1. innomaker Автор
      18.09.2021 10:34
      +3

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

      Причины переезда в облако это удешевление и повышение скорости разработки, хороший уровень SLA, гибкость, точечное планирование бюджета и безопасность.

      Почему именно Яндекс.Облако? Так как это достаточно молодой сервис у нас была и остаётся возможность влияния на его развитие путем формирования запросов на определенные фичи, индивидуальная тарифная сетка и содействие команды Яндекс.Облака так же играют не последнюю роль.


      1. ky0
        18.09.2021 11:17
        +1

        Очень интересную фразу вы оборонили про индивидуальные тарифы, потому что, по опыту, инфраструктуры таких масштабов, как АБ (я точно, разумеется, не знаю, но подозреваю, что она у вас достаточно крупная) в облаках обходятся существенно дороже, чем развёрнутые на своём железе.

        Стоимость разработки, может, и уменьшилась — но обычно это с лихвой компенсируется увеличившимся счётом за обслуживание всего остального.

        Ещё интересно, как переезд в облако поспособствовал точному планированию бюджета? Имхо, куда проще расчитывать расходы, располагаясь на собственном железе, чем в облаке, чья «гибкость», являющаяся преимуществом с одной стороны, с другой продуцирует как раз-таки меньшую предсказуемость затрат.

        Разумеется, эти «индивидуальные тарифы» теоретически могут быть настолько привлекательны, что перевешивают всё, описанное выше :) Но применимы ли они к общему случаю — компании не столь крупной и известной, просто зашедшей в Я.О «с улицы»?


        1. IsaninAV
          18.09.2021 13:48

          зависит от времени амортизации , своя инфраструктура тоже амортизируется + кроме инфраструктуры есть ещё софт, многие облачный провайдеры забывают про софт , а soft does matter. Например, нужно S3 хранилище , а в компании его нет , где его взять ? да можно нанять свой саппорт купить железяк и сделать свой S3, но это потеря 1 год времени - > полгода всех убеждать , что нужен S3 , насчитать там какой-то большой бюджет года на три вперёд , потом "нанимаем людей и строим S3". Железки в ЯО норм , но основное это софт ,плюс каналы взаимодействия , например есть Amazon и он очевидно по функционалу богаче , но как и к кому тыкнуться в случае чего там , как построить ландшафт так , чтобы его там внезапно не заблокировали - гораздо большая проблема, поэтому ЯО


          1. IsaninAV
            18.09.2021 14:09

            можно было конечно, например, "замутить" небольшое своё S3 "опытно-промышленное", чтобы год не ждать , но тоже так всё везде сразу не сделаешь , поэтому облако добавляет возможностей . Сильно ресурсоёмкие вещи ( по ядрам процессоров) в облако пока не тащим , плюс есть различные механизмы оптимизации стоимости при работе с облачной инфраструктурой , поэтому расходы зависят больше от архитектуры продуктов в облаке и качества контроля за расходами


            1. chemtech
              18.09.2021 18:59

              Кстати, на счет "своё S3". Говорят, что Seaweedfs получше чем Minio на повышенной нагрузке.


  1. chemtech
    18.09.2021 14:28
    +2

    Спасибо за интересный пост.

    имеющиеся в работе кластеры были deprecated-версий (снятых с поддержки в Яндекс.Облаке).

    Какие именно версии Kubernetes у вас были? Какие главные причины не обновления Kubernetes? Спасибо.


    1. innomaker Автор
      18.09.2021 16:17

      Версия 1.15. Там находился специфический софт, при обновлении кластера необходимо было обновить и его, это и было временным стоппером.