Definiowanie zadań kontenera (YAML)

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

Domyślnie zadania są uruchamiane na maszynie hosta, na której jest zainstalowany agent. Jest to wygodne i zazwyczaj dobrze dopasowane do projektów, które dopiero zaczynają wdrażać usługę Azure Pipelines. W miarę upływu czasu może się okazać, że chcesz mieć większą kontrolę nad kontekstem, w którym są uruchamiane zadania. Potoki YAML oferują zadania kontenera dla tego poziomu kontroli.

W przypadku agentów systemu Linux i Windows zadania mogą być uruchamiane na hoście lub w kontenerze. (W systemach macOS i Red Hat Enterprise Linux 6 zadania kontenera są niedostępne). Kontenery zapewniają izolację od hosta i umożliwiają przypinanie określonych wersji narzędzi i zależności. Zadania hosta wymagają mniej początkowej konfiguracji i infrastruktury do utrzymania.

Kontenery oferują uproszczoną abstrakcję w systemie operacyjnym hosta. Możesz wybrać dokładne wersje systemów operacyjnych, narzędzi i zależności wymaganych przez kompilację. Po określeniu kontenera w potoku agent najpierw pobierze i uruchomi kontener. Następnie każdy krok zadania zostanie uruchomiony wewnątrz kontenera. Nie można mieć zagnieżdżonych kontenerów. Kontenery nie są obsługiwane, gdy agent jest już uruchomiony wewnątrz kontenera.

Jeśli potrzebujesz szczegółowej kontroli na poziomie poszczególnych kroków, cele kroków umożliwiają wybranie kontenera lub hosta dla każdego kroku.

Wymagania

Kontenery oparte na systemie Linux

System Azure Pipelines wymaga kilku elementów w kontenerach opartych na systemie Linux:

  • Bash
  • oparte na glibc
  • Można uruchomić Node.js (które udostępnia agent)
  • Nie definiuje elementu ENTRYPOINT
  • USER ma dostęp do groupadd poleceń i innych uprawnień bez sudo

I na hoście agenta:

  • Upewnij się, że platforma Docker jest zainstalowana
  • Agent musi mieć uprawnienia dostępu do demona platformy Docker

Upewnij się, że kontener ma każde z tych narzędzi. Niektóre kontenery usunięte dostępne w usłudze Docker Hub, zwłaszcza te oparte na systemie Alpine Linux, nie spełniają tych minimalnych wymagań. Kontenery z elementem ENTRYPOINT mogą nie działać, ponieważ usługa Azure Pipelines będzie docker create oczekiwać kontenera i docker exec serii poleceń, które oczekują, że kontener jest zawsze uruchomiony.

Uwaga

W przypadku kontenerów systemu Linux opartych na systemie Windows należy wstępnie zainstalować Node.js.

Kontenery systemu Windows

Usługa Azure Pipelines może również uruchamiać kontenery systemu Windows. Wymagany jest system Windows Server w wersji 1803 lub nowszej. Należy zainstalować platformę Docker. Upewnij się, że agent potoków ma uprawnienia dostępu do demona platformy Docker.

Kontener systemu Windows musi obsługiwać uruchamianie Node.js. W podstawowym kontenerze systemu Windows Nano Server brakuje zależności wymaganych do uruchomienia węzła.

Hostowani agenci

Tylko windows-2019 obrazy i ubuntu-* obsługują uruchamianie kontenerów. Obraz systemu macOS nie obsługuje uruchomionych kontenerów.

Jedno zadanie

Prosty przykład:

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

Spowoduje to, że system pobierze ubuntu obraz otagowany 18.04 z usługi Docker Hub , a następnie uruchom kontener. Po uruchomieniu printenv polecenia odbywa się to wewnątrz kontenera ubuntu:18.04 .

Przykład systemu Windows:

pool:
  vmImage: 'windows-2019'

container: mcr.microsoft.com/windows/servercore:ltsc2019

steps:
- script: set

Uwaga

System Windows wymaga dopasowania wersji jądra hosta i kontenera. Ponieważ w tym przykładzie użyto obrazu systemu Windows 2019, użyjemy tagu 2019 dla kontenera.

Wiele zadań

Kontenery są również przydatne do uruchamiania tych samych kroków w wielu zadaniach. W poniższym przykładzie te same kroki są uruchamiane w wielu wersjach systemu Ubuntu Linux. (I nie musimy wspominać o słowie jobs kluczowym, ponieważ zdefiniowano tylko jedno zadanie).

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

Punkty końcowe

Kontenery mogą być hostowane w rejestrach innych niż publiczne rejestry usługi Docker Hub. Aby hostować obraz w usłudze Azure Container Registry lub innym prywatnym rejestrze kontenerów (w tym prywatnym rejestrze usługi Docker Hub), dodaj połączenie usługi do rejestru prywatnego. Następnie możesz odwoływać się do niego w specyfikacji kontenera:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

steps:
- script: echo hello

lub

container:
  image: myprivate.azurecr.io/windowsservercore:1803
  endpoint: my_acr_connection

steps:
- script: echo hello

Inne rejestry kontenerów mogą również działać. Usługa Amazon ECR nie działa obecnie, ponieważ istnieją inne narzędzia klienckie wymagane do konwersji poświadczeń platformy AWS na coś, czego platforma Docker może używać do uwierzytelniania.

Uwaga

Kompilacja red Hat Enterprise Linux 6 agenta nie będzie uruchamiać zadania kontenera. Wybierz inny smak systemu Linux, taki jak Red Hat Enterprise Linux 7 lub nowszy.

Opcje

Jeśli musisz kontrolować uruchamianie kontenera, możesz określić wartość options.

container:
  image: ubuntu:18.04
  options: --hostname container-test --ip 192.168.0.1

steps:
- script: echo hello

Uruchomienie docker create --help udostępnia listę opcji, które można przekazać do wywołania platformy Docker. Nie wszystkie te opcje są gwarantowane do pracy z usługą Azure DevOps. Najpierw sprawdź, czy możesz użyć właściwości kontenera, aby osiągnąć ten sam cel. Aby uzyskać więcej informacji, zobacz resources.containers.container w schemacieYAML i docker create dokumentacji polecenia.

Definicja kontenera wielokrotnego użytku

W poniższym przykładzie kontenery są definiowane w sekcji zasobów. Następnie do każdego kontenera odwołuje się później, odwołując się do przypisanego aliasu. (Tutaj jawnie wyświetlamy jobs słowo kluczowe w celu uzyskania jasności).

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

Kontenery niezwiązane z glibcem

Agent usługi Azure Pipelines dostarcza kopię Node.js, która jest wymagana do uruchamiania zadań i skryptów. Aby dowiedzieć się, w której wersji Node.js dla hostowanego agenta, zobacz Agenci hostowani przez firmę Microsoft. Wersja Node.js jest kompilowana w środowisku uruchomieniowym języka C używanym w naszej chmurze hostowanej, zazwyczaj glibc. Niektóre warianty systemu Linux używają innych środowisk uruchomieniowych języka C. Na przykład alpine Linux używa musl.

Jeśli chcesz użyć kontenera innego niż glibc jako kontenera zadań, musisz zorganizować kilka rzeczy samodzielnie. Najpierw należy podać własną kopię Node.js. Po drugie, należy dodać etykietę do obrazu z informacją o tym, gdzie agent znajdzie Node.js binarny. Na koniec magazyn Alpine nie zawiera innych zależności, od których zależy usługa Azure Pipelines: bash, sudo, które i groupadd.

Przynieś własne Node.js

Odpowiadasz za dodanie pliku binarnego Node do kontenera. Węzeł 18 jest bezpiecznym wyborem. Możesz zacząć od node:18-alpine obrazu.

Poinformuj agenta o Node.js

Agent odczytuje etykietę kontenera "com.azure.dev.pipelines.handler.node.path". Jeśli ta etykieta istnieje, musi być ścieżką do pliku binarnego Node.js. Na przykład na obrazie opartym na node:18-alpinepliku dodaj ten wiersz do pliku Dockerfile:

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

Dodawanie wymagań

Usługa Azure Pipelines zakłada, że system oparty na powłoce Bash z zainstalowanymi typowymi pakietami administracyjnymi. Alpine Linux w szczególności nie zawiera kilku potrzebnych pakietów. Instalowanie bash, sudoi shadow obejmuje podstawowe potrzeby.

RUN apk add bash sudo shadow

Jeśli zależysz od dowolnych zadań wbudowanych lub w witrynie Marketplace, musisz również podać wymagane pliki binarne.

Pełny przykład pliku Dockerfile

FROM node:10-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" ]

Wiele zadań z pulami agentów w jednym hostowanym agencie

Zadanie kontenera używa podstawowego agenta hosta do config.json na potrzeby autoryzacji rejestru obrazów, która wyloguje się na końcu inicjowania kontenera rejestru platformy Docker. Kolejna autoryzacja ściągania obrazu rejestru może zostać odrzucona w przypadku "nieautoryzowanego uwierzytelniania", ponieważ plik platformy Docker config.json zarejestrowany w systemie na potrzeby uwierzytelniania został już wylogowany przez jedno z innych zadań kontenera, które są uruchomione równolegle.

Rozwiązaniem jest ustawienie zmiennej środowiskowej DOCKER_CONFIG platformy Docker specyficznej dla każdej usługi puli agentów uruchomionej na hostowanym agencie. Wyeksportuj DOCKER_CONFIG skrypt runsvc.sh każdej puli agentów:

#insert anything to set up env when running as a service
export DOCKER_CONFIG=./.docker