Jalankan agen yang di-host sendiri di Docker
Layanan Azure DevOps | Azure DevOps Server 2022 - Azure DevOps Server 2019
Artikel ini menyediakan instruksi untuk menjalankan agen Azure Pipelines Anda di Docker. Anda dapat menyiapkan agen yang dihost sendiri di Azure Pipelines untuk berjalan di dalam Windows Server Core (untuk host Windows), atau kontainer Ubuntu (untuk host Linux) dengan Docker. Ini berguna ketika Anda ingin menjalankan agen dengan orkestrasi luar, seperti Azure Container Instances. Dalam artikel ini, Anda akan menelusuri contoh kontainer lengkap, termasuk menangani pembaruan mandiri agen.
Windows dan Linux didukung sebagai host kontainer. Kontainer Windows harus berjalan pada Windows vmImage
.
Untuk menjalankan agen di Docker, Anda akan meneruskan beberapa variabel lingkungan ke docker run
, yang mengonfigurasi agen untuk terhubung ke Azure Pipelines atau Azure DevOps Server. Terakhir, Anda menyesuaikan kontainer agar sesuai dengan kebutuhan Anda. Tugas dan skrip mungkin bergantung pada alat tertentu yang tersedia di kontainer PATH
, dan Anda bertanggung jawab untuk memastikan bahwa alat-alat ini tersedia.
Fitur ini memerlukan agen versi 2.149 atau yang lebih baru. Azure DevOps 2019 tidak dikirim dengan versi agen yang kompatibel. Namun, Anda dapat mengunggah paket agen yang benar ke tingkat aplikasi Jika Anda ingin menjalankan agen Docker.
Windows
Mengaktifkan Hyper-V
Hyper-V tidak diaktifkan secara default di Windows. Jika Anda ingin memberikan isolasi antar kontainer, Anda harus mengaktifkan Hyper-V. Jika tidak, Docker untuk Windows tidak akan dimulai.
Catatan
Anda harus mengaktifkan virtualisasi pada komputer Anda. Biasanya diaktifkan secara default. Namun, jika penginstalan Hyper-V gagal, lihat dokumentasi sistem Anda tentang cara mengaktifkan virtualisasi.
Menginstal Docker untuk Windows
Jika Anda menggunakan Windows 10, Anda dapat menginstal Docker Community Edition. Untuk Windows Server 2016, instal Docker Enterprise Edition.
Alihkan Docker untuk menggunakan kontainer Windows
Secara default, Docker untuk Windows dikonfigurasi untuk menggunakan kontainer Linux. Untuk mengizinkan menjalankan kontainer Windows, konfirmasikan bahwa Docker untuk Windows menjalankan daemon Windows.
Membuat dan membangun Dockerfile
Selanjutnya, buat Dockerfile.
Buka prompt perintah.
Buat direktori baru:
mkdir "C:\azp-agent-in-docker\"
Buka direktori baru ini:
cd "C:\azp-agent-in-docker\"
Simpan konten berikut ke file yang disebut
C:\azp-agent-in-docker\azp-agent-windows.dockerfile
:FROM mcr.microsoft.com/windows/servercore:ltsc2022 WORKDIR /azp/ COPY ./start.ps1 ./ CMD powershell .\start.ps1
Simpan konten berikut ke
C:\azp-agent-in-docker\start.ps1
:function Print-Header ($header) { Write-Host "`n${header}`n" -ForegroundColor Cyan } if (-not (Test-Path Env:AZP_URL)) { Write-Error "error: missing AZP_URL environment variable" exit 1 } if (-not (Test-Path Env:AZP_TOKEN_FILE)) { if (-not (Test-Path Env:AZP_TOKEN)) { Write-Error "error: missing AZP_TOKEN environment variable" exit 1 } $Env:AZP_TOKEN_FILE = "\azp\.token" $Env:AZP_TOKEN | Out-File -FilePath $Env:AZP_TOKEN_FILE } Remove-Item Env:AZP_TOKEN if ((Test-Path Env:AZP_WORK) -and -not (Test-Path $Env:AZP_WORK)) { New-Item $Env:AZP_WORK -ItemType directory | Out-Null } New-Item "\azp\agent" -ItemType directory | Out-Null # Let the agent ignore the token env variables $Env:VSO_AGENT_IGNORE = "AZP_TOKEN,AZP_TOKEN_FILE" Set-Location agent Print-Header "1. Determining matching Azure Pipelines agent..." $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(Get-Content ${Env:AZP_TOKEN_FILE})")) $package = Invoke-RestMethod -Headers @{Authorization=("Basic $base64AuthInfo")} "$(${Env:AZP_URL})/_apis/distributedtask/packages/agent?platform=win-x64&`$top=1" $packageUrl = $package[0].Value.downloadUrl Write-Host $packageUrl Print-Header "2. Downloading and installing Azure Pipelines agent..." $wc = New-Object System.Net.WebClient $wc.DownloadFile($packageUrl, "$(Get-Location)\agent.zip") Expand-Archive -Path "agent.zip" -DestinationPath "\azp\agent" try { Print-Header "3. Configuring Azure Pipelines agent..." .\config.cmd --unattended ` --agent "$(if (Test-Path Env:AZP_AGENT_NAME) { ${Env:AZP_AGENT_NAME} } else { hostname })" ` --url "$(${Env:AZP_URL})" ` --auth PAT ` --token "$(Get-Content ${Env:AZP_TOKEN_FILE})" ` --pool "$(if (Test-Path Env:AZP_POOL) { ${Env:AZP_POOL} } else { 'Default' })" ` --work "$(if (Test-Path Env:AZP_WORK) { ${Env:AZP_WORK} } else { '_work' })" ` --replace Print-Header "4. Running Azure Pipelines agent..." .\run.cmd } finally { Print-Header "Cleanup. Removing Azure Pipelines agent..." .\config.cmd remove --unattended ` --auth PAT ` --token "$(Get-Content ${Env:AZP_TOKEN_FILE})" }
Jalankan perintah berikut dalam direktori tersebut:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .
Gambar akhir ditandai
azp-agent:windows
.
Memulai gambar
Setelah membuat gambar, Anda dapat menjalankan kontainer. Ini menginstal versi terbaru agen, mengonfigurasinya, dan menjalankan agen. Ini menargetkan kumpulan agen yang ditentukan ( Default
kumpulan agen secara default) dari instans Azure DevOps atau Azure DevOps Server tertentu pilihan Anda:
docker run -e AZP_URL="<Azure DevOps instance>" -e AZP_TOKEN="<Personal Access Token>" -e AZP_POOL="<Agent Pool Name>" -e AZP_AGENT_NAME="Docker Agent - Windows" --name "azp-agent-windows" azp-agent:windows
Anda mungkin perlu menentukan --network
parameter jika Mengalami masalah jaringan.
docker run --network "Default Switch" < . . . >
Anda mungkin perlu menentukan --interactive
dan menandai (atau sederhana -it
) jika Anda ingin dapat menghentikan kontainer dan menghapus agen denganC
Ctrl
+ .--tty
docker run --interactive --tty < . . . >
Jika Anda menginginkan kontainer agen baru untuk setiap pekerjaan alur, teruskan --once
bendera ke run
perintah .
docker run < . . . > --once
--once
Dengan bendera , Anda mungkin ingin menggunakan sistem orkestrasi kontainer, seperti Kubernetes atau Azure Container Instances, untuk memulai salinan baru kontainer ketika pekerjaan selesai.
Anda dapat mengontrol nama agen, kumpulan agen, dan direktori kerja agen dengan menggunakan variabel lingkungan opsional.
Linux
Menginstal Docker
Bergantung pada Distribusi Linux, Anda dapat menginstal Docker Community Edition atau Docker Enterprise Edition.
Membuat dan membangun Dockerfile
Selanjutnya, buat Dockerfile.
Buka terminal.
Buat direktori baru (disarankan):
mkdir ~/azp-agent-in-docker/
Buka direktori baru ini:
cd ~/azp-agent-in-docker/
Simpan konten berikut ke
~/azp-agent-in-docker/azp-agent-linux.dockerfile
:Untuk Alpine:
FROM alpine ENV TARGETARCH="linux-musl-x64" # Another option: # FROM arm64v8/alpine # ENV TARGETARCH="linux-musl-arm64" RUN apk update RUN apk upgrade RUN apk add bash curl git icu-libs jq WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh RUN adduser -D agent RUN chown agent ./ USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]
Untuk Ubuntu 22.04:
FROM ubuntu:22.04 ENV TARGETARCH="linux-x64" # Also can be "linux-arm", "linux-arm64". RUN apt update RUN apt upgrade -y RUN apt install -y curl git jq libicu70 WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh # Create agent user and set up home directory RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]
Batalkan
ENV AGENT_ALLOW_RUNASROOT="true"
komentar baris dan hapus penambahanagent
pengguna sebelum baris ini jika Anda ingin menjalankan agen sebagai root.Catatan
Tugas mungkin bergantung pada executable yang diharapkan disediakan kontainer Anda. Misalnya, Anda harus menambahkan
zip
paket danunzip
keRUN apt install -y
perintah untuk menjalankanArchiveFiles
tugas danExtractFiles
. Selain itu, karena ini adalah gambar Ubuntu Linux untuk digunakan agen, Anda dapat menyesuaikan gambar sesuai kebutuhan Anda. Misalnya: jika Anda perlu membangun aplikasi .NET, Anda dapat mengikuti dokumen Instal .NET SDK atau .NET Runtime di Ubuntu dan menambahkannya ke gambar Anda.Simpan konten berikut ke
~/azp-agent-in-docker/start.sh
, pastikan untuk menggunakan akhir baris gaya Unix (LF):#!/bin/bash set -e if [ -z "${AZP_URL}" ]; then echo 1>&2 "error: missing AZP_URL environment variable" exit 1 fi if [ -z "${AZP_TOKEN_FILE}" ]; then if [ -z "${AZP_TOKEN}" ]; then echo 1>&2 "error: missing AZP_TOKEN environment variable" exit 1 fi AZP_TOKEN_FILE="/azp/.token" echo -n "${AZP_TOKEN}" > "${AZP_TOKEN_FILE}" fi unset AZP_TOKEN if [ -n "${AZP_WORK}" ]; then mkdir -p "${AZP_WORK}" fi cleanup() { trap "" EXIT if [ -e ./config.sh ]; then print_header "Cleanup. Removing Azure Pipelines agent..." # If the agent has some running jobs, the configuration removal process will fail. # So, give it some time to finish the job. while true; do ./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") && break echo "Retrying in 30 seconds..." sleep 30 done fi } print_header() { lightcyan="\033[1;36m" nocolor="\033[0m" echo -e "\n${lightcyan}$1${nocolor}\n" } # Let the agent ignore the token env variables export VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE" print_header "1. Determining matching Azure Pipelines agent..." AZP_AGENT_PACKAGES=$(curl -LsS \ -u user:$(cat "${AZP_TOKEN_FILE}") \ -H "Accept:application/json" \ "${AZP_URL}/_apis/distributedtask/packages/agent?platform=${TARGETARCH}&top=1") AZP_AGENT_PACKAGE_LATEST_URL=$(echo "${AZP_AGENT_PACKAGES}" | jq -r ".value[0].downloadUrl") if [ -z "${AZP_AGENT_PACKAGE_LATEST_URL}" -o "${AZP_AGENT_PACKAGE_LATEST_URL}" == "null" ]; then echo 1>&2 "error: could not determine a matching Azure Pipelines agent" echo 1>&2 "check that account "${AZP_URL}" is correct and the token is valid for that account" exit 1 fi print_header "2. Downloading and extracting Azure Pipelines agent..." curl -LsS "${AZP_AGENT_PACKAGE_LATEST_URL}" | tar -xz & wait $! source ./env.sh trap "cleanup; exit 0" EXIT trap "cleanup; exit 130" INT trap "cleanup; exit 143" TERM print_header "3. Configuring Azure Pipelines agent..." ./config.sh --unattended \ --agent "${AZP_AGENT_NAME:-$(hostname)}" \ --url "${AZP_URL}" \ --auth "PAT" \ --token $(cat "${AZP_TOKEN_FILE}") \ --pool "${AZP_POOL:-Default}" \ --work "${AZP_WORK:-_work}" \ --replace \ --acceptTeeEula & wait $! print_header "4. Running Azure Pipelines agent..." chmod +x ./run.sh # To be aware of TERM and INT signals call ./run.sh # Running it with the --once flag at the end will shut down the agent after the build is executed ./run.sh "$@" & wait $!
Catatan
Anda juga harus menggunakan sistem orkestrasi kontainer, seperti Kubernetes atau Azure Container Instances, untuk memulai salinan baru kontainer saat pekerjaan selesai.
Jalankan perintah berikut dalam direktori tersebut:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .
Gambar akhir ditandai
azp-agent:linux
.
Memulai gambar
Setelah membuat gambar, Anda dapat menjalankan kontainer. Ini menginstal versi terbaru agen, mengonfigurasinya, dan menjalankan agen. Ini menargetkan kumpulan agen yang ditentukan ( Default
kumpulan agen secara default) dari instans Azure DevOps atau Azure DevOps Server tertentu pilihan Anda:
docker run -e AZP_URL="<Azure DevOps instance>" -e AZP_TOKEN="<Personal Access Token>" -e AZP_POOL="<Agent Pool Name>" -e AZP_AGENT_NAME="Docker Agent - Linux" --name "azp-agent-linux" azp-agent:linux
Anda mungkin perlu menentukan --interactive
dan menandai (atau sederhana -it
) jika Anda ingin dapat menghentikan kontainer dan menghapus agen denganC
Ctrl
+ .--tty
docker run --interactive --tty < . . . >
Jika Anda menginginkan kontainer agen baru untuk setiap pekerjaan alur, teruskan --once
bendera ke run
perintah .
docker run < . . . > --once
--once
Dengan bendera , Anda mungkin ingin menggunakan sistem orkestrasi kontainer, seperti Kubernetes atau Azure Container Instances, untuk memulai salinan baru kontainer ketika pekerjaan selesai.
Anda dapat mengontrol nama agen, kumpulan agen, dan direktori kerja agen dengan menggunakan variabel lingkungan opsional.
Variabel lingkungan
Variabel lingkungan | Deskripsi |
---|---|
AZP_URL | URL instans Azure DevOps atau Azure DevOps Server. |
AZP_TOKEN | Token Akses Pribadi (PAT) dengan cakupan Kumpulan Agen (baca, kelola), dibuat oleh pengguna yang memiliki izin untuk mengonfigurasi agen, di AZP_URL . |
AZP_AGENT_NAME | Nama agen (nilai default: nama host kontainer). |
AZP_POOL | Nama kumpulan agen (nilai default: Default ). |
AZP_WORK | Direktori kerja (nilai default: _work ). |
Menambahkan alat dan menyesuaikan kontainer
Anda telah membuat agen build dasar. Anda dapat memperluas Dockerfile untuk menyertakan alat tambahan dan dependensinya, atau membangun kontainer Anda sendiri dengan menggunakan yang ini sebagai lapisan dasar. Pastikan bahwa berikut ini dibiarkan tidak tersentuh:
start.sh
Skrip dipanggil oleh Dockerfile.start.sh
Skrip adalah perintah terakhir di Dockerfile.- Pastikan bahwa kontainer turunan tidak menghapus salah satu dependensi yang dinyatakan oleh Dockerfile.
Menggunakan Docker dalam kontainer Docker
Untuk menggunakan Docker dari dalam kontainer Docker, Anda mengikat-mount soket Docker.
Perhatian
Melakukan ini memiliki implikasi keamanan yang serius. Kode di dalam kontainer sekarang dapat berjalan sebagai root pada host Docker Anda.
Jika Anda yakin ingin melakukan ini, lihat dokumentasi pemasangan ikatan di Docker.com.
Menggunakan kluster Azure Kubernetes Service
Perhatian
Harap, pertimbangkan bahwa setiap tugas berbasis docker tidak akan berfungsi pada AKS 1.19 atau yang lebih baru karena docker dalam pembatasan docker. Docker diganti dengan kontainer di Kubernetes 1.19, dan Docker-in-Docker menjadi tidak tersedia.
Menyebarkan dan mengonfigurasi Azure Kubernetes Service
Ikuti langkah-langkah dalam Mulai Cepat: Menyebarkan kluster Azure Kubernetes Service (AKS) dengan menggunakan portal Azure. Setelah ini, konsol PowerShell atau Shell Anda dapat menggunakan kubectl
baris perintah.
Menyebarkan dan mengonfigurasi Azure Container Registry
Ikuti langkah-langkah di Mulai Cepat: Membuat registri kontainer Azure dengan menggunakan portal Azure. Setelah ini, Anda dapat mendorong dan menarik kontainer dari Azure Container Registry.
Mengonfigurasi rahasia dan menyebarkan set replika
Buat rahasia pada kluster AKS.
kubectl create secret generic azdevops \ --from-literal=AZP_URL=https://dev.azure.com/yourOrg \ --from-literal=AZP_TOKEN=YourPAT \ --from-literal=AZP_POOL=NameOfYourPool
Jalankan perintah ini untuk mendorong kontainer Anda ke Container Registry:
docker push "<acr-server>/azp-agent:<tag>"
Konfigurasikan integrasi Container Registry untuk kluster AKS yang ada.
Catatan
Jika Anda memiliki beberapa langganan di Portal Microsoft Azure, silakan gunakan perintah ini terlebih dahulu untuk memilih langganan
az account set --subscription "<subscription id or subscription name>"
az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
Simpan konten berikut ke
~/AKS/ReplicationController.yml
:apiVersion: apps/v1 kind: Deployment metadata: name: azdevops-deployment labels: app: azdevops-agent spec: replicas: 1 # here is the configuration for the actual agent always running selector: matchLabels: app: azdevops-agent template: metadata: labels: app: azdevops-agent spec: containers: - name: kubepodcreation image: <acr-server>/azp-agent:<tag> env: - name: AZP_URL valueFrom: secretKeyRef: name: azdevops key: AZP_URL - name: AZP_TOKEN valueFrom: secretKeyRef: name: azdevops key: AZP_TOKEN - name: AZP_POOL valueFrom: secretKeyRef: name: azdevops key: AZP_POOL volumeMounts: - mountPath: /var/run/docker.sock name: docker-volume volumes: - name: docker-volume hostPath: path: /var/run/docker.sock
YAML Kubernetes ini membuat set replika dan penyebaran, di mana
replicas: 1
menunjukkan jumlah atau agen yang berjalan pada kluster.Jalankan perintah ini:
kubectl apply -f ReplicationController.yml
Sekarang agen Anda akan menjalankan kluster AKS.
Mengatur parameter MTU kustom
Izinkan menentukan nilai MTU untuk jaringan yang digunakan oleh pekerjaan kontainer (berguna untuk skenario docker-in-docker di kluster k8s).
Anda perlu mengatur variabel lingkungan AGENT_DOCKER_MTU_VALUE untuk mengatur nilai MTU, lalu memulai ulang agen yang dihost sendiri. Anda dapat menemukan lebih lanjut tentang memulai ulang agen di sini dan tentang mengatur variabel lingkungan yang berbeda untuk setiap agen individu di sini.
Ini memungkinkan Anda untuk menyiapkan parameter jaringan untuk kontainer pekerjaan, penggunaan perintah ini mirip dengan penggunaan perintah berikutnya sementara konfigurasi jaringan kontainer:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Memasang volume menggunakan Docker dalam kontainer Docker
Jika kontainer Docker berjalan di dalam kontainer Docker lain, keduanya menggunakan daemon host, sehingga semua jalur pemasangan mereferensikan host, bukan kontainer.
Misalnya, jika kita ingin memasang jalur dari host ke kontainer Docker luar, kita dapat menggunakan perintah ini:
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
Dan jika kita ingin memasang jalur dari host ke dalam kontainer Docker, kita dapat menggunakan perintah ini:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Tetapi kita tidak dapat memasang jalur dari kontainer luar ke dalam; untuk mengatasinya, kita harus mendeklarasikan variabel ENV:
docker run ... --env DIND_USER_HOME=$HOME ...
Setelah ini, kita dapat memulai kontainer dalam dari yang luar menggunakan perintah ini:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Kesalahan umum
Jika Anda menggunakan Windows, dan Anda mendapatkan kesalahan berikut:
standard_init_linux.go:178: exec user process caused "no such file or directory"
Instal Git Bash dengan mengunduh dan menginstal git-scm.
Jalankan perintah ini:
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
Coba lagi. Anda tidak lagi mendapatkan kesalahan.