Docker'da şirket içinde barındırılan bir aracı çalıştırma
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Bu makalede, Azure Pipelines aracınızı Docker'da çalıştırma yönergeleri sağlanır. Azure Pipelines'da Docker ile bir Windows Server Core (Windows konakları için) veya Ubuntu kapsayıcısı (Linux konakları için) içinde çalışacak şekilde şirket içinde barındırılan bir aracı ayarlayabilirsiniz. Bu, Azure Container Instances gibi dış düzenleme ile aracıları çalıştırmak istediğinizde kullanışlıdır. Bu makalede, aracı kendi kendine güncelleştirmesini işleme de dahil olmak üzere eksiksiz bir kapsayıcı örneğini inceleyeceksiniz.
Hem Windows hem de Linux kapsayıcı konakları olarak desteklenir. Windows kapsayıcıları bir Windows vmImage
üzerinde çalıştırılmalıdır.
Aracınızı Docker'da çalıştırmak için aracıyı Azure Pipelines'a docker run
veya Azure DevOps Server'a bağlanacak şekilde yapılandıran öğesine birkaç ortam değişkeni geçireceksiniz. Son olarak kapsayıcıyı gereksinimlerinize uyacak şekilde özelleştirebilirsiniz. Görevler ve betikler, kapsayıcının PATH
üzerinde kullanılabilen belirli araçlara bağlı olabilir ve bu araçların kullanılabilir olduğundan emin olmak sizin sorumluluğunuzdadır.
Bu özellik için aracı sürümü 2.149 veya üzeri gerekir. Azure DevOps 2019 uyumlu bir aracı sürümüyle birlikte gelmedi. Ancak Docker aracılarını çalıştırmak istiyorsanız doğru aracı paketini uygulama katmanınıza yükleyebilirsiniz.
Windows
Hyper-V'yi etkinleştirme
Hyper-V, Windows'ta varsayılan olarak etkin değildir. Kapsayıcılar arasında yalıtım sağlamak istiyorsanız Hyper-V'yi etkinleştirmeniz gerekir. Aksi takdirde, Windows için Docker başlatılmaz.
Not
Makinenizde sanallaştırmayı etkinleştirmeniz gerekir. Genellikle varsayılan olarak etkindir. Ancak, Hyper-V yüklemesi başarısız olursa sanallaştırmayı etkinleştirme hakkında sistem belgelerinize bakın.
Windows için Docker'ı yükleme
Windows 10 kullanıyorsanız Docker Community Edition'ı yükleyebilirsiniz. Windows Server 2016 için Docker Enterprise Sürümü yükleyin.
Docker'ı Windows kapsayıcılarını kullanacak şekilde değiştirme
Varsayılan olarak, Windows için Docker Linux kapsayıcılarını kullanacak şekilde yapılandırılır. Windows kapsayıcısının çalıştırılmasına izin vermek için Windows için Docker'ın Windows daemon'unu çalıştırdığını onaylayın.
Dockerfile oluşturma ve oluşturma
Ardından Dockerfile'ı oluşturun.
Komut istemi açın.
Yeni dizin oluşturma:
mkdir "C:\azp-agent-in-docker\"
Şu yeni dizine gidin:
cd "C:\azp-agent-in-docker\"
Aşağıdaki içeriği adlı
C:\azp-agent-in-docker\azp-agent-windows.dockerfile
bir dosyaya kaydedin:FROM mcr.microsoft.com/windows/servercore:ltsc2022 WORKDIR /azp/ COPY ./start.ps1 ./ CMD powershell .\start.ps1
Aşağıdaki içeriği 'ye
C:\azp-agent-in-docker\start.ps1
kaydedin: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})" }
Bu dizinde aşağıdaki komutu çalıştırın:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .
Son görüntü etiketli
azp-agent:windows
.
Resmi başlatma
Artık bir görüntü oluşturduğunuza göre bir kapsayıcı çalıştırabilirsiniz. Bu, aracının en son sürümünü yükler, yapılandırılır ve aracıyı çalıştırır. Seçtiğiniz belirli bir Azure DevOps veya Azure DevOps Server örneğinin belirtilen aracı havuzunu ( Default
varsayılan olarak aracı havuzu) hedefler:
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
Ağ sorunlarıyla karşılaşırsanız parametresini --network
belirtmeniz gerekebilir.
docker run --network "Default Switch" < . . . >
Kapsayıcıyı durdurmak ve --tty
aracısını ileC
+ Ctrl
kaldırmak istiyorsanız ve bayrakları (veya basitçe-it
) belirtmeniz --interactive
gerekebilir.
docker run --interactive --tty < . . . >
Her işlem hattı işi için yeni bir aracı kapsayıcısı istiyorsanız bayrağını --once
komutuna run
geçirin.
docker run < . . . > --once
bayrağıyla, iş tamamlandığında kapsayıcının --once
yeni bir kopyasını başlatmak için Kubernetes veya Azure Container Instances gibi bir kapsayıcı düzenleme sistemi kullanmak isteyebilirsiniz.
İsteğe bağlı ortam değişkenlerini kullanarak aracı adını, aracı havuzunu ve aracı iş dizinini denetleyebilirsiniz.
Linux
Docker'ı yükleme
Linux Dağıtımınıza bağlı olarak Docker Community Edition veya Docker Enterprise Sürümü yükleyebilirsiniz.
Dockerfile oluşturma ve oluşturma
Ardından Dockerfile'ı oluşturun.
Bir terminal açın.
Yeni dizin oluşturma (önerilen):
mkdir ~/azp-agent-in-docker/
Şu yeni dizine gidin:
cd ~/azp-agent-in-docker/
Aşağıdaki içeriği 'ye
~/azp-agent-in-docker/azp-agent-linux.dockerfile
kaydedin:Alpler için:
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" ]
Ubuntu 22.04 için:
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" ]
Aracıyı kök olarak çalıştırmak istiyorsanız satırın
ENV AGENT_ALLOW_RUNASROOT="true"
açıklamasını kaldırın ve kullanıcıyı bu satırdan önce eklemeyiagent
kaldırın.Not
Görevler, kapsayıcınızın sağlaması beklenen yürütülebilir dosyalara bağlı olabilir. Örneğin, ve görevlerini çalıştırmak için
RUN apt install -y
veunzip
ExtractFiles
paketlerini komutunaArchiveFiles
eklemenizzip
gerekir. Ayrıca, aracının kullanması için bir Linux Ubuntu görüntüsü olduğundan, görüntüyü istediğiniz gibi özelleştirebilirsiniz. Örneğin: .NET uygulamaları oluşturmanız gerekiyorsa Ubuntu'da .NET SDK'sını veya .NET Çalışma Zamanı'nı yükleme belgesini izleyebilir ve bunu görüntünüze ekleyebilirsiniz.Unix stili (LF) satır sonlarını kullandığınızdan emin olmak için aşağıdaki içeriği
~/azp-agent-in-docker/start.sh
öğesine kaydedin:#!/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 $!
Not
Ayrıca, iş tamamlandığında kapsayıcının yeni kopyalarını başlatmak için Kubernetes veya Azure Container Instances gibi bir kapsayıcı düzenleme sistemi kullanmanız gerekir.
Bu dizinde aşağıdaki komutu çalıştırın:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .
Son görüntü etiketli
azp-agent:linux
.
Resmi başlatma
Artık bir görüntü oluşturduğunuza göre bir kapsayıcı çalıştırabilirsiniz. Bu, aracının en son sürümünü yükler, yapılandırılır ve aracıyı çalıştırır. Seçtiğiniz belirli bir Azure DevOps veya Azure DevOps Server örneğinin belirtilen aracı havuzunu ( Default
varsayılan olarak aracı havuzu) hedefler:
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
Kapsayıcıyı durdurmak ve --tty
aracısını ileC
+ Ctrl
kaldırmak istiyorsanız ve bayrakları (veya basitçe-it
) belirtmeniz --interactive
gerekebilir.
docker run --interactive --tty < . . . >
Her işlem hattı işi için yeni bir aracı kapsayıcısı istiyorsanız bayrağını --once
komutuna run
geçirin.
docker run < . . . > --once
bayrağıyla, iş tamamlandığında kapsayıcının --once
yeni bir kopyasını başlatmak için Kubernetes veya Azure Container Instances gibi bir kapsayıcı düzenleme sistemi kullanmak isteyebilirsiniz.
İsteğe bağlı ortam değişkenlerini kullanarak aracı adını, aracı havuzunu ve aracı iş dizinini denetleyebilirsiniz.
Ortam değişkenleri
Ortam değişkeni | Açıklama |
---|---|
AZP_URL | Azure DevOps veya Azure DevOps Server örneğinin URL'si. |
AZP_TOKEN | aracıları yapılandırma iznine sahip bir kullanıcı tarafından oluşturulan Aracı Havuzları (okuma, yönetme) kapsamına sahip Kişisel Erişim Belirteci (PAT) adresindeAZP_URL . |
AZP_AGENT_NAME | Aracı adı (varsayılan değer: kapsayıcı konak adı). |
AZP_POOL | Aracı havuzu adı (varsayılan değer: Default ). |
AZP_WORK | İş dizini (varsayılan değer: _work ). |
Araç ekleme ve kapsayıcıyı özelleştirme
Temel bir derleme aracısı oluşturdunuz. Dockerfile'ı ek araçları ve bağımlılıklarını içerecek şekilde genişletebilir veya bunu temel katman olarak kullanarak kendi kapsayıcınızı oluşturabilirsiniz. Yalnızca aşağıdakilerin dokunulmadığından emin olun:
- Betik
start.sh
Dockerfile tarafından çağrılır. - Betik
start.sh
, Dockerfile'daki son komutdur. - Türev kapsayıcıların Dockerfile tarafından belirtilen bağımlılıklardan hiçbirini kaldırmadığından emin olun.
Docker kapsayıcısı içinde Docker kullanma
Docker'ı bir Docker kapsayıcısının içinden kullanmak için Docker yuvasını bağlamanız gerekir.
Dikkat
Bunu yapmanın ciddi güvenlik etkileri vardır. Kapsayıcının içindeki kod artık Docker konağınızda kök olarak çalıştırılabilir.
Bunu yapmak istediğinizden eminseniz Docker.com bağlama belgelerine bakın.
Azure Kubernetes Service kümesini kullanma
Dikkat
Docker kısıtlaması nedeniyle docker tabanlı görevlerin AKS 1.19 veya sonraki sürümlerinde çalışmayacağını lütfen göz önünde bulundurun. Docker, Kubernetes 1.19'da kapsayıcılı olarak değiştirildi ve Docker-in-Docker kullanılamaz hale geldi.
Azure Kubernetes Service'i dağıtma ve yapılandırma
Hızlı Başlangıç: Azure portalını kullanarak Azure Kubernetes Service (AKS) kümesi dağıtma altındaki adımları izleyin. Bundan sonra PowerShell veya Kabuk konsolunuz komut satırını kullanabilir kubectl
.
Azure Container Registry'yi dağıtma ve yapılandırma
Hızlı Başlangıç: Azure portalını kullanarak Azure kapsayıcı kayıt defteri oluşturma'daki adımları izleyin. Bundan sonra Azure Container Registry'den kapsayıcıları gönderip çekebilirsiniz.
Gizli dizileri yapılandırma ve çoğaltma kümesi dağıtma
AKS kümesinde gizli dizileri oluşturun.
kubectl create secret generic azdevops \ --from-literal=AZP_URL=https://dev.azure.com/yourOrg \ --from-literal=AZP_TOKEN=YourPAT \ --from-literal=AZP_POOL=NameOfYourPool
Kapsayıcınızı Container Registry'ye göndermek için şu komutu çalıştırın:
docker push "<acr-server>/azp-agent:<tag>"
Mevcut AKS kümeleri için Container Registry tümleştirmesini yapılandırın.
Not
Azure Portal'da birden çok aboneliğiniz varsa lütfen önce bu komutu kullanarak bir abonelik seçin
az account set --subscription "<subscription id or subscription name>"
az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
Aşağıdaki içeriği 'ye
~/AKS/ReplicationController.yml
kaydedin: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
Bu Kubernetes YAML,
replicas: 1
kümede çalışan aracıların sayısını veya aracılarını gösteren bir çoğaltma kümesi ve bir dağıtım oluşturur.Şu komutu çalıştırın:
kubectl apply -f ReplicationController.yml
Artık aracılarınız AKS kümesini çalıştıracak.
Özel MTU parametresini ayarlama
Kapsayıcı işleri tarafından kullanılan ağlar için MTU değeri belirtmeye izin verin (k8s kümesindeki docker-in-docker senaryoları için kullanışlıdır).
MTU değerini ayarlamak için ortam değişkeni AGENT_DOCKER_MTU_VALUE ayarlamanız ve ardından şirket içinde barındırılan aracıyı yeniden başlatmanız gerekir. Aracı yeniden başlatma hakkında daha fazla bilgiye buradan ve her bir aracı için farklı ortam değişkenleri ayarlama hakkında burada bulabilirsiniz.
Bu, iş kapsayıcısı için bir ağ parametresi ayarlamanıza olanak tanır. Bu komutun kullanılması, kapsayıcı ağ yapılandırması sırasında sonraki komutun kullanımına benzer:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Docker kapsayıcısı içinde Docker kullanarak birimleri bağlama
Docker kapsayıcısı başka bir Docker kapsayıcısı içinde çalışıyorsa, her ikisi de konağın daemon'unu kullanır, bu nedenle tüm bağlama yolları kapsayıcıya değil konağa başvurur.
Örneğin, ana bilgisayardan dış Docker kapsayıcısına yol bağlamak istiyorsak şu komutu kullanabiliriz:
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
Ana bilgisayardan iç Docker kapsayıcısına yol bağlamak istiyorsak şu komutu kullanabiliriz:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Ancak dış kapsayıcıdaki yolları iç kapsayıcıya bağlayamıyoruz; bu sorunu çözmek için bir ENV değişkeni bildirmemiz gerekir:
docker run ... --env DIND_USER_HOME=$HOME ...
Bundan sonra, şu komutu kullanarak iç kapsayıcıyı dış kapsayıcıdan başlatabiliriz:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Sık karşılaşılan hatalar
Windows kullanıyorsanız ve aşağıdaki hatayı alırsanız:
standard_init_linux.go:178: exec user process caused "no such file or directory"
Git-scm dosyasını indirip yükleyerek Git Bash'i yükleyin.
Şu komutu çalıştırın:
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
Yeniden deneyin. Artık hatayı alamayacaksınız.