Ejecuta un agente autohospedado en Docker

Servicios de Azure DevOps | Azure DevOps Server | Azure DevOps Server 2022

En este artículo se proporcionan instrucciones para ejecutar el agente de Azure Pipelines en Docker. Puede configurar un agente autohospedado en Azure Pipelines para que se ejecute dentro de un contenedor de Windows Server Core (para hosts de Windows) o de Ubuntu (para hosts de Linux) con Docker. Resulta útil si desea ejecutar agentes con orquestación externa, como, por ejemplo, Azure Container Instances. En este artículo se le guiará por un ejemplo de contenedor completo, incluido el control de la actualización automática del agente.

Tanto Windows como Linux se admiten como hosts de contenedor. Los contenedores de Windows deben ejecutarse en un Windows vmImage. Para ejecutar el agente en Docker, deberá pasar algunas variables de entorno a docker run, que configura el agente para conectarse a Azure Pipelines o a Azure DevOps Server. Por último, deberá personalizar el contenedor para satisfacer sus necesidades. Las tareas y los scripts pueden depender de herramientas específicas que estén disponibles en la PATH del contenedor y es responsabilidad suya asegurarse de que estas herramientas estén disponibles.

Windows

Habilitar Hyper-V

Hyper-V no está habilitado de forma predeterminada en Windows. Si desea proporcionar aislamiento entre contenedores, debe habilitar Hyper-V. De lo contrario, Docker para Windows no se iniciará.

Nota:

Debe habilitar la virtualización en la máquina. Suele estar habilitado de forma predeterminada. Sin embargo, si se produce un error en la instalación de Hyper-V, consulte la documentación del sistema sobre cómo habilitar la virtualización.

Instalación de Docker para Windows

Si usa Windows 10, puede instalar Docker Community Edition. Para Windows Server 2016, instale Mirantis Container Runtime (anteriormente Docker Enterprise Edition).

Cambio de Docker para usar contenedores de Windows

De forma predeterminada, Docker para Windows está configurado para usar contenedores de Linux. Para poder ejecutar un contenedor de Windows, confirme que Docker para Windows se está ejecutando con el daemon de Windows.

Crear y compilar el Dockerfile

A continuación, cree el archivo Dockerfile.

  1. Abra un símbolo del sistema.

  2. Cree un directorio:

    mkdir "C:\azp-agent-in-docker\"
    
  3. Vaya a este nuevo directorio:

    cd "C:\azp-agent-in-docker\"
    
  4. Guarde el siguiente contenido en un archivo denominado 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
    
  5. Guarde el siguiente contenido en 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})"
    }
    
  6. Ejecute el comando siguiente desde ese directorio:

    docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .
    

    La imagen final se etiqueta azp-agent:windows.

Arrancar la imagen

Ahora que ha creado una imagen, puede ejecutar un contenedor. Se instala la versión más reciente del agente, la configura y ejecuta el agente. Tiene como destino el grupo de agentes especificado (el grupo de agentes de Default de forma predeterminada) de una instancia de Azure DevOps o Azure DevOps Server especificada de su elección:

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

Es posible que tenga que especificar el parámetro --network si tiene problemas de red.

docker run --network "Default Switch" < . . . >

Es posible que tenga que especificar las marcas --interactive y --tty (o simplemente -it) si desea poder detener el contenedor y quitar el agente con Ctrl + C.

docker run --interactive --tty < . . . >

Si desea un contenedor de agentes nuevo para cada trabajo de canalización, pase la marca --once al comando run.

docker run < . . . > --once

Con la marca --once, es posible que quiera usar un sistema de orquestación de contenedores, como Kubernetes o Azure Container Instances, para iniciar una nueva copia del contenedor cuando se complete el trabajo.

Puede controlar el nombre del agente, el grupo de agentes y el directorio de trabajo del agente mediante variables de entorno opcionales.

Linux

Instalación de Docker

En función de la distribución de Linux que tenga, puede instalar Docker Community Edition o Docker Enterprise Edition.

Crear y compilar el Dockerfile

A continuación, cree el archivo Dockerfile.

  1. Abra un terminal.

  2. Cree un directorio nuevo (recomendado):

    mkdir ~/azp-agent-in-docker/
    
  3. Vaya a este nuevo directorio:

    cd ~/azp-agent-in-docker/
    
  4. Guarde el siguiente contenido en ~/azp-agent-in-docker/azp-agent-linux.dockerfile:

    • Para Alpine, usando la técnica descrita en este problema:

      FROM python:3-alpine
      ENV TARGETARCH="linux-musl-x64"
      
      # Another option:
      # FROM arm64v8/alpine
      # ENV TARGETARCH="linux-musl-arm64"
      
      RUN apk update && \
        apk upgrade && \
        apk add bash curl gcc git icu-libs jq musl-dev python3-dev libffi-dev openssl-dev cargo make
      
      # Install Azure CLI
      RUN pip install --upgrade pip
      RUN pip install azure-cli
      
      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" ]
      
    • Para Ubuntu 24.04:

      FROM ubuntu:24.04
      ENV TARGETARCH="linux-x64"
      # Also can be "linux-arm", "linux-arm64".
      
      RUN apt update && \
        apt upgrade -y && \
        apt install -y curl git jq libicu74
      
      # Install Azure CLI
      RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash
      
      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" ]
      
    • Para Ubuntu 22.04:

      FROM ubuntu:22.04
      ENV TARGETARCH="linux-x64"
      # Also can be "linux-arm", "linux-arm64".
      
      RUN apt update && \
        apt upgrade -y && \
        apt install -y curl git jq libicu70
      
      # Install Azure CLI
      RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash
      
      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" ]
      

    Descomente la línea ENV AGENT_ALLOW_RUNASROOT="true" y elimine la adición del usuario agent antes de esta línea si desea ejecutar el agente como root.

    Nota:

    Las tareas pueden depender de los ejecutables que se prevé que proporcione el contenedor. Por ejemplo, debe agregar los paquetes zip y unzip al comando RUN apt install -y para poder ejecutar las tareas ArchiveFiles y ExtractFiles. Además, como se trata de una imagen de Linux Ubuntu para que la use el agente, puede personalizar la imagen según sea necesario. Por ejemplo, si necesita compilar aplicaciones .NET, puede seguir el documento Instalación del SDK de .NET o el entorno de ejecución de .NET en Ubuntu y agregarlo a la imagen.

  5. Guarde el siguiente contenido en ~/azp-agent-in-docker/start.sh, asegurándose de usar finales de línea de estilo Unix (LF):

    #!/bin/bash
    set -e
    
    # Load a token either from the environment variable or by using the service principal credentials.
    load_azp_token() {
      # Always un-export AZP_CLIENTSECRET so it is never inherited by
      # child processes (e.g., agent job processes). It remains available
      # as a shell variable so that it can be used to generate a token.
      export -n AZP_CLIENTSECRET
    
      if [ -n "$AZP_CLIENTID" ]; then
        if [ -z "$AZP_CLIENTSECRET" ]; then
          echo 1>&2 "error: AZP_CLIENTSECRET must be set when AZP_CLIENTID is used"
          exit 1
        fi
    
        if [ -z "$AZP_TENANTID" ]; then
          echo 1>&2 "error: AZP_TENANTID must be set when AZP_CLIENTID is used"
          exit 1
        fi
    
        echo "Using service principal credentials to get token"
        # Isolate Azure CLI state to a dedicated, restrictive directory to avoid
        # leaking cached credentials/tokens to subsequent pipeline job processes.
        AZP_TOKEN="$(
           export AZURE_CONFIG_DIR="$(mktemp -d)"
           chmod 700 "$AZURE_CONFIG_DIR"
           az_cli_cleanup() {
             # Log out and remove the isolated Azure CLI config directory to purge cached tokens.
             az logout --username "$AZP_CLIENTID" >/dev/null 2>&1 || true
             az account clear >/dev/null 2>&1 || true
             rm -rf "$AZURE_CONFIG_DIR"
           }
           trap az_cli_cleanup EXIT
           az login --allow-no-subscriptions --service-principal --username "$AZP_CLIENTID" --password "$AZP_CLIENTSECRET" --tenant "$AZP_TENANTID" >/dev/null
           # adapted from https://learn.microsoft.com/en-us/azure/databricks/dev-tools/user-aad-token
           az account get-access-token --query accessToken --output tsv
         )"
        echo "Token retrieved"
      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="$(dirname "$0")/.token"
      fi
    
      if [ -n "${AZP_TOKEN-}" ]; then
        if [ -d "${AZP_TOKEN_FILE}" ]; then
          echo 1>&2 "error: AZP_TOKEN_FILE is a directory, expected a file path: ${AZP_TOKEN_FILE}"
          exit 1
        fi
        # If the file already exists, it must itself be writable. 
        if [ -e "${AZP_TOKEN_FILE}" ]; then
          if [ ! -w "${AZP_TOKEN_FILE}" ]; then
            echo 1>&2 "error: existing AZP_TOKEN_FILE is not writable: ${AZP_TOKEN_FILE}"
            exit 1
          fi
        else
          if [ ! -w "$(dirname "${AZP_TOKEN_FILE}")" ]; then
            echo 1>&2 "error: AZP_TOKEN_FILE parent directory is missing or not writable: $(dirname "${AZP_TOKEN_FILE}")"
            exit 1
          fi
        fi
        (umask 177 && echo -n "${AZP_TOKEN}" > "${AZP_TOKEN_FILE}")
        chmod 600 "${AZP_TOKEN_FILE}" || true
      else
        if [ ! -r "${AZP_TOKEN_FILE}" ]; then
          echo 1>&2 "error: AZP_TOKEN_FILE is not readable: ${AZP_TOKEN_FILE}"
          exit 1
        fi
        if [ ! -s "${AZP_TOKEN_FILE}" ]; then
          echo 1>&2 "error: AZP_TOKEN_FILE is empty: ${AZP_TOKEN_FILE}"
          exit 1
        fi
      fi
    
      # Unset the AZP_TOKEN environment variable to prevent it from being exposed.
      # At this point the token is only available in the file specified by AZP_TOKEN_FILE.
      unset AZP_TOKEN
    }
    
    # Cleanup function to remove the agent configuration.
    cleanup() {
      trap "" EXIT
    
      if [ -e ./config.sh ]; then
        print_header "Cleanup. Removing Azure Pipelines agent..."
    
        # Try to get a new token if using service principal credentials, as the old one
        # might have expired between the time it was waiting to run a job and now.
        # If refresh fails, continue cleanup with the existing token file.
        if [ -n "$AZP_CLIENTID" ]; then
          if ! ( load_azp_token ); then
             echo "Warning: failed to refresh Azure Pipelines token during cleanup. Continuing with the existing token."
          fi
        fi
    
        # If the agent has some running jobs, the configuration removal process will fail.
        # So, give it some time to finish the job. But only try max_attempts and then exit.
        max_attempts=10
        attempt=1
        while [ $attempt -le $max_attempts ]; do
          ./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") && break
    
          echo "Attempt $attempt failed. Retrying in 30 seconds..."
          attempt=$((attempt+1))
          sleep 30
        done
        if [ $attempt -gt $max_attempts ]; then
           echo 1>&2 "warning: failed to remove agent configuration after $max_attempts attempts"
        fi
      fi
    }
    
    print_header() {
      lightcyan="\033[1;36m"
      nocolor="\033[0m"
      echo -e "\n${lightcyan}$1${nocolor}\n"
    }
    
    if [ -z "${AZP_URL}" ]; then
      echo 1>&2 "error: missing AZP_URL environment variable"
      exit 1
    fi
    
    # Load the AZP token for initial setup.
    load_azp_token
    
    if [ -n "${AZP_WORK}" ]; then
      mkdir -p "${AZP_WORK}"
    fi
    
    # Let the agent ignore sensitive env variables, including tokens and the client secret.
    export VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE,AZP_CLIENTSECRET"
    
    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 $!
    
    . ./env.sh
    
    trap "cleanup; exit 0" EXIT
    trap "cleanup; exit 130" INT
    trap "cleanup; exit 143" TERM
    
    print_header "3. Configuring Azure Pipelines agent..."
    
    # Despite it saying "PAT", it can be the token through the service principal
    ./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 $!
    

    Nota:

    También debe usar un sistema de orquestación de contenedores, como Kubernetes o Azure Container Instances, para iniciar nuevas copias del contenedor cuando finalice el trabajo.

  6. Ejecute el comando siguiente desde ese directorio:

    docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .
    

    La imagen final se etiqueta azp-agent:linux.

Arrancar la imagen

Ahora que ha creado una imagen, puede ejecutar un contenedor. Se instala la versión más reciente del agente, la configura y ejecuta el agente. Tiene como destino el grupo de agentes especificado (el grupo de agentes de Default de forma predeterminada) de una instancia de Azure DevOps o Azure DevOps Server especificada de su elección:

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

Es posible que tenga que especificar las marcas --interactive y --tty (o simplemente -it) si desea poder detener el contenedor y quitar el agente con Ctrl + C.

docker run --interactive --tty < . . . >

Si desea un contenedor de agentes nuevo para cada trabajo de canalización, pase la marca --once al comando run.

docker run < . . . > --once

Con la marca --once, es posible que quiera usar un sistema de orquestación de contenedores, como Kubernetes o Azure Container Instances, para iniciar una nueva copia del contenedor cuando se complete el trabajo.

Puede controlar el nombre del agente, el grupo de agentes y el directorio de trabajo del agente mediante variables de entorno opcionales.

Variables de entorno

Variable de entorno Descripción
AZP_URL Dirección URL de la instancia de Azure DevOps o Azure DevOps Server.
AZP_TOKEN Token de acceso personal (PAT)
AZP_CLIENTID ID de cliente de entidad de servicio
AZP_CLIENTSECRET Secreto del cliente de la entidad de servicio
AZP_TENANTID ID de inquilino de entidad de servicio
AZP_AGENT_NAME Nombre del agente (valor predeterminado: el nombre de host del contenedor).
AZP_POOL Nombre del grupo de agentes (valor predeterminado: Default).
AZP_WORK Directorio de trabajo (valor predeterminado: _work).

Autenticación

Se requiere una de las siguientes opciones:

  • Si usa un PAT: AZP_TOKEN
  • Si va a usar una entidad de servicio: AZP_CLIENTID, AZP_CLIENTSECRET y AZP_TENANTID

Autorización

El token o la entidad de servicio deben tener el ámbito de Grupos de agentes (lectura, administración) en el nivel de organización de AZP_URL. Si usa un PAT, el token lo debe crear un usuario que tenga permiso para configurar agentes.

Adición de herramientas y personalización del contenedor

Has creado un agente de compilación básico. Puede ampliar el archivo Dockerfile para incluir herramientas adicionales y sus dependencias, o bien crear su propio contenedor usando este como capa base. Solo debe asegurarse de que no se toque lo siguiente:

  • El script start.sh es llamado por Dockerfile.
  • El script start.sh es el último comando del archivo Dockerfile.
  • Asegúrese de que los contenedores derivados no eliminen ninguna de las dependencias especificadas en el Dockerfile.

Uso de Docker en un contenedor de Docker

Para usar Docker desde un contenedor de Docker, se debe enlazar el socket de Docker.

Precaución

Esto tiene graves implicaciones de seguridad. El código que hay dentro del contenedor ahora se puede ejecutar como raíz en el host de Docker.

Si sabe seguro que desea hacerlo, consulte la documentación de montaje de enlace en Docker.com.

Uso de un clúster de Azure Kubernetes Service

Precaución

Tenga en cuenta que las tareas basadas en Docker no funcionarán en AKS 1.19 o posteriores debido a la restricción de Docker-in-Docker. Docker se reemplazó por containerd en Kubernetes 1.19 y Docker-in-Docker dejó de estar disponible.

Implementación y configuración de Azure Kubernetes Service

Siga los pasos descritos en Inicio rápido: implementación de un clúster de Azure Kubernetes Service (AKS) mediante Azure Portal. Después, la consola de PowerShell o Shell puede usar la línea de comandos kubectl.

Implementación y configuración de Azure Container Registry

Siga los pasos de Inicio rápido: Creación de un instancia de Azure Container Registry mediante Azure Portal. Después, puede insertar y extraer contenedores de Azure Container Registry.

Configure secretos e implemente un conjunto de réplicas

  1. Cree los secretos en el clúster de 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
    
  2. Ejecute este comando para insertar el contenedor en Container Registry:

    docker push "<acr-server>/azp-agent:<tag>"
    
  3. Configure la integración de Container Registry para los clústeres de AKS existentes.

    Nota:

    Si tiene varias suscripciones en Azure Portal, use este comando primero para seleccionar una suscripción.

    az account set --subscription "<subscription id or subscription name>"
    
    az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
    
  4. Guarde el siguiente contenido en ~/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
    

    Este YAML de Kubernetes crea un conjunto de réplicas y una implementación, donde replicas: 1 indica el número o los agentes que se ejecutan en el clúster.

  5. Ejecute este comando:

    kubectl apply -f ReplicationController.yml
    

Ahora los agentes ejecutarán el clúster de AKS.

Establecimiento del parámetro MTU personalizado

Permite especificar el valor de MTU para las redes que usan los trabajos de contenedor (útiles en los escenarios Docker-in-Docker en el clúster k8s).

Debe establecer la variable de entorno AGENT_DOCKER_MTU_VALUE para establecer el valor de MTU y, a continuación, reiniciar el agente autohospedado. Encontrará más información sobre el reinicio del agente aquí y sobre cómo establecer diferentes variables de entorno para cada agente individual aquí.

De este modo, podrá configurar un parámetro de red para el contenedor de trabajos; el uso de este comando es similar al uso del comando siguiente mientras se configura la red del contenedor:

-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE

Montaje de volúmenes mediante Docker en un contenedor de Docker

Si un contenedor de Docker se ejecuta dentro de otro contenedor de Docker, ambos usan el demonio del host, por lo que todas las rutas de montaje hacen referencia al host, no al contenedor.

Por ejemplo, si queremos montar la ruta de acceso del host en un contenedor externo de Docker, podemos usar este comando:

docker run ... -v "<path-on-host>:<path-on-outer-container>" ...

Y si queremos montar la ruta de acceso del host en un contenedor interno de Docker, podemos usar este comando:

docker run ... -v "<path-on-host>:<path-on-inner-container>" ...

Pero no podemos montar rutas de acceso desde el contenedor exterior en el interno; para solucionarlo, tenemos que declarar una variable ENV:

docker run ... --env DIND_USER_HOME=$HOME ...

Después, podemos iniciar el contenedor interno desde el exterior usando este comando:

docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...

Errores comunes

Si usa Windows y recibe el siguiente error:

standard_init_linux.go:178: exec user process caused "no such file or directory"

Instale Git Bash descargando e instalando git-scm.

Ejecute este comando:

dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push

Inténtelo de nuevo. Ya no aparece el error.