在 Docker 中執行自我裝載式代理程式

Azure DevOps 服務 |Azure DevOps Server |Azure DevOps Server 2022

本文提供在 Docker 中執行 Azure Pipelines 代理程式的指示。 您可以在 Azure Pipelines 中設定自我裝載代理程式,以在 Windows Server Core 內執行(適用於 Windows 主機),或使用 Docker 在 Ubuntu 容器中執行。 當您想要使用外部協調流程執行代理程式,例如 Azure 容器實例時,這會很有用。 在本文中,您將逐步解說完整的容器範例,包括處理代理程式自我更新。

Windows 和 Linux 都支援作為容器主機。 Windows 容器應在 Windows vmImage上執行。 若要在 Docker 中執行代理程式,您會將幾個 環境變數 傳遞至 docker run,其會將代理程式設定為連線到 Azure Pipelines 或 Azure DevOps Server。 最後,您可以 自定義容器 以符合您的需求。 工作和腳本可能取決於容器 PATH上可用的特定工具,而且您必須負責確保這些工具可供使用。

窗戶

啟用 Hyper-V

根據預設,Windows 上不會啟用 Hyper-V。 如果您想要在容器之間提供隔離,您必須啟用 Hyper-V。 否則,適用於 Windows 的 Docker 將不會啟動。

注意

您必須在電腦上啟用虛擬化。 它通常預設為啟用。 不過,如果 Hyper-V 安裝失敗,請參閱您的系統檔,以瞭解如何啟用虛擬化。

安裝適用於 Windows 的 Docker (英文)

如果您使用 Windows 10,您可以安裝 Docker Community Edition。 Windows Server 2016 時,安裝 Mirantis Container Runtime(前稱 Docker Enterprise Edition)。

將 Docker 切換為使用 Windows 容器

根據預設,適用於 Windows 的 Docker 會設定為使用 Linux 容器。 若要允許執行 Windows 容器,請確認適用於 Windows 的 Docker 正在執行 Windows 精靈。

建立並建置 Dockerfile

接下來,建立 Dockerfile。

  1. 開啟命令提示字元。

  2. 建立新的目錄:

    mkdir "C:\azp-agent-in-docker\"
    
  3. 移至這個新目錄:

    cd "C:\azp-agent-in-docker\"
    
  4. 將下列內容儲存至名為 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. 將下列內容儲存至 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. 在該目錄中執行下列命令:

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

    最後一個影像會標記 azp-agent:windows。

啟動映像

現在您已建立映像檔,您可以運行容器。 這會安裝最新版的代理程序、設定並執行代理程式。 它會以您選擇的指定 Azure DevOps 或 Azure DevOps Server 實例的指定代理程式集區(預設代理 Default 程式集區)為目標:

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

如果您遇到網路問題,您可能需要指定 --network 參數。

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

如果您希望能夠停止容器並移除代理程式,您可能需要指定 --interactive 和 --tty 旗標(或者只需要 -it)。Ctrl + C。

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

如果您希望每個管線作業都使用全新的代理容器,請將這個--once旗標傳遞給run命令。

docker run < . . . > --once

--once使用旗標時,您可能會想要使用容器編排系統,例如 Kubernetes 或 Azure 容器執行個體,在作業完成後啟動容器的副本。

您可以使用選擇性 環境變數來控制代理程式名稱、代理程式集區和代理程式工作目錄。

Linux

安裝 Docker

根據您的 Linux 散發套件,您可以安裝 Docker Community Edition 或 Docker Enterprise Edition。

建立並建置 Dockerfile

接下來,建立 Dockerfile。

  1. 開啟終端機。

  2. 建立新的目錄 (建議):

    mkdir ~/azp-agent-in-docker/
    
  3. 移至這個新目錄:

    cd ~/azp-agent-in-docker/
    
  4. 將下列內容儲存至 ~/azp-agent-in-docker/azp-agent-linux.dockerfile:

    • 針對 Alpine,請使用 此問題中所述的技術:

      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" ]
      
    • 對於 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" ]
      
    • 針對 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" ]
      

    如果您想要以 root 身分執行代理程式,請取消ENV AGENT_ALLOW_RUNASROOT="true"行的註解,並移除在此行之前新增的agent使用者。

    注意

    工作可能取決於容器預期提供的可執行檔。 例如,您必須將 zip 和 unzip 套件新增到 RUN apt install -y 命令中,才能執行 ArchiveFiles 和 ExtractFiles 工作。 此外,由於這是Linux Ubuntu映像供代理程式使用,因此您可以視需要自定義映像。 例如:如果您需要建置 .NET 應用程式,可以遵循檔案 在 Ubuntu 上安裝 .NET SDK 或 .NET 執行環境,然後將其新增至映像檔。

  5. 將下列內容儲存至 ~/azp-agent-in-docker/start.sh,請務必使用 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 $!
    

    注意

    您也必須使用 Kubernetes 或 Azure 容器實例等容器協調流程系統,在工作完成時啟動容器的新複本。

  6. 在該目錄中執行下列命令:

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

    最後一個影像會標記 azp-agent:linux。

啟動映像

現在您已建立映像檔,您可以運行容器。 這會安裝最新版的代理程序、設定並執行代理程式。 它會以您選擇的指定 Azure DevOps 或 Azure DevOps Server 實例的指定代理程式集區(預設代理 Default 程式集區)為目標:

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

如果您希望能夠停止容器並移除代理程式,您可能需要指定 --interactive 和 --tty 旗標(或者只需要 -it)。Ctrl + C。

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

如果您希望每個管線作業都使用全新的代理容器,請將這個--once旗標傳遞給run命令。

docker run < . . . > --once

--once使用旗標時,您可能會想要使用容器編排系統,例如 Kubernetes 或 Azure 容器執行個體,在作業完成後啟動容器的副本。

您可以使用選擇性 環境變數來控制代理程式名稱、代理程式集區和代理程式工作目錄。

環境變數

環境變數 描述
AZP_URL Azure DevOps 或 Azure DevOps Server 實例的 URL。
AZP_TOKEN 個人存取權杖 (PAT)
AZP_CLIENTID 服務主體 用戶端識別碼
AZP_CLIENTSECRET 服務主體用戶端密鑰
AZP_TENANTID 服務主體租用戶標識碼
AZP_AGENT_NAME 代理程式名稱(預設值:容器主機名)。
AZP_POOL 代理程式集區名稱(預設值: Default)。
AZP_WORK 工作目錄(預設值: _work)。

認證

需要下列其中一項:

  • 如果使用 PAT:AZP_TOKEN
  • 如果使用服務主體:AZP_CLIENTID、AZP_CLIENTSECRET和 AZP_TENANTID

授權

令牌或服務主體必須具有 組織層級的 AZP_URL 範圍。 如果使用 PAT,則必須由有權 設定代理程式的使用者建立令牌。

新增工具和自定義容器

您已建立基本組建代理程式。 您可以擴充 Dockerfile 以包含其他工具和其相依性,或使用此容器作為基底層來建置您自己的容器。 請確保下列項目保持不變:

  • 腳本 start.sh 是由 Dockerfile 呼叫。
  • 腳本 start.sh 是 Dockerfile 中的最後一個命令。
  • 確定衍生容器不會移除 Dockerfile 所陳述的任何相依性。

在 Docker 容器內使用 Docker

若要在 Docker 容器內使用 Docker,需要掛載 Docker 套接字。

警告

這樣做具有嚴重的安全性影響。 容器內的程式代碼現在可以在 Docker 主機上以 root 使用者身份執行。

如果您確定要這樣做,請參閱 Docker.com 上的綁定掛載文件。

注意

對於 Azure Pipelines 的 容器作業,預設不會將主機 Docker socket(/var/run/docker.sock)對應至作業容器。 如果你的容器作業需要從容器內存取主機上的 Docker 常駐程式,請在容器資源上設定 mapDockerSocket: true。 欲了解更多資訊,請參閱 Docker socket mapping。

使用 Azure Kubernetes Service 叢集

警告

請注意,由於 Docker in Docker 的限制,任何基於 Docker 的任務都無法在 AKS 1.19 或更高版本上運行。 Docker 被 containerd 取代 在 Kubernetes 1.19 中,且 Docker-in-Docker 變得無法使用。

部署和設定 Azure Kubernetes Service

請遵循 快速入門:使用 Azure 入口網站部署 Azure Kubernetes Service (AKS) 叢集中的步驟。 之後,您的 PowerShell 或 Shell 控制台可以使用 kubectl 命令行。

部署及設定 Azure Container Registry

請遵循 快速入門:使用 Azure 入口網站建立 Azure 容器登錄中的步驟。 之後,您可以從 Azure Container Registry 推送和提取容器。

設定機密資料並部署副本集

  1. 在 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. 執行此指令將您的容器推送至 Container Registry:

    docker push "<acr-server>/azp-agent:<tag>"
    
  3. 設定現有 AKS 叢集的容器登錄整合。

    注意

    如果您在 Azure 入口網站上有多個訂用帳戶,請先使用此命令來選取訂用帳戶

    az account set --subscription "<subscription id or subscription name>"
    
    az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
    
  4. 將下列內容儲存至 ~/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
    

    此 Kubernetes YAML 會建立副本集和部署,其中 replicas: 1 表示在叢集上執行的號碼或代理程式。

  5. 執行此命令:

    kubectl apply -f ReplicationController.yml
    

現在您的代理程式會執行 AKS 叢集。

設定自訂 MTU 參數

允許為容器工作所使用的網路指定 MTU 值(這在 k8s 叢集中的 docker-in-docker 情況下十分有用)。

您必須設定環境變數AGENT_DOCKER_MTU_VALUE來設定 MTU 值,然後重新啟動自我裝載代理程式。 您可以 在這裡 找到有關代理程式重新啟動的詳細資訊,以及 在這裡為每個個別代理程式設定不同的環境變數。

這可讓您設定作業容器的網路參數,使用此命令類似於在容器網路設定時使用下一個命令:

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

在 Docker 容器中使用 Docker 掛載磁碟區

如果 Docker 容器在另一個 Docker 容器內執行,它們都會使用主機的精靈,因此所有掛接路徑都會參考主機,而不是容器。

例如,如果我們想要將路徑從主機掛接至外部 Docker 容器,我們可以使用此命令:

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

如果我們想要將路徑從主機掛接至內部 Docker 容器,則可以使用此命令:

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

但是,我們無法將外部容器的路徑掛接至內部容器;若要解決此問題,我們必須宣告 ENV 變數:

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

在此之後,我們可以使用下列命令,從外部容器啟動內部容器:

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

常見錯誤

如果您使用 Windows,並收到下列錯誤:

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

下載並安裝 git-scm 以安裝 Git Bash。

執行此命令:

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

然後再試一次。 您不再遇到錯誤。