Задания контейнеров в конвейерах YAML
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
В этой статье объясняются контейнерные задания в Azure Pipelines.
По умолчанию задания Azure Pipelines выполняются непосредственно на хост-компьютерах, на которых установлен агент. Задания агентов в облаке удобны, требуют минимальной начальной настройки и инфраструктуры для обслуживания, и отлично подходят для базовых проектов.
Если требуется больше контроля над контекстом задачи, можно определить и запустить задания в контейнерах. Контейнеры — это легковесная абстракция над операционной системой хоста, которые обеспечивают изоляцию от хоста. При выполнении заданий в контейнерах можно выбрать точные версии операционных систем, средств и зависимостей, необходимых для сборки.
Агенты Linux и Windows могут выполнять задания конвейера непосредственно на узле или в контейнерах. Задания контейнеров недоступны для macOS.
Для работы с контейнером агент сначала извлекает и запускает контейнер. Затем каждый шаг задания выполняется внутри контейнера.
Если вам нужен детализированный контроль на уровне отдельного шага сборки, целевые шаги позволяют выбрать контейнер или хост для каждого шага.
Предварительные требования
- Используйте конвейер YAML. Классические конвейеры не поддерживают контейнерные задания.
- Используйте размещенный агент Windows или Ubuntu. Только агенты
windows-*
иubuntu-*
поддерживают выполнение контейнеров. Агентыmacos-*
не поддерживают выполнение контейнеров. - Агент настроен для контейнерных заданий.
- Агенты Windows и Linux должны установить Docker и иметь разрешение на доступ к управляющей программе Docker.
- Контейнеры не поддерживаются, если агент уже работает внутри контейнера. Вы не можете иметь вложенные контейнеры.
Дополнительные требования к контейнеру
Контейнеры под управлением Linux имеют следующие требования. Сведения об обходных решениях см. в разделе "Контейнеры на основе Nonglibc".
- Установлен Bash
- Библиотека GNU C (glibc) на основе
- Без
ENTRYPOINT
- Предоставление
USER
доступа кgroupadd
и другим привилегированным командам без использованияsudo
- Может запускать Node.js, который предоставляет агент.
Примечание.
Node.js необходимо предварительно установить для контейнеров Linux на узлах Windows.
Некоторые облегченнные контейнеры, доступные в Docker Hub, особенно контейнеры на базе Alpine Linux, не удовлетворяют этим требованиям. Контейнеры с ENTRYPOINT
могут не работать, потому что Azure Pipelines docker create
и docker exec
ожидают, что контейнер всегда запущен и функционирует.
Примеры отдельных заданий
В следующих примерах определяется контейнер Windows или Linux для одного задания.
Следующий простой пример определяет контейнер Linux:
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
В предыдущем примере указывается получить изображение ubuntu
, помеченное 18.04
, из Docker Hub, а затем запустить контейнер. Команда printenv
выполняется внутри ubuntu:18.04
контейнера.
Несколько заданий
Контейнеры можно использовать для выполнения одного шага в нескольких заданиях. В следующем примере выполняется один и тот же шаг в нескольких версиях Ubuntu Linux. Ключевое jobs
слово не нужно упоминать, так как определено только одно задание.
pool:
vmImage: 'ubuntu-latest'
strategy:
matrix:
ubuntu16:
containerImage: ubuntu:16.04
ubuntu18:
containerImage: ubuntu:18.04
ubuntu20:
containerImage: ubuntu:20.04
container: $[ variables['containerImage'] ]
steps:
- script: printenv
Несколько заданий с пулами агентов на одном хосте агента
Задание контейнера использует файл конфигурации Docker базового агента узла для авторизации реестра образов. Этот файл выходит из системы в конце инициализации контейнера реестра Docker. Извлечение образа реестра для последующих заданий контейнеров может быть запрещено unauthorized authentication
, так как другое задание, выполняемое параллельно, уже вышло из конфигурационного файла Docker.
Решением является установка переменной DOCKER_CONFIG
среды Docker, относящейся к каждому пулу агентов, работающему на размещенном агенте.
DOCKER_CONFIG
Экспортируйте сценарий runsvc.sh каждого пула агентов следующим образом:
export DOCKER_CONFIG=./.docker
Параметры запуска
Можно указать options
для управления запуском контейнера, как показано в следующем примере:
container:
image: ubuntu:18.04
options: --hostname container-test --ip 192.168.0.1
steps:
- script: echo hello
Выполнение docker create --help
предоставляет список параметров, которые можно передать в вызов Docker. Не все эти параметры гарантированно работают с Azure DevOps. Сначала проверьте, можно ли использовать container
свойство для выполнения той же цели.
Дополнительные сведения см. в справочнике по команде docker create и в определении resources.containers.container в справочнике по схеме YAML в Azure DevOps.
Определение контейнера для повторного использования
Следующий пример определяет контейнеры в resources
разделе, а затем ссылается на них по назначенным псевдонимам. Ключевое jobs
слово явно указано для ясности.
resources:
containers:
- container: u16
image: ubuntu:16.04
- container: u18
image: ubuntu:18.04
- container: u20
image: ubuntu:20.04
jobs:
- job: RunInContainer
pool:
vmImage: 'ubuntu-latest'
strategy:
matrix:
ubuntu16:
containerResource: u16
ubuntu18:
containerResource: u18
ubuntu20:
containerResource: u20
container: $[ variables['containerResource'] ]
steps:
- script: printenv
Конечные точки служб
Контейнеры можно размещать в других реестрах, кроме общедоступного Центра Docker. Чтобы разместить образ в Реестр контейнеров Azure или другом частном реестре контейнеров, включая частный реестр Docker Hub, добавьте подключение к службе для доступа к реестру. Затем можно ссылаться на конечную точку в определении контейнера.
Частное подключение Docker Hub:
container:
image: registry:ubuntu1804
endpoint: private_dockerhub_connection
Подключение к реестру контейнеров Azure:
container:
image: myprivate.azurecr.io/windowsservercore:1803
endpoint: my_acr_connection
Примечание.
Azure Pipelines не может настроить подключение к службе для реестра контейнеров Amazon Elastic Container Registry (ECR), так как Amazon ECR требует других клиентских средств для преобразования учетных данных AWS в то, что Docker может использовать для проверки подлинности.
Контейнеры на основе nonglibc
Агент Azure Pipelines предоставляет копию Node.js, которая требуется для выполнения задач и сценариев. Чтобы узнать версию Node.js для размещенного агента, ознакомьтесь с агентами, размещенными корпорацией Майкрософт.
Версия Node.js компилируется с учетом среды выполнения C, используемой в размещенном облаке, обычно это glibc. Некоторые варианты Linux используют другие среды выполнения C. Например, в Alpine Linux используется мусл.
Если вы хотите использовать контейнер на основе nonglibc, необходимо выполнить следующие действия.
- Предоставьте собственную копию Node.js.
- Добавьте метку в изображение, указывающее агенту, где найти Node.js двоичный файл.
- Укажите другие зависимости, от которые зависит Azure Pipelines:
bash
,sudo
иwhich
groupadd
.
Предоставьте свой собственный Node.js
Если вы используете контейнер, не основанный на glibc, вы несете ответственность за добавление исполняемого файла Node.js в ваш контейнер. Node.js 18 является безопасным выбором. Начните с node:18-alpine
изображения.
Сообщите агенту о Node.js
Агент считывает метку "com.azure.dev.pipelines.handler.node.path"
контейнера. Если эта метка существует, это должен быть путь к Node.js двоичному файлу.
Например, в образ на основе node:18-alpine
добавьте следующую строку в ваш Dockerfile:
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"
Добавление необходимых пакетов
Azure Pipelines требует систему на основе Bash со стандартными административными пакетами, уже установленными. В частности, Alpine Linux не предоставляет несколько необходимых пакетов. Установите bash
, sudo
и shadow
для покрытия основных потребностей.
RUN apk add bash sudo shadow
Если вы зависите от любых задач in-box или Marketplace, укажите необходимые двоичные файлы.
Полный пример Dockerfile
FROM node:18-alpine
RUN apk add --no-cache --virtual .pipeline-deps readline linux-pam \
&& apk add bash sudo shadow \
&& apk del .pipeline-deps
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"
CMD [ "node" ]