Задания контейнеров в конвейерах 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и whichgroupadd.

Укажите собственные 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" ]