Появилась цель предоставить пользователям изолированную среду для выполнения задач в сегменте локальной сети. Поднимать гипервизор для виртуализации машин и выделять каждому пользователю ВМ — это слишком расточительный подход, требующий определенных ресурсов. С увеличением числа виртуальных машин, разница в расходах ресурсов становится очевидной.

Контейнеризация — эффективный способ виртуализации на уровне ядра ОС. В системах контейнеризации гипервизора нет, но есть Container Engine, который создаёт контейнеры и управляет ими. В качестве движка контейнеризации мы будем использовать Podman.

Почему не Docker?

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

Большинство традиционных сетей контейнеров обрабатываются мостами bridge, преобразованием сетевых адресов (NAT) или путем привязки к сети хоста. Если вы хотите, чтобы ваши контейнеры выглядели как физические хосты в вашей сети и каждый с уникальным MAC-адресом, то самый простой способ — это использовать плагины macvlan и dhcp, которые поставляются с пакетом containernetworking-plugins.

Macvlan похож на коммутатор, который подключен к сетевому интерфейсу хоста. Используя виртуальные интерфейсы в сочетании с интерфейсом хоста, каждое устройство может иметь отдельный MAC-адрес. Этот факт позволяет существующим DHCP-серверам в существующей сети взаимодействовать с устройствами и назначать адреса.

Итак, приступим

Для начала установим движок контейнеризации Podman:

dnf install podman -y

Создание файла конфигурации CNI

Теперь необходимо создать новый файл конфигурации сетевого интерфейса контейнера (CNI). Перед созданием файла вы должны знать, какой интерфейс хоста будет использоваться для привязки. Эту информацию можно найти с помощью инструментов ip или ifconfig.

vi /etc/cni/net.d/90-infranet.conflist
{
    "cniVersion": "0.4.0",
    "name": "infranet",
    "plugins": [
        {
            "type": "macvlan",
            "master": "ens33",
            "ipam": {
                "type": "dhcp"
            }
        }
    ]
}

Запуск DHCP плагина

Плагин dhcp является прокси-клиентом DHCP для контейнера, поскольку в большинстве образов контейнеров отсутствует DHCP-клиент для взаимодействия с DHCP-сервером.

Чтобы запустить плагин dhcp, введите:

/usr/libexec/cni/dhcp daemon &

Собираем образ

Наш кастомный образ для пользователей будет на основе AlmaLinux версии 8.4, также назначим пароль суперпользователю “toor”, установим необходимые пакеты для работы с сетью и службу SSH для подключения пользователей:

cat Dockerfile
FROM almalinux:8.4
 
RUN echo 'root:toor' | chpasswd; dnf -y install bind-utils iproute net-tools nmap-ncat openssh-server; dnf clean all; systemctl enable sshd
 
CMD [ "/sbin/init" ]

Собираем кастомный образ:

podman build -t almalinux:custom .

Запускаем контейнер:

podman run -d --name test --network infranet almalinux:custom

Проверяем получение IP-адреса:

podman exec -it test ifconfig

Источники:

https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-interfaces-for-virtual-networking

https://www.redhat.com/sysadmin/leasing-ips-podman

https://habr.com/ru/company/redhatrussia/blog/468931/

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


  1. Sergey-S-Kovalev
    27.10.2021 10:31
    +1

    А как же ограничение ресурсов vCPU/vRAM? Иначе будет классическая проблема любых терминальных серверов: любой пользователь может сожрать все процессорные мощности, память или иопсы.


    1. isobby Автор
      27.10.2021 12:32
      +1

      Вы можете ограничить ресурсы контейнера, указав дополнительные опции при запуске. Например, ограничить выделяемую память можно опцией --memory. podman run -d --name test --network infranet --memory 128m almalinux:custom. А проверить установленный лимит можно командой: podman stats --no-stream test


      1. Sergey-S-Kovalev
        27.10.2021 15:08
        +1

        Я про то, что этот момент упущен в статье.


  1. dmitryvolochaev
    27.10.2021 11:21

    Кто гарантирует уникальность мак-адресов у контейнеров? Если за уникальностью приходится следить вручную, то чем это лучше, чем вручную прописывать айпишники?


    1. isobby Автор
      27.10.2021 12:54
      +1

      При каждом запуске контейнера ему присваивается новый мак-адрес. Начиная с версии 1.7 появилась возможность указать статичный мак-адрес.


  1. osipov_dv
    27.10.2021 14:44
    +4

    мне кажется, применение термина виртуализация, к контейнерам ошибочно... Там ничего не виртуализируется.


  1. Ion_Storm
    28.10.2021 09:57
    +4

    Подскажите, а чем для вашей задачи не подошел systemd-container?