Блог

План стъпка по стъпка за мултитенантна изолация в Docker

Изолирайте мултитенантните работни натоварвания в Docker, като същевременно контролирате разходите за хостинг. Научете как да конфигурирате namespaces, cgroups, мрежови политики и подсилване на средата за изпълнение.

Обобщение

Управлението на споделена инфраструктура за множество клиентски кампании или вътрешни уеб ресурси често води до разногласия с ръководството относно разходите за хостинг и сигурността на данните. Контейнерите на Docker предоставят олекотена алтернатива на специално заделените виртуални машини, но стандартните настройки оставят сериозни пропуски в изолацията. Истинската мултитенантност (multi-tenancy) изисква добре обмислени граници на ниво ядро, процеси, мрежа и съхранение на данни. Това ръководство предлага практическа рамка от пет стъпки за защита на мултитенантни Docker внедрявания чрез използване на базовите механизми за изолация в Linux. Ще научите как да налагате квоти за ресурси, да ограничавате привилегиите на процесите, да сегментирате мрежите на контейнерите и да избирате правилното ниво на изолация. Следвайки този план, ще можете да защитите клиентските среди и да обосновете инфраструктурния бюджет пред нетехнически лица.

Вашият нетехнически мениджър влиза в офиса ви с разпечатка от фактурата за облачен хостинг за миналия месец. Разходите са нараснали, а няколко целеви страници (landing pages) с висок приоритет са отбелязали скок в латентността по време на паралелно стартиране на продукт. От вас се иска да обясните защо маркетинговите ресурси споделят едни и същи сървъри, дали клиентските данни са изложени на риск и защо екипът не може да пусне скъпа отделна виртуална машина за всяка отделна кампания.

Предоставянето на собствена виртуална машина (VM) за всеки дигитален ресурс елиминира проблема с т.нар. „шумни съседи“ (noisy neighbors), но бързо изчерпва оперативния ви бюджет. Стандартните Docker внедрявания решават проблема с разходите, като изпълняват множество сайтове върху едно ядро на операционната система, но конфигурациите по подразбиране оставят опасни пропуски в сигурността. Ако приложението на един клиент се сблъска с неконтролиран скрипт или пробив в сигурността, всяко друго съвместно хоствано приложение на този сървър е изложено на риск.

Използвайте този подробен технически план, за да конфигурирате стриктна мултитенантна изолация в Docker. Приложете тези пет оперативни стъпки, за да защитите стабилността на системата, да изолирате данните на наемателите и да превърнете техническите инфраструктурни решения в ясна бизнес стойност за ръководството.


1. Налагане на твърди квоти за ресурси чрез Control Groups (cgroups)

Задайте незабавно ясни лимити за процесор (CPU), памет и дисков I/O на всеки контейнер. Когато множество наематели споделят един базов хост, неограничените контейнери се конкурират за системни ресурси. Една неконтролирана заявка към база данни или кампания с голям трафик може да изчерпи цялата налична памет на хоста, задействайки механизма на Linux Out-Of-Memory (OOM) killer, който прекратява системни процеси на произволен принцип.

Контролните групи в Linux (cgroups) определят какъв изчислителен капацитет може да използва даден контейнер. Приложете тези ограничения директно в дефинициите си за внедряване:

services:
  tenant_app:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
  • Лимити за памет (limits.memory): Задава твърд таван. Ако контейнерът надхвърли 512 мегабайта, ядрото прекратява процесите вътре в този контейнер, без да нарушава работата на съседните наематели.
  • Резервирана памет (reservations.memory): Гарантира минимално заделена памет, така че приложенията с нисък трафик да останат бързи и отзивчиви.
  • Лимити за процесор (limits.cpus): Ограничава контейнера до определена максимална част от наличните процесорни ядра, предотвратявайки монополизирането на CPU ресурси от един наемател.

Когато обосновавате тази архитектура пред нетехнически ръководители, обяснете cgroups като автоматизирани дигитални електромери. Точно както наемателите в офис сграда плащат за собственото си потребление на електроенергия, вместо да претоварват главния предпазител, cgroups гарантират, че целева страница с висок трафик никога няма да срине портала за генериране на лийдове на друг клиент. За по-задълбочен поглед върху архитектурните компромиси разгледайте нашето ръководство за проектирането на мултитенантна архитектура.


2. Сегментиране на процесите на наемателите чрез Namespaces и потребители без Root права

Никога не стартирайте процесите в контейнера с потребителя по подразбиране root. В стандартните Linux контейнерни среди потребителят root в контейнера съответства на root на хост ядрото, освен ако не е изрично пренасочен (remapped). Ако нападател компрометира уеб приложение, работещо като root, той получава повишени права върху целия споделен хост.

Наложете изолация на процесите чрез потребителски пространства от имена (user namespaces) и изрично изпълнение без root права:

  1. Дефиниране на потребители без привилегии за средата на изпълнение: Създайте специални системни потребители с минимални права във вашите Dockerfile файлове.
    FROM php:8.2-fpm-alpine
    RUN addgroup -g 10001 tenantgroup && \n       adduser -u 10001 -D -G tenantgroup tenantuser
    USER tenantuser
    
  2. Активиране на потребителски пространства от имена (userns-remap): Конфигурирайте Docker демона (/etc/docker/daemon.json), за да пренасочи потребителските ID-та (UID) на контейнерите към диапазон без привилегии на хоста.
    {
      "userns-remap": "default"
    }
    

Linux пространствата от имена (namespaces) разделят видимостта на системата. Пространството от имена за Process ID (PID) гарантира, че Наемател A не може да вижда, изпраща сигнали или спира процеси, принадлежащи на Наемател B. Пространството Mount (MNT) предоставя на всеки наемател изолиран изглед на файловата система, докато IPC пространствата блокират неоторизирана комуникация между процесите.

Пренасочването на потребителските пространства от имена неутрализира векторите за бягство от контейнера (container escape): процес, който счита, че е root (UID 0) в своя контейнер, се картографира към непривилегирован ID (като UID 165536) на хост машината. Ако даден експлойт преодолее бариерите на контейнера, нападателят попада в непривилегирована обвивка (shell), неспособна да променя хост конфигурациите или да достъпва директориите на съседните наематели.


3. Премахване на системни права на ядрото и налагане на файлови системи само за четене

Ограничете наличните Linux възможности (capabilities) и направете кореновата файлова система на контейнера неизменяема при стартиране. По подразбиране средата за изпълнение на контейнери предоставя около дузина възможности на Linux ядрото, много от които уеб приложенията никога не използват. Излишните възможности предоставят на нападателите инструменти за манипулиране на мрежовото маршрутизиране, промяна на системния часовник на хоста или заобикаляне на контрола за достъп до файлове.

Защитете работещите контейнери, като премахнете всички възможности по подразбиране и добавите обратно само най-необходимите оперативни флагове:

services:
  tenant_web:
    image: custom-nginx:latest
    read_only: true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
      - seccomp=default.json
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=64m
      - /var/run:rw,noexec,nosuid,size=16m
  • cap_drop: - ALL: Премахва всяка възможност на ядрото от процеса в контейнера.
  • cap_add: - NET_BIND_SERVICE: Изрично разрешава свързването с привилегировани портове (като 80 и 443), като същевременно блокира директната манипулация на мрежови сокети.
  • read_only: true: Монтира цялата коренова файлова система на контейнера в режим само за четене (read-only). Нападателите не могат да изтеглят злонамерени изпълними файлове, да променят PHP скриптове или да редактират конфигурационни файлове на уеб сървъра.
  • tmpfs: Заделя временни директории в оперативната памет за необходимите работни файлове (като /tmp), като същевременно блокира изпълнението на двоични файлове (noexec) и ескалацията на привилегии (nosuid).

Приложете seccomp филтри (secure computing mode) и модули за сигурност като AppArmor или SELinux, за да прихващате и ограничавате системните извиквания към споделеното ядро на хоста. Ако екипът ви управлява персонализирани компилации на уеб приложения, следвайте нашите структурирани стъпки за подсилване на сигурността на Docker контейнери във вашите пайплайни за внедряване.


4. Разделяне на мрежите между клиентските среди

Деактивирайте стандартната bridge мрежа и създайте персонализирани, изолирани софтуерно дефинирани bridge мрежи за всеки отделен клиентски стек. По подразбиране контейнерите в стандартната bridge мрежа на Docker могат да се откриват и комуникират помежду си чрез вътрешни IP адреси. Уязвимост в маркетинговия микросървис на един наемател позволява странично движение (lateral movement) към всяка друга вътрешна база данни и приложение на този хост.

Изолирайте трафика на наемателите напълно, като дефинирате независими мрежови мостове за всеки от тях:

networks:
  tenant_alpha_net:
    driver: bridge
    internal: true
  tenant_beta_net:
    driver: bridge
    internal: true
  public_gateway_net:
    driver: bridge

services:
  alpha_app:
    image: tenant_a_app:latest
    networks:
      - tenant_alpha_net
      - public_gateway_net

  alpha_db:
    image: mariadb:10.11
    networks:
      - tenant_alpha_net

  beta_app:
    image: tenant_b_app:latest
    networks:
      - tenant_beta_net
      - public_gateway_net

  beta_db:
    image: mariadb:10.11
    networks:
      - tenant_beta_net
  • Изолация на наемателите: alpha_app и alpha_db комуникират ексклузивно през tenant_alpha_net. beta_app няма достъп до alpha_db, дори ако нападател сканира вътрешната подмрежа.
  • Флаг за вътрешна мрежа (internal: true): Предотвратява директното маршрутизиране на трафик от мрежите на базите данни към външния интернет, ограничавайки входящия и изходящия достъп единствено до контейнерите на приложението.
  • Reverse Proxy Gateway: Само входният прокси сървър се свързва с public_gateway_net, за да пренасочва входящите HTTP/HTTPS заявки към съответния контейнер на наемателя въз основа на името на хоста.

За по-високи изисквания за сигурност разгледайте режимите на Docker за разширена изолация (Enhanced Container Isolation - ECI) или среди за изпълнение като Sysbox, които автоматично налагат по-строги граници на потребителските пространства от имена и виртуализирани файлови системи /proc и /sys без сложни ръчни мрежови настройки.


5. Изграждане на обективна матрица за вземане на решения за мултитенантност

Опровергайте предположението, че всички дигитални ресурси изискват отделни виртуални машини. Маркетинговите лидери често смятат, че изолацията на ниво хардуерна виртуална машина е единственият сигурен модел. На практика осигуряването на специални виртуални машини за леки целеви страници или краткотрайни кампанийни сайтове води до огромно раздуване на разходите и оперативна поддръжка, без реално да подобрява сигурността на уеб приложението.

Използвайте следната сравнителна матрица, за да оцените изискванията на работните натоварвания и да представите рационална стратегия за внедряване пред лицата, вземащи решения:

Ниво на изолацияБазова технологияГраница на сигурностРазход на ресурси (Overhead)Най-подходящ случай на употреба
Споделен стек от контейнериNamespaces & Cgroups върху една ОСЛогическа изолация на ниво ОСМного нисъкЦелеви страници с голям трафик, вътрешни staging среди, временни сайтове за кампании
Подсилени контейнери (ECI / Sysbox)User namespaces, AppArmor, Read-Only rootРазширено ниво на ОС и виртуализацияНисъкАгенционен хостинг за множество клиенти, портали с автентикация, чувствителни маркетингови форми
Специализирани виртуални машини (VMs)Хардуерна виртуализация чрез HypervisorСтрого разделяне на ниво хардуер/ядроВисокОбработка на плащания, регулаторни данни по HIPAA/PCI, изпълнение на ненадежден потребителски код
Хибриден модел (Контейнери в отделни VM)Подсилени контейнери в рамките на специфични за наемателя VMМногослойни хардуерни граници и граници на ОСУмерен до високГолеми корпоративни клиенти с изисквания за стриктно спазване на договори

Оценявайте всеки проект спрямо строги критерии, преди да разпределяте бюджет за инфраструктура:

  1. Чувствителност на данните: Съхранява ли проектът регулаторни данни (напр. данни за кредитни карти или медицинска информация)? Ако да, внедрете го на отделна виртуална машина.
  2. Произход на кода: Внедрявате ли стандартизиран, одитиран от екипа код или допускате непроверени плъгини на трети страни? Стандартният код е подходящ за подсилени контейнери; нетестваният код от трети страни изисква изолация на ниво хипервайзър.
  3. Бюджет и жизнен цикъл: За сезонни целеви страници и основни фирмени уебсайтове мултитенантността с подсилени контейнери осигурява максимална производителност спрямо направените разходи.

Когато представяте инфраструктурни планове пред ръководството, направете справка с нашето ръководство за оценяването кога клиентите се нуждаят от отделни виртуални машини, за да подкрепите препоръките си с ясни, базирани на нива аргументи.


Заключение: Превръщане на мерките за сигурност в бизнес възвръщаемост (ROI)

Защитата на мултитенантна Docker среда не изисква гигантски бюджет за корпоративна облачна архитектура. Тя изисква стриктно и дисциплинирано прилагане на контролните механизми на операционната система.

Когато обсъждате инфраструктурата с нетехническото ръководство, представете тези технически конфигурации през призмата на три основни бизнес метрики:

  • Ефективност на разходите: Мултитенантните контейнери позволяват на екипа да хоства десетки маркетингови сайтове с малка част от изчислителните ресурси, изисквани от индивидуалните виртуални машини.
  • Гарантирано време на непрекъсната работа (Uptime): Контролните групи гарантират, че скоковете в трафика на сезонна кампания няма да влошат производителността на основните бранд уебсайтове.
  • Ограничаване на радиуса на поражение (Blast Radius): Файловите системи само за четене, премахнатите възможности и изолираните мрежови мостове гарантират, че пробив в един сайт не може да засегне съседни клиентски бази данни или системния контрол на хоста.

Внедрете тези защитни механизми систематично във вашите шаблони за контейнери. Така ще осигурите високопроизводителна и рентабилна инфраструктура, която отговаря както на инженерните стандарти за сигурност, така и на бюджетните изисквания на ръководството.

Sources (5)