Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Usługi Azure DevOps | Azure DevOps Server | Azure DevOps Server 2022
W tym artykule opisano zadania kontenera w usłudze Azure Pipelines. Kontenery to lekkie abstrakcje z systemu operacyjnego hosta, które zapewniają wszystkie elementy niezbędne do uruchomienia zadania w określonym środowisku.
Domyślnie zadania usługi Azure Pipelines są uruchamiane bezpośrednio na agentach zainstalowanych na maszynach hosta. Zadania hostowanego agenta są wygodne, wymagają niewielkiej początkowej konfiguracji lub konserwacji infrastruktury i są odpowiednie dla podstawowych projektów. Aby uzyskać większą kontrolę nad kontekstem zadania, możesz definiować i uruchamiać zadania potoku w kontenerach, aby korzystać z dokładnie tych wersji systemów operacyjnych, narzędzi i zależności, których potrzebujesz.
W przypadku zadania kontenerowego agent najpierw pobiera i uruchamia kontener, a następnie wykonuje każdy krok zadania wewnątrz kontenera. Jeśli potrzebujesz bardziej szczegółowej kontroli poszczególnych kroków kompilacji, możesz użyć elementów docelowych kroków , aby wybrać kontener lub host dla każdego kroku.
Wymagania dotyczące zadań kontenerowych
- Potok przetwarzania oparty na YAML. Klasyczne potoki nie obsługują zadań kontenera.
- Agent hostowany w systemie Windows lub Ubuntu. Agenci systemu MacOS nie obsługują kontenerów. Aby użyć agentów innych niż Ubuntu Linux, zobacz Kontenery oparte na protokole Nonglibc.
- Docker zainstalowany na agencie, z uprawnieniami dostępu do demona Docker.
- Agent uruchomiony bezpośrednio na hoście, jeszcze nie wewnątrz kontenera. Zagnieżdżone kontenery nie są obsługiwane.
Kontenery oparte na systemie Linux mają również następujące wymagania:
- Zainstalowano powłokę Bash.
- Oparty na bibliotece GNU C (
glibc). Kontenery non-glibc wymagają dodatkowej konfiguracji. Aby uzyskać więcej informacji, zobacz Kontenery oparte na protokole Nonglibc. - Nie
ENTRYPOINT. Kontenery z konteneremENTRYPOINTmogą nie działać, ponieważ narzędzie docker exec oczekuje, że kontener będzie zawsze uruchomiony. -
USERz zapewnionym dostępem dogroupaddi innych uprzywilejowanych poleceń bez użycia poleceniasudo. - Możliwość uruchamiania Node.js, który zapewnia agent.
Uwaga
Node.js muszą być wstępnie zainstalowane dla kontenerów systemu Linux na hostach systemu Windows.
Niektóre kontenery usunięte dostępne w usłudze Docker Hub, zwłaszcza kontenery oparte na systemie Alpine Linux, nie spełniają tych wymagań. Aby uzyskać więcej informacji, zobacz Kontenery oparte na protokole Nonglibc.
Jedno zadanie
W poniższym przykładzie zdefiniowano kontener pojedynczego zadania systemu Windows lub Linux.
Ten przykład informuje system o pobraniu ubuntu obrazu oznakowanego 18.04 z usługi Docker Hub , a następnie uruchomieniu kontenera. Polecenie printenv jest uruchamiane wewnątrz kontenera ubuntu:18.04 .
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
Wiele zadań
Za pomocą kontenerów można uruchomić ten sam krok w wielu zadaniach. Poniższy przykład uruchamia ten sam krok w wielu wersjach systemu Ubuntu Linux. Nie musisz używać słowa kluczowego jobs , 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
Wiele zadań na jednym hoście agenta
Zadanie kontenera korzysta z pliku konfiguracji Dockera na podstawowym agencie hosta do autoryzacji rejestru obrazów. Ten plik kończy działanie po zakończeniu inicjalizacji kontenera rejestru Docker.
Ściąganie obrazu rejestru dla zadań kontenera może zostać odrzucone w przypadku nieautoryzowanego uwierzytelniania, jeśli inne zadanie uruchomione równolegle w agencie już wylogowało plik konfiguracji platformy Docker. Rozwiązaniem jest ustawienie zmiennej środowiskowej Dockera o nazwie DOCKER_CONFIG dla każdej puli agentów działającej na agencie hostowanym.
Wyeksportuj DOCKER_CONFIG w skrypcie runsvc.sh każdej puli agentów w następujący sposób:
export DOCKER_CONFIG=./.docker
Opcje uruchamiania
Za pomocą właściwości można określić opcje uruchamiania options kontenera.
container:
image: ubuntu:18.04
options: --hostname container-test --ip 192.168.0.1
steps:
- script: echo hello
Uruchom docker create --help, aby uzyskać listę opcji, które można przekazać do polecenia Docker. Nie wszystkie te opcje są gwarantowane do pracy z usługą Azure Pipelines. Najpierw sprawdź, czy możesz użyć właściwości container do tego samego celu.
Aby uzyskać więcej informacji, zobacz informacje o poleceniu docker container create i definicję resources.containers.container w informacjach o schemacie YAML dla usługi Azure Pipelines.
Mapowanie gniazd platformy Docker
Począwszy od wersji 5.279.0 agenta zadania kontenerowe na agentach systemu Linux domyślnie nie montują gniazda Docker hosta (/var/run/docker.sock) do kontenera zadania. To ustawienie domyślne jest zgodne z zasadą najmniejszych uprawnień, więc zadaniom, które nie wymagają działania w trybie Docker-in-container, nie jest przyznawany dostęp do demona Docker na hoście.
Jeśli zadanie kontenera uruchamia polecenia Dockera na demonie hosta (Docker-in-container), należy jawnie włączyć tę opcję, ustawiając mapDockerSocket na true w zasobie kontenera.
resources:
containers:
- container: my_container
image: ubuntu:22.04
mapDockerSocket: true
W przypadku wdrożeń na dużą skalę, w których aktualizowanie plików YAML we wszystkich miejscach jest niepraktyczne, można tymczasowo ustawić zmienną środowiskową hosta agenta AZP_AGENT_DEFAULT_MAP_DOCKER_SOCKET_TO_FALSE=false, aby przywrócić poprzednie domyślne zachowanie, w którym zadania kontenera Linux mapują /var/run/docker.sock, chyba że jawnie skonfigurowano mapDockerSocket. Użyj tego ustawienia tylko jako krótkoterminowego ograniczenia ryzyka, ponieważ domyślnie ponownie włącza mapowanie gniazd platformy Docker.
Caution
Mapowanie gniazda platformy Docker ma poważne konsekwencje w zakresie zabezpieczeń. Kod wewnątrz kontenera może działać jako root na hoście Dockera. Ustaw mapDockerSocket: true tylko wtedy, gdy zadanie wymaga działania Docker-in-container.
Definicja kontenera wielokrotnego użytku
Poniższy przykład YAML definiuje kontenery w resources sekcji, a następnie odwołuje się do nich za pomocą przypisanych aliasów. Słowo kluczowe jobs jest używane dla przejrzystoś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
Punkty końcowe usługi
Kontenery można hostować w rejestrach innych niż publiczna usługa 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 w celu uzyskania dostępu do rejestru. Następnie możesz odwołać się do punktu końcowego w definicji kontenera.
Prywatne połączenie z usługą Docker Hub:
container:
image: registry:ubuntu1804
endpoint: private_dockerhub_connection
Połączenie usługi Azure Container Registry:
container:
image: myprivate.azurecr.io/windowsservercore:1803
endpoint: my_acr_connection
Uwaga
Usługa Azure Pipelines nie może skonfigurować połączenia z usługą dla usługi Amazon Elastic Container Registry (ECR), ponieważ usługa Amazon ECR wymaga innych narzędzi klienckich do konwertowania poświadczeń usług Amazon Web Services (AWS) na potrzeby uwierzytelniania platformy Docker.
Kontenery niezależne od glibc
Hostowani agenci usługi Azure Pipelines dostarczają Node.js, który jest wymagany do uruchamiania zadań i skryptów. Wersja Node.js jest kompilowana względem środowiska uruchomieniowego języka C używanego w 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. Aby uzyskać więcej informacji, zobacz Agenci hostowani przez firmę Microsoft.
Jeśli chcesz użyć kontenera opartego na języku nonglibc w potoku, musisz:
- Podaj własną kopię Node.js.
- Dodaj etykietę do obrazu wskazującą lokalizację pliku binarnego Node.js.
- Podaj zależności usługi Azure Pipelines
bash,sudo,whichigroupadd.
Użyj własnego Node.js
Jeśli używasz kontenera opartego na języku nonglibc, musisz dodać plik binarny Node do kontenera. Node.js 18 jest bezpiecznym wyborem. Zacznij od node:18-alpine obrazu.
Skieruj agenta do Node.js
Agent odczytuje etykietę "com.azure.dev.pipelines.handler.node.path"kontenera . Jeśli ta etykieta istnieje, musi być ścieżką do pliku binarnego Node.js.
Na przykład w obrazie opartym na node:18-alpine, dodaj następujący wiersz do pliku Dockerfile:
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"
Dodawanie wymaganych pakietów
Usługa Azure Pipelines wymaga, aby system oparty na powłoce Bash miał zainstalowane typowe pakiety administracyjne. Alpine Linux nie ma kilku wymaganych pakietów. Zainstaluj program bash, sudoi shadow , aby uwzględnić podstawowe potrzeby.
RUN apk add bash sudo shadow
Jeśli korzystasz z jakichkolwiek zadań wbudowanych lub zadań z Marketplace, dołącz również wymagane przez nie pliki binarne.
Pełny przykład pliku 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" ]