Runtime
External Link:
В 2007 году Google сделали проект Let Me Contain That For You (LMCTFY), в 2008 году появился Linux Containers (LXC). Для управления LXC в 2013 году появился инструмент Docker. Далее в 2015, команда Docker разработали проект libcontainer на языке Go. Также, в 2015 вышел Kubernetes 1.0. В 2015 собрали Open Container Initiative (OCI), которые стали разрабатывать стандарты на метаданные (манифесты-спецификации), образы контейнеров, методы управления ими. В том числе, в рамках OCI создали инструмент запуска и работы с контейнерами runc.
runc
В спецификации от runc можно увидеть всё необходимое для создания и запуска контейнера: environment variables, user + group IDs, mount points, Linux namespaces. Не хватает только файловой системы (rootfs), базового образа контейнера:
В распакованном образе можно найти готовую Runtime Specification:
В ней можно увидеть обычные поля из runc, а доп заполненные annotations:
Чтобы создать контейнер с runc, нужно его зацепить на терминал ввода команд TTY:
На существующий TTY зацепить контейнер нельзя (потому что окно удалённого xTerm не поддерживает такое), нужно создать новый виртуальный TTY и указать его сокет. Для этого надо установить Golang, скачать приложение rectty, создать с его помощью виртуальный терминал, после чего В ДРУГОМ ОКНЕ терминала создать контейнер и зацепить его на создвнный TTY:
В ДРУГОМ ОКНЕ терминала создать контейнер и зацепить его на создвнный TTY:
runc init создаёт новую среду со всеми namespaces. /bin/bash ещё не запущен в контейнере, но уже можно запускать в нём свои процессы, полезно чтоб настроить сеть:
Для запуска контейнера выполним:
Исходный runc init пропал, теперь только /bin/bash существует в контейнере. На ПЕРВОМ ОКНЕ терминала появилась консоль контейнера:
Можно проверить управление: заморозим контейнер. Во ВТОРОМ ОКНЕ терминала выполним:
Для остановки контейнера достаточно выйти из rectty-сессии, после чего удалить контейнер. Остановленный контейнер нельзя перезапустить, можно лишь пересоздать в новом состоянии:
Можно модифицировать спецификацию в контейнере (bundle/config.json):
Можно удалить разделение PID namespace процессов в контейнере с хостом:
- runc очень низкоуровневый и позволяет серьёзно нарушить работу и безопасность контейнеров.
- Поэтому сделаны надстройки обеспечения ИБ уровня ОС: seccomp, SELinux и AppArmor
- Однако, их намного удобнее использовать на уровне управления выше
- Для защиты также можно запускать контейнеры в режиме rootless из runc
- С помощью runc нужно руками настраивать сетевые интерфейсы, очень трудоемко
CRI-O
Инструмент CRI-O разработан в 2016 при участии OCI в рамках проекта Kubernetes. Философия UNIX, максимально лёгкий аналог Docker/containerd. Он НЕ предназначен как инструмент для приёма команд от разработчиков. Задача - принимать команды от K8s. Внутри себя CRI-O использует runc как backend, и принимает команды по gRPC API как frontend.
Попробуем CRI-O с помощью спец-контейнера с crictl:
Внутри лежит файл sandbox.yml:
Из него можно создать Pod:
