Задания контейнеров в конвейерах YAML
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
В этой статье описываются задания контейнеров в Azure Pipelines.
По умолчанию задания Azure Pipelines выполняются непосредственно на хост-компьютерах, на которых установлен агент. Размещенные задания агента удобны, требуют мало начальной настройки и инфраструктуры для обслуживания и хорошо подходят для базовых проектов.
Если требуется больше контроля над контекстом задачи, можно определить и запустить задания в контейнерах. Контейнеры — это упрощенная абстракция по операционной системе узла, которая обеспечивает изоляцию от узла. При выполнении заданий в контейнерах можно выбрать точные версии операционных систем, средств и зависимостей, необходимых для сборки.
Агенты Linux и Windows могут выполнять задания конвейера непосредственно на узле или в контейнерах. Задания контейнеров недоступны в macOS.
Для задания контейнера агент сначала извлекает и запускает контейнер. Затем каждый шаг задания выполняется внутри контейнера.
Если вам нужен подробный контроль на уровне отдельного шага сборки, целевые объекты шагов позволяют выбрать контейнер или узел для каждого шага.
Необходимые компоненты
- Используйте конвейер YAML. Классические конвейеры не поддерживают задания контейнеров.
- Используйте размещенный агент Windows или Ubuntu.
ubuntu-*
Толькоwindows-*
агенты поддерживают выполнение контейнеров. Агенты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.container.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
Если вы используете контейнер на основе nonglibc, вы несете ответственность за добавление двоичного файла Node в контейнер. 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" ]