[Документация Yandex Cloud](../../index.md) > [Yandex Serverless Containers](../index.md) > [Концепции](index.md) > Контейнер

# Контейнер

Контейнер позволяет запустить в Yandex Cloud приложение, которое содержится в [Docker-образе](../../container-registry/concepts/docker-image.md). После создания ревизии контейнера его можно вызвать:
* через HTTPS;
* с помощью триггера;
* с помощью расширения Yandex API Gateway.

Подробнее о [вызове контейнера](invoke.md).

## Ревизия контейнера {#revision}

Ревизию контейнера можно создать только из Docker-образа, который загружен в [реестр](../../container-registry/concepts/registry.md) Yandex Container Registry. Другие реестры не поддерживаются. Ревизия содержит всю информацию, необходимую для запуска контейнера.

Возможные статусы ревизии:
* `Active` — активная;
* `Obsolete` — устаревшая.

При вызове контейнера запускается активная ревизия. По умолчанию это последняя ревизия, но вы можете [сделать активной](../operations/activate-revision.md) другую. Если вы создадите новую ревизию, она автоматически станет активной.

{% note info %}

Для сохранения целостности связей изменение и удаление ревизий контейнера не предусмотрено.

{% endnote %}

Создавать новую ревизию необходимо в следующих случаях:

* загрузка новой версии Docker-образа в [Yandex Container Registry](../../container-registry/index.md);
* изменение настроек ревизии.

Если [реестр](../../container-registry/concepts/registry.md) или [репозиторий](../../container-registry/concepts/repository.md) с Docker-образом не являются [публичными](../../container-registry/qa/index.md#public-registry), необходимо указать в настройках ревизии [сервисный аккаунт](../../iam/concepts/users/service-accounts.md), у которого [есть права](../../iam/operations/sa/assign-role-for-sa.md) на скачивание Docker-образа. Например, роль `container-registry.images.puller` на каталог или реестр, в которых находится Docker-образ.

Если в настройках ревизии указан сервисный аккаунт, у пользователя или сервисного аккаунта, от имени которого создается ревизия, должна быть роль `iam.serviceAccounts.user`. Она подтверждает права на использование сервисного аккаунта.

## Экземпляр контейнера {#container-instance}

Экземпляр контейнера — это виртуальная машина, на которой:

* загружена операционная система;
* запущен bootstrap-процесс;
* проинициализированы компоненты среды выполнения Serverless Containers;
* загружено и проинициализировано пользовательское приложение.

Serverless Containers динамически управляет жизненным циклом виртуальных машин на основе внутренних правил. Эти правила могут меняться в связи с развитием сервиса.

### Создание экземпляра {#instance-creating}

При вызове контейнера происходит одно из двух событий:

* для обработки вызова запускается новый экземпляр контейнера;
* вызов перенаправляется в уже запущенный экземпляр контейнера — экземпляр, не завершившийся после обработки предыдущих вызовов или созданный сервисом в фоновом режиме до получения пользовательского запроса.

Принимая решение о запуске нового экземпляра, Serverless Containers учитывает:

* нагрузку на уже запущенные экземпляры;
* количество вызовов, которые ожидают обработки;
* [настройки масштабирования](#scaling) контейнера;
* использование [квот](limits.md#serverless-containers-quotas).

#### Процесс запуска экземпляра {#starting-process}

1. Serverless Containers выбирает узел сервисного кластера, учитывая наличие ресурсов (CPU, RAM, сеть), загруженных образов пользовательского приложения и другие характеристики, влияющие на длительность запуска экземпляра. Приоритет отдается узлу, который обеспечит минимальную длительность запуска. При этом время запуска может варьироваться: например, оно будет меньше, если узел закешировал образ пользовательского приложения с предыдущего вызова.
1. На выбранном узле кластера запускается виртуальная машина, для которой настраиваются сетевые интерфейсы, выделяются ресурсы CPU и RAM, подключаются образы дисков, содержащие операционную систему и пользовательское приложение.
1. Виртуальная машина запускает ядро Linux и стартовый процесс bootstrap.
1. После инициализации bootstrap-процесс запускает пользовательское приложение.

### Работа экземпляра {#instance-work}

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

### Приостановка экземпляра {#instance-suspending}

Если в течение некоторого времени в созданный экземпляр не поступают новые вызовы, он приостанавливается. Операционная система и запущенные процессы остаются в оперативной памяти, но не обрабатываются процессором. Экземпляр возобновляет работу в следующих случаях:

* при поступлении нового вызова;
* при запуске служебного цикла возобновления работы экземпляра, например для обновления таймеров или выполнения служебных задач гостевой операционной системы;
* перед [завершением экземпляра](#instance-termination).

{% note info %}

Когда экземпляр приостановлен, он не потребляет ресурсы CPU, поэтому сетевые соединения могут быть разорваны. Пользовательское приложение должно корректно обрабатывать такие случаи.

{% endnote %}

### Завершение экземпляра {#instance-termination}

Serverless Containers принимает решение о завершении запущенного экземпляра на основе набора факторов, например:

* длительное время отсутствуют новые вызовы;
* произошел таймаут выполнения контейнера;
* произошла ошибка выполнения, которую нельзя исправить.

В некоторых случаях сервис может [принудительно остановить](long-lived-containers.md#possible-termination) экземпляр контейнера. Тогда в пользовательское приложение поступит [уведомление](termination-notifications.md) о предстоящем принудительном завершении работы.

## Режим работы контейнера {#runtime}

Serverless Containers поддерживает следующие режимы работы контейнера:

Режим работы | Описание работы | Что возвращается при успешном вызове контейнера | Данные HTTP-запроса к контейнеру | Ограничения
--- | --- | --- | --- | ---
**HTTP-сервер** | HTTP-запросы к контейнеру принимает HTTP-сервер, который должен быть запущен на порту из [переменной окружения](runtime.md#environment-variables) `PORT`. Значение переменной задается сервисом автоматически | HTTP-ответ, полученный от HTTP-сервера. При передаче в контейнер некоторые HTTP-заголовки ответа [изменяются](invoke.md#filter) | Передаются в HTTP-запросе к HTTP-серверу | —
**Выполнение команд** | При каждом HTTP-запросе к контейнеру выполняются инструкции `ENTRYPOINT` из Dockerfile или команды, заданные при [создании ревизии](../operations/manage-revision.md). Если команды заданы, они переопределяют инструкции `ENTRYPOINT` из Dockerfile | Код ответа 200 и код завершения в заголовке ответа `X-Task-Exit-Code` | Находятся в файле по пути из переменной окружения `REQUEST_PATH` | Количество одновременных вызовов одного экземпляра контейнера не может быть больше 1

## Масштабирование контейнера {#scaling}

Экземпляр контейнера обрабатывает один его вызов в один момент времени. Если контейнер вызывается быстрее, чем экземпляр успевает обработать запрос, сервис масштабирует контейнер — запускает его дополнительные экземпляры. Таким образом обеспечивается _параллельная обработка запросов_.

Чтобы уменьшить количество холодных стартов, Serverless Containers создает экземпляры контейнера в фоновом режиме, не для обработки пользовательских запросов. При этом количество экземпляров, созданных таким образом, не превышает квоты.

Кроме этого, в Serverless Containers можно задать следующие настройки масштабирования:

* Количество [подготовленных экземпляров](container.md#provisioned-instances).
* Максимальное количество экземпляров контейнера в [зоне доступности](../../overview/concepts/geo-scope.md).
* Максимальное количество одновременно выполняемых вызовов контейнера в зоне доступности.

{% note info %}

Вызовы распределяются по зонам доступности случайным образом. Serverless Containers не гарантирует равномерное распределение вызовов по зонам. Например, все вызовы вне зависимости от их количества могут попасть в одну зону.

{% endnote %}

Настройки масштабирования применяются в течение 5 минут после их задания.

Когда количество экземпляров контейнера достигает значения, указанного в параметре `Количество экземпляров контейнера в зоне доступности`, Serverless Containers перестает масштабировать контейнер. Если вызовов контейнера больше, чем могут обработать экземпляры, вызов становится в очередь, но при этом считается выполняемым. Когда количество выполняемых вызовов достигает значения, указанного в параметре `Количество одновременно выполняемых вызовов контейнера в зоне доступности`, сервис перестает ставить вызовы в очередь и возвращает ошибку `429 TooManyRequests`.

### Подготовленные экземпляры {#provisioned-instances}

_Подготовленный экземпляр_ — это экземпляр контейнера, при запуске которого гарантированно нет холодного старта. В подготовленном экземпляре до вызова контейнера:
* инициализируются компоненты среды выполнения Serverless Containers;
* загружается и инициализируется пользовательское приложение.

Процессы инициализации и работы простого и подготовленного экземпляров контейнера не отличаются. Подготовленный экземпляр приостановлен и не потребляет CPU до тех пор, пока не начнет обрабатывать вызов.

Время простоя подготовленных экземпляров и выполнения в них контейнера [тарифицируется](../pricing.md##execution-provisioned-instances) дополнительно.

Если количество вызовов контейнера превышает количество подготовленных экземпляров, Serverless Containers масштабирует контейнер в пределах [квот](limits.md#functions-quotas), но в неподготовленных экземплярах при их первом запуске происходит холодный старт.

Подготовленные экземпляры расходуют следующие [квоты](limits.md), даже если не запущены:
* Количество экземпляров контейнеров в каждой зоне доступности.
* Суммарный объем RAM для всех запущенных экземпляров контейнеров в каждой зоне доступности.	
* Количество подготовленных экземпляров контейнеров в одном облаке.

## Одновременные вызовы экземпляра контейнера {#concurrency}

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

Параметр `concurrency` не может быть больше 1, если выбран [режим работы](#runtime) `Выполнение команд`.

Если пользователь самостоятельно задает идентификаторы вызовов (`RequestID`), он должен обеспечить их уникальность, иначе при попытке экземпляра обработать вызов с повторяющимся идентификатором вернется ошибка.

Когда экземпляр контейнера обрабатывает одновременно несколько вызовов, в логи записывается идентификатор только последнего из них. Чтобы в логи записывались идентификаторы всех вызовов, которые обрабатывал контейнер, используйте [структурировананные логи](logs.md#structured-logs).

Если хотя бы один вызов достигнет таймаута, он и все остальные вызовы, которые обрабатываются тем же экземпляром контейнера, завершатся. Подробнее о таймауте в [Лимиты](limits.md#serverless-containers-limits).

## Примеры использования {#examples}

* [Разработка CRUD API для сервиса фильмов](../tutorials/movies-database.md)
* [Настройка подключения к Yandex Managed Service for PostgreSQL из контейнера Serverless Containers](../tutorials/pg-connect.md)
* [Запуск контейнерного приложения в Yandex Serverless Containers](../tutorials/deploy-app-container.md)
* [Разработка функций в Functions Framework и их развертывание в Yandex Serverless Containers](../tutorials/functions-framework-to-container.md)

#### Полезные ссылки {#see-also}

* [Создать ревизию контейнера](../operations/manage-revision.md#create)
* [Добавить настройки масштабирования](../operations/scaling-settings-add.md)
* [Задать количество одновременных вызовов экземпляра контейнера](../operations/concurrency.md)