Сделайте первые шаги с containerd и запустите образы докеров как обычно

В декабре 2020 года проект Kubernetes устарел докер. В рамках этой лекции мы впервые познакомимся с dockerhistory, чтобы понять причины такого устаревания. Это приведет нас к открытию containerd и выяснению его преимуществ.

Мы попрактикуемся containerd, установив его на Raspberry Pi. Эта целевая платформа - хороший сценарий для изучения различных компонентов, необходимых для использования containerd. Доступных двоичных файлов нет, поэтому мы будем собирать их из исходников. После установки мы увидим, как с ним взаимодействовать с помощью ctrcommand и что там можно сделать.

История программного обеспечения Docker

Программное обеспечение Docker было создано в 2013 году и способствовало тому, что контейнеризация стала известной и доступной. Однако люди часто путают docker и контейнеризацию.

Docker ≠ контейнеры

Контейнеризация в Linux была возможна с помощью этих двух функций ядра Linux:

  • Пространство имен ядра Linux определяет границы осведомленности процесса о том, что еще происходит вокруг него.
  • Группы управления (cgroups) - это функция ядра, которая управляет и изолирует ресурсы (ЦП, память), на которые влияет процесс.

Контейнеры Linux (LXC) были выпущены в 2008 году и основаны на обеих предыдущих функциях ядра. Он предоставляет API для простого создания систем контейнерных приложений и управления ими.

Вначале docker использовала стек LXC для изоляции ресурсов приложения. dockerprowess заключалась в создании стандартного программного модуля, в котором пользователь может определять изображения и легко запускать их в контейнерах.

Эволюция архитектуры программного обеспечения

Основанный на LXC, docker действительно зависел от его развития. Чтобы исправить это, docker начал внедрять libcontainers для запуска контейнеров без LXC.

Параллельно в то время было много критики в адрес монолитной архитектуры docker, содержащей CLI и демон. Приняв во внимание эти отзывы docker начал вырезать демон и CLI в docker.

В 2015 году была основана Open Container Initiative (OCI) для создания стандарта контейнеров приложений. Компания Docker была ключевым игроком в ее определении. В результате этой инициативы возникли два стандарта, которые составляют модель OCI:

  • runtime-spec, определяющий, как запускать контейнер:


  • image-spec, определяющий создание изображения:


Компания Docker пожертвовала libcontainers в OCI. Теперь он является частью проекта runc, который является средой выполнения OCI. В настоящее время docker больше не монолитный блок, которым был когда-то. Он использует containerd и runc для управления запуском контейнеров:

Containerd

containerd родился из docker и был включен в выпуск 1.11:



Это среда выполнения, реализующая интерфейс времени выполнения контейнера (CRI) и представляющая интересные ресурсы для размещенных систем:

Containerd - это стандартная среда выполнения контейнеров с упором на простоту, надежность и переносимость. Он доступен как демон для Linux и Windows, который может управлять полным жизненным циклом контейнера своей хост-системы: передача и хранение образов, выполнение и контроль контейнера, низкоуровневое хранилище и сетевые вложения и т. Д. Из https://github.com/containerd/containerd

Докер и Кубернетес

До выпуска 1.20 kubernetes использовал docker для связи с контейнерами. docker сама вызывает containerd для управления контейнерами:

Начиная с v1.20 kubernetes устарел docker в пользу сред выполнения с использованием интерфейса времени выполнения контейнера (CRI), например containerdи cri-o. Вы получите предупреждения, если по-прежнему будете использовать docker в этом выпуске. Изменение вступит в силу в версии 1.22. Предыдущая диаграмма теперь выглядит так:

Несмотря на это kuberneteschange, вы можете продолжать использовать Docker в своем CI / CD или в целях разработки. docker предоставляет множество удобных функций, облегчающих взаимодействие. Тем не менее, оркестратору контейнеров, подобному kubernetes, нужна только среда выполнения контейнера для управления контейнерами. Работа с дополнительным слоем может усложнить работу, но не принесет больше пользы.

Containerd на Raspberry Pi

Установка

Я использую Raspberry Pi с архитектурой процессора armv6l и ОС Raspbian. Вы должны проверить архитектуру вашего процессора с помощью uname и адаптировать исходный код к вашей архитектуре.

Мы обеспечиваем актуальность системы:

$ sudo apt update
$ sudo apt full-upgrade
$ sudo rpi-update

Нам понадобятся некоторые инструменты сборки для компиляции исходников:

$ sudo apt install autoconf automake libtool curl unzip gcc make

Нам также нужна последняя golang версия:

$ wget https://golang.org/dl/go1.15.8.linux-armv6l.tar.gz
$ sudo tar -C /usr/local -xzf go1.15.8.linux-armv6l.tar.gz
$ echo 'PATH="$PATH:/usr/local/go/bin"' | tee -a $HOME/.profile
$ echo "export GOPATH=$(go env GOPATH)" | tee -a $HOME/.profile
$ source $HOME/.profile
$ go version
# version should be 1.15.8

Установите libseccomp пакеты для поддержки seccomp:

$ sudo apt install libseccomp2 libseccomp-dev

Установите runc:

$ go get -v github.com/opencontainers/runc
$ cd $GOPATH/src/github.com/opencontainers/runc
$ make -j`nproc`
$ sudo env PATH="$PATH" make install

Нам нужно btrfsпакетов для подготовки protobufустановки:

sudo apt install btrfs-progs libbtrfs-dev

Скачиваем protobufsources и строим их:

$ wget https://github.com/protocolbuffers/protobuf/archive/v3.14.0.tar.gz -O protobuf_v3.14.0.tar.gz
$ tar xzf protobuf_v3.14.0.tar.gz
$ cd protobuf-3.14.0/
$ ./autogen.sh
$ ./configure
$ make -j`nproc`
$ make -l2 -j`nproc` check
$ sudo make install

Скачиваем containerdsources и строим их:

$ go get -v github.com/containerd/containerd
$ cd $GOPATH/src/github.com/containerd/containerd
$ make -j`nproc`
$ sudo env PATH="$PATH" make install

Сборка containerd завершена, мы можем проверить двоичный файл:

$ containerd --version
containerd github.com/containerd/containerd v1.5.0-beta.1 cfa842c278694860a7e32917066f4a24978f80d0

Мы развертываем предоставленный файл systemdservice для запуска containerd в качестве демона:

cd $GOPATH/src/github.com/containerd/containerd
sudo cp containerd.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable containerd.service
sudo systemctl start containerd.service

Взаимодействовать с containerd

Мы собираемся использовать команду ctr для взаимодействия с containerd. Он был включен в containerdустановку:

NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
containerd CLI
USAGE:
   ctr [global options] command [command options] [arguments...]
VERSION:
   v1.5.0-beta.1
DESCRIPTION:
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.
COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command
GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

containerd может извлекать изображения из реестра контейнеров и поддерживает теги. Мы используем ctr, чтобы вытащить nginx изображение:

$ sudo ctr image pull docker.io/library/nginx:latest

Используя ctr, мы можем получить список изображений. Мы можем убедиться, что изображение nginx было извлечено:

$ sudo ctr image ls
$ sudo ctr image ls -q
docker.io/library/nginx:latest

У нас есть nginximage, и теперь мы можем запускать контейнер, используя его:

$ sudo ctr container create docker.io/library/nginx:latest webdemo

Контейнер запущен? Подтвердим это, перечислив контейнеры:

$ sudo ctr container list
CONTAINER    IMAGE                             RUNTIME
webdemo      docker.io/library/nginx:latest    io.containerd.runc.v2

Если мы удалим изображение, контейнер все еще будет работать:

$ sudo ctr image remove docker.io/library/nginx:latest
docker.io/library/nginx:latest
$ sudo ctr image ls -q
$ sudo ctr container list
CONTAINER    IMAGE                             RUNTIME
webdemo      docker.io/library/nginx:latest    io.containerd.runc.v2

Теперь мы можем удалить контейнер:

sudo ctr container delete webdemo

Заключение

У нас был обзор dockerhistory. Мы видели, что вначале это было монолитное программное обеспечение. Docker внес свой вклад в определение стандартов контейнеров в OCI. В результате этого docker архитектура изменилась.

Первоначально kubernetes использовался docker, но в версии 1.20 было решено отказаться от него. Мы видели, что docker общается с containerdи runc для запуска контейнеров. Его дополнительная ценность заключается в предоставлении разработчикам удобных возможностей для управления изображениями и ресурсами.

В случае распределенной системы, такой как kubernetes, она может напрямую вызывать среду выполнения контейнера. Дополнительный уровень не требуется, и он может создать сложность и увеличить количество вызовов между уровнями программного обеспечения.

Наконец, мы попрактиковались containerd, установив и настроив его на Raspberry Pi. Это хорошая цель для тестирования containerd, поскольку у нее ограниченные ресурсы, и в большинстве случаев вы не создаете на ней изображения. Вы просто хотите вытащить изображения и поместить их в контейнеры. Мы заметили, что можем извлекать docker изображений и запускать контейнеры, как обычно, с containerd.

Спасибо за прочтение!

Ресурсы