• Русский
  • Создание образов

    Узнайте, как создавать собственные контейнерные образы на основе предварительно созданных образов, которые готовы помочь вам. Процесс включает изучение лучших практик написания образов, определение метаданных для образов, тестирование образов и использование пользовательского рабочего процесса сборки для создания образов, которые можно использовать с Alauda Container Platform Registry. После создания образа вы можете отправить его в Alauda Container Platform Registry.

    Изучение лучших практик контейнеров

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

    Общие рекомендации по контейнерным образам

    Следующие рекомендации применимы при создании контейнерного образа в целом и не зависят от того, используются ли образы на Alauda Container Platform.

    Повторное использование образов

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

    Кроме того, используйте теги в инструкции FROM, например, alpine:3.20, чтобы пользователи точно знали, на какой версии образа основан ваш образ. Использование тега, отличного от latest, гарантирует, что ваш образ не подвергнется ломаюшим изменениям, которые могут появиться в последней версии исходного образа.

    Поддерживайте совместимость внутри тегов

    При тегировании собственных образов старайтесь сохранять обратную совместимость внутри тега. Например, если вы предоставляете образ с именем image и он в настоящее время включает версию 1.0, вы можете использовать тег image:v1. При обновлении образа, если он остается совместимым с исходным, вы можете продолжать использовать тег image:v1, и пользователи этого тега смогут получать обновления без сбоев.

    Если позже вы выпустите несовместимое обновление, переключитесь на новый тег, например image:v2. Это позволит пользователям самостоятельно перейти на новую версию, не ломая их случайно несовместимым образом. Любой пользователь, использующий image:latest, принимает на себя риск любых несовместимых изменений.

    Избегайте нескольких процессов

    Не запускайте несколько сервисов, таких как база данных и SSHD, внутри одного контейнера. Это не нужно, так как контейнеры легковесны и их легко связать вместе для оркестрации нескольких процессов. Alauda Container Platform позволяет легко размещать и совместно управлять связанными образами, группируя их в один pod.

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

    Используйте exec в обёрточных скриптах

    Многие образы используют обёрточные скрипты для подготовки перед запуском основного процесса программного обеспечения. Если ваш образ использует такой скрипт, он должен использовать exec, чтобы процесс скрипта был заменён вашим программным процессом. Если не использовать exec, сигналы, отправленные средой выполнения контейнера, будут направлены скрипту, а не процессу вашего ПО. Это нежелательно.

    Если у вас есть обёрточный скрипт, который запускает процесс сервера, и вы запускаете контейнер, например, с помощью podman run -i, который запускает скрипт, а тот запускает процесс. Если вы хотите остановить контейнер с помощью CTRL+C, и если скрипт использует exec для запуска сервера, podman отправит SIGINT процессу сервера, и всё будет работать как ожидается. Если exec не используется, SIGINT будет отправлен процессу скрипта, а ваш процесс продолжит работу, как будто ничего не произошло.

    Также обратите внимание, что ваш процесс работает как PID 1 в контейнере. Это означает, что если основной процесс завершится, весь контейнер остановится, прерывая любые дочерние процессы, запущенные из процесса с PID 1.

    Очищайте временные файлы

    Удаляйте все временные файлы, созданные во время сборки. Это также касается файлов, добавленных с помощью команды ADD. Например, выполняйте команду yum clean после операций yum install.

    Вы можете предотвратить попадание кэша yum в слой образа, создавая команду RUN следующим образом:

    RUN yum -y install mypackage && yum -y install myotherpackage && yum clean all -y

    Обратите внимание, что если написать так:

    RUN yum -y install mypackage
    RUN yum -y install myotherpackage && yum clean all -y

    то первый вызов yum оставит лишние файлы в этом слое, и эти файлы не могут быть удалены при последующем выполнении yum clean. Лишние файлы не видны в итоговом образе, но присутствуют в базовых слоях.

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

    Кроме того, выполнение нескольких команд в одном операторе RUN уменьшает количество слоев в образе, что улучшает время загрузки и распаковки.

    Располагаете инструкции в правильном порядке

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

    Например, если вы работаете с Dockerfile, который содержит команду ADD для установки файла, над которым вы работаете, и команду RUN для установки пакета через yum, лучше поставить команду ADD последней:

    FROM foo
    RUN yum -y install mypackage && yum clean all -y
    ADD myfile /test/myfile

    Так при каждом изменении myfile и повторной сборке с помощью podman build система повторно использует кэш слоя для команды yum и создаёт новый слой только для операции ADD.

    Если же написать Dockerfile так:

    FROM foo
    ADD myfile /test/myfile
    RUN yum -y install mypackage && yum clean all -y

    то при каждом изменении myfile и повторной сборке команда ADD инвалидирует кэш слоя RUN, и команда yum будет выполняться заново.

    Отмечайте важные порты

    Инструкция EXPOSE делает порт в контейнере доступным для хост-системы и других контейнеров. Хотя можно указать, что порт должен быть открыт при вызове podman run, использование инструкции EXPOSE в Dockerfile облегчает как людям, так и программам использование вашего образа, явно объявляя порты, необходимые для работы вашего ПО:

    • Открытые порты отображаются в выводе podman ps для контейнеров, созданных из вашего образа.
    • Открытые порты присутствуют в метаданных образа, возвращаемых podman inspect.
    • Открытые порты связываются при связывании одного контейнера с другим.

    Устанавливайте переменные окружения

    Рекомендуется устанавливать переменные окружения с помощью инструкции ENV. Например, можно указать версию вашего проекта. Это облегчает пользователям поиск версии без просмотра Dockerfile. Другой пример — указание пути в системе, который может использоваться другим процессом, например, JAVA_HOME.

    Избегайте паролей по умолчанию

    Избегайте установки паролей по умолчанию. Многие расширяют образ и забывают удалить или изменить пароль по умолчанию. Это может привести к проблемам безопасности, если пользователь в продакшене получает известный пароль. Пароли лучше настраивать через переменные окружения.

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

    Избегайте sshd

    Лучше не запускать sshd в вашем образе. Вы можете использовать podman exec для доступа к контейнерам на локальном хосте. В кластере используйте kubectl exec для доступа к контейнерам, управляемым Alauda Container Platform. Установка и запуск sshd в образе увеличивает поверхность атаки и усложняет обновления.

    Используйте тома для постоянных данных

    Образы используют тома для постоянных данных. Таким образом, Alauda Container Platform монтирует сетевое хранилище на узел, где запущен контейнер, и если контейнер перемещается на другой узел, хранилище подключается к нему. Использование тома для всех постоянных данных сохраняет содержимое даже при перезапуске или перемещении контейнера. Если ваш образ записывает данные в произвольные места внутри контейнера, эти данные не сохранятся.

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

    Явное определение томов в вашем Dockerfile облегчает пользователям понимание, какие тома нужно создавать при запуске вашего образа.

    Подробнее о томах и их использовании в Alauda Container Platform смотрите в документации Kubernetes.

    Примечание:

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

    Включение метаданных в образы

    Определение метаданных образа помогает Alauda Container Platform лучше использовать ваши контейнерные образы, создавая лучший опыт для разработчиков, использующих ваш образ. Например, вы можете добавить метаданные с полезными описаниями образа или предложениями других образов, которые также могут понадобиться.

    Эта тема описывает только метаданные, необходимые для текущего набора сценариев использования. В будущем могут быть добавлены дополнительные метаданные или сценарии.

    Определение метаданных образа

    Вы можете использовать инструкцию LABEL в Dockerfile для определения метаданных образа. Метки похожи на переменные окружения тем, что представляют собой пары ключ-значение, прикреплённые к образу или контейнеру. Метки отличаются от переменных окружения тем, что они не видны запущенному приложению и могут использоваться для быстрого поиска образов и контейнеров.

    Подробнее об инструкции LABEL смотрите в справке по Dockerfile.

    Имена меток обычно имеют пространство имён. Пространство имён устанавливается в соответствии с проектом, который будет использовать метки. Для Kubernetes пространство имён — io.k8s.