Nikita Shirikov Ed blog

Containers

Автор: Булат @BleckPrime

Способы создания изолированного пространства в вашей ОС

Часто возникает необходимость создания изолированной файловой системы, ради безопасности или простого удобства, и у нас есть несколько способов это сделать.

Виртуализация

container_scheme

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

Контейнеризация

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

container_scheme2

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

Реализация контейнеризации

Грубый способ

Мы хотим сделать изолированные файловые системы для каждого контейнера, ну и у нас есть некая технология древних, которая называется ’chroot’

Мы имеем папку chroot, положим туда какой-то бинарник и файлы данных. После этого в терминале запустим процесс chroot, при котором он будет считать корнем файловой системы эту нашу папку.

sudo chroot chroot /bin_name

Важно отметить, что бинарник должен быть статически скомпонован, иначе ничего не получится, без подтягивания всех сборочных файлов. Так же запущенному в этой папке процессу будет не видна любая файловая система, кроме своей собственной. (Посмотреть дерево процессов можно командой pstree), однако остаётся возможность подложить ему ещё файлов.

Так, теперь мы смогли изолировать файловую систему, но не всё остальное, например мы мо- жем убить внешний процесс из нашей папки. Чтобы создать полностью изолированный контейнер, можно использовать пространство имён.

Docker

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

FROM scratch - какой использовать базовый образ для этого контейнера
COPY busybox /busybox - команды для создания файловой системы
ENTRYPOINT ["/busybox"] - какую команду мы будем выполнять, когда этот контейнер будет запускаться

Создаём контейнер minimal

docker build . -t minimal

Запускаем (it для терминала)

docker run -it minimal /busybox sh

Контейнер закроется, когда основной процесс завершится.

Хост сайта

Рассмотрим ситуацию интересней, у нас есть простенький сайт(index.html). Мы хотим положить в контейнер веб сервер и файлы, которые он будет раздавать пользователям. Пишем Dockerfile:

FROM cr.yandex/mirror/python:3.10-slim -берем чистый питон WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 80 - порт
CMD ["python", "-n", "http.server", "80"]

У нас есть команда, которая отображает все действующие контейнеры

docker ps

Чтобы зайти в контейнер:

docker exec -it name bash

#Os