Redundancy (Избыточность в ИТ-инфраструктуре)

⌘K

Redundancy (Избыточность в ИТ-инфраструктуре)

Redundancy, или избыточность, — это принцип проектирования IT-инфраструктуры, при котором ключевые компоненты системы дублируются для обеспечения её непрерывной работы в случае сбоев или отказов. Цель избыточности — исключить единичные точки отказа и повысить устойчивость всей архитектуры.

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

Один из наиболее показательных кейсов — сетевой redundancy, особенно в контексте ISP redundancy, когда организация подключена к интернету сразу через нескольких независимых провайдеров. Это позволяет сохранить доступность внешних сервисов даже при полном выходе из строя одной линии связи.

В облачных системах применяется cloud redundancy — дублирование виртуальных машин, баз данных и сервисов в рамках одного региона или между разными зонами доступности. Это минимизирует риск потери данных и обеспечивает быстрое восстановление при сбоях.

Redundancy тесно связана с концепцией High Availability (HA) и служит её технической основой. Без дублирования систем невозможно гарантировать стабильный SLA и восстановление после инцидентов в пределах допустимого времени.

На уровне архитектуры redundancy может включать:

  • отказоустойчивые кластеры,
  • репликацию данных,
  • автоматический failover и балансировку нагрузки,
  • активные и пассивные резервные компоненты,
  • геораспределённые среды.

Современные инфраструктуры, особенно в критически важных секторах (финансы, телеком, медицина, государственные ИТ-системы), изначально проектируются с учётом избыточности. Это уже не дополнительная функция, а базовый стандарт надёжной, предсказуемой и управляемой IT-среды.


Типы избыточности

1. Active-Active
Оба (или все) компонента работают одновременно и обрабатывают нагрузку. При выходе одного из них система продолжает работу на оставшихся.
Пример: два балансировщика, каждый обслуживает часть трафика.

2. Active-Passive
Один компонент активен, второй находится в режиме ожидания. При сбое активного — пассивный автоматически подхватывает работу (failover).
Пример: основная база данных + реплика, готовая к переключению.

3. N+1 / N+N

  • N+1 — система работает на N элементах, плюс один в резерве.
  • N+N — все элементы дублируются, нагрузка полностью может быть перераспределена.

Примеры реализации

В облаках:

  • AWS:
    • Multi-AZ размещение для RDS (автоматический failover между зонами доступности);
    • Elastic Load Balancer с несколькими EC2-инстансами в разных зонах.
  • Azure:
    • Availability Sets и Availability Zones для защиты от отказов на уровне оборудования и ЦОД;
    • Geo-redundant storage (GRS) — автоматическая репликация данных между регионами.
  • Google Cloud:
    • Global Load Balancer с бэкендами в нескольких регионах;
    • Cloud SQL high availability с репликацией и автоматическим перезапуском.

В Kubernetes:

  • ReplicaSets обеспечивают избыточность подов;
  • PodDisruptionBudgets (PDB) гарантируют, что минимальное число подов останется доступным при обновлении;
  • Node pools в разных зонах — защита от сбоя одного дата-центра;
  • HA control plane — отказоустойчивый управляющий уровень (например, в managed EKS/GKE).

Реальные примеры:

  1. Terraform-модуль с избыточной инфраструктурой (AWS, EC2 в двух зонах)
  2. YAML-манифест ReplicaSet в Kubernetes
  3. Схема failover через DNS + Anycast

1. Terraform: EC2 в двух зонах (N+1 избыточность)

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "web" {
  count         = 2
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  availability_zone = element(["us-east-1a", "us-east-1b"], count.index)

  tags = {
    Name = "web-${count.index}"
  }
}

📌 Этот код запускает два инстанса в разных зонах AWS. Даже если одна зона выйдет из строя, второй инстанс останется доступным.


2. ReplicaSet в Kubernetes (избыточность подов)

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: web-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80

📌 Здесь Kubernetes гарантирует, что в любой момент времени будет работать 3 пода. Если один падает — создаётся новый автоматически.


3. DNS + Anycast (логика failover по географии)

Anycast — это способ назначения одного IP-адреса сразу нескольким узлам в разных географических точках. DNS-сервер или маршрутизатор направляет пользователя к ближайшему или работающему инстансу.

Сценарий:

  • Один сервис с IP 203.0.113.1 объявлен в Европе, Азии и США;
  • Пользователь из Франции получает ответ с ближайшего европейского PoP;
  • При отказе узла в Европе трафик перенаправляется в США автоматически — без изменения DNS-записей.

📌 Используется в CDN, глобальных DNS, маршрутизации отказоустойчивых API (например, Cloudflare, Google Public DNS).


Вот ещё одно расширение — полный шаблон избыточной архитектуры с Terraform и Helm, включающий:

  • EC2-инстансы в разных зонах (Terraform)
  • Kubernetes-кластер с ReplicaSet и PodDisruptionBudget (Helm/YAML)
  • DNS failover с AWS Route 53 (Terraform)

1. Terraform: EC2-инстансы с балансировкой и health check

resource "aws_lb" "web_alb" {
  name               = "web-load-balancer"
  internal           = false
  load_balancer_type = "application"
  subnets            = [aws_subnet.public_a.id, aws_subnet.public_b.id]
}

resource "aws_lb_target_group" "web_tg" {
  name     = "web-targets"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id

  health_check {
    path                = "/"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 2
    unhealthy_threshold = 2
  }
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.web_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web_tg.arn
  }
}

resource "aws_lb_target_group_attachment" "web_instances" {
  count            = 2
  target_group_arn = aws_lb_target_group.web_tg.arn
  target_id        = aws_instance.web[count.index].id
  port             = 80
}

2. Helm / Kubernetes: ReplicaSet + PodDisruptionBudget

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

📌 PDB гарантирует, что как минимум 2 пода будут живы даже при плановом обновлении или удалении узлов.


3. Terraform: Route 53 DNS Failover

resource "aws_route53_health_check" "web" {
  fqdn              = "web.example.com"
  port              = 80
  type              = "HTTP"
  resource_path     = "/"
  failure_threshold = 3
  request_interval  = 30
}

resource "aws_route53_record" "web_failover_primary" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "web.example.com"
  type    = "A"
  ttl     = 60

  set_identifier = "primary"
  failover       = "PRIMARY"
  health_check_id = aws_route53_health_check.web.id
  records        = [aws_instance.web[0].public_ip]
}

resource "aws_route53_record" "web_failover_secondary" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "web.example.com"
  type    = "A"
  ttl     = 60

  set_identifier = "secondary"
  failover       = "SECONDARY"
  records        = [aws_instance.web[1].public_ip]
}

📌 Если основной инстанс не проходит health check — DNS автоматически направляет трафик на вторичный.


И финальный элемент — GitOps-доставка избыточной инфраструктуры через Argo CD, где:

  • инфраструктура описана кодом (Terraform, Helm),
  • доставка в Kubernetes автоматизирована,
  • компоненты разворачиваются с высокой доступностью.

📂 Структура Git-репозитория (mono-repo вариант)

infrastructure/
├── terraform/
│   ├── main.tf
│   ├── variables.tf
│   └── route53_failover.tf
└── k8s/
    ├── base/
    │   ├── helm-release.yaml       # HelmRelease или Application
    │   ├── pdb.yaml
    │   └── replicas.yaml
    └── overlays/
        ├── staging/
        └── production/

📄 Пример Argo CD Application (GitOps HA деплой)

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-ha
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/infrastructure
    targetRevision: main
    path: k8s/base
    helm:
      values: |
        replicaCount: 3
        pdb:
          enabled: true
          minAvailable: 2
  destination:
    server: https://kubernetes.default.svc
    namespace: web
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Что это делает:

  • Разворачивает Helm-чарт с replicaCount: 3;
  • Включает PodDisruptionBudget с minAvailable: 2;
  • Гарантирует, что при обновлениях или сбоях сервис не прерывается;
  • Использует Argo CD как GitOps-контроллер: любое изменение в values.yaml автоматически применится в кластере;
  • Поддерживает self-healing: Argo CD откатывает ручные изменения, если они расходятся с Git.

Добавочно: CI/CD-пайплайн для GitOps

  • Изменения в k8s/base/ или terraform/ идут через Pull Request;
  • CI запускает terraform plan + линтер Helm чарта (helm lint);
  • После ревью и merge Argo CD автоматически подхватывает изменения;
  • Стейт Terraform хранится удалённо (например, S3 с DynamoDB lock).