Поделиться через


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

Предоставьте свой собственный 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" ]