將工作負載從 Azure DevOps 管道部署到私有 Amazon EKS 叢集 - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

將工作負載從 Azure DevOps 管道部署到私有 Amazon EKS 叢集

Mahendra Revanasiddappa,Amazon Web Services

Summary

此模式示範如何實作從 Azure DevOps 管道到私有 Amazon Elastic Kubernetes Service (Amazon EKS) 叢集的持續整合和持續交付 (CI/CD)。它解決了組織透過轉換到 Amazon EKS 叢集的私有 API 伺服器端點來增強其安全狀態面臨的關鍵挑戰。

公有端點會將 Kubernetes API 伺服器直接公開至網際網路,建立惡意人士可能鎖定的更大攻擊面。透過切換到私有端點,對叢集控制平面的存取僅限於客戶虛擬私有雲端 (VPC) 內。

雖然將 Amazon EKS 叢集轉換為私有 API 端點可大幅提升安全性,但它為 Azure DevOps 等外部 CI/CD 平台帶來連線挑戰。私有端點只能從叢集的 VPC 或對等網路存取。因此,在 AWS 私有網路外操作的標準 Microsoft 託管 Azure DevOps 代理程式無法直接連線到 Kubernetes API 伺服器。這會中斷依賴在這些代理程式上執行之 kubectl 或 Helm 等工具的典型部署工作流程,因為它們無法建立與叢集的連線。

為了克服這個問題,此模式展示了在私有 Amazon EKS 叢集中使用自我託管 Azure DevOps 代理程式的高效方法。此解決方案提供卓越的成本最佳化、營運效率和可擴展性,同時保留安全需求。這種方法特別有利於尋求簡化多雲端 DevOps 程序的企業,而不會影響效能或安全性。

先決條件和限制

先決條件

  • 作用中 AWS 帳戶。

  • AWS Command Line Interface (AWS CLI) 2.13.17 版或更新版本,已安裝。

  • 已安裝 kubectl 1.25.1 版或更新版本。 https://kubernetes.io/docs/tasks/tools/

  • 已建立私有 Amazon EKS 叢集 1.24 版或更新版本,具有建立命名空間、秘密和部署的許可

  • Amazon EKS 叢集中的工作者節點具有網際網路的傳出連線,因此在其上執行的 Azure DevOps 代理程式可以連線至 Azure DevOps 代理程式集區。

  • 已建立 GitHub 帳戶。

  • 具有設定服務連線之存取權的 Azure DevOps 專案,這些連線是在 Azure Pipelines 與外部或遠端服務之間建立的驗證連線。

  • 針對前一點所述的 Azure DevOps 專案安裝的 1.15 AWS Toolkit for Azure DevOps 版或更新版本。如需安裝說明,請參閱 Visual Studio Marketplace AWS Toolkit for Azure DevOps中的 。

限制

架構

此模式會建立下列項目:

  • Amazon ECR 儲存庫 - Amazon Elastic Container Registry (Amazon ECR) 儲存庫會將 Docker 映像與 Azure DevOps 代理程式和部署的範例應用程式一起存放。

  • Azure DevOps 代理程式集區 - Azure DevOps 自我託管代理程式集區會註冊在私有 Amazon EKS 叢集上執行的代理程式。

  • IAM 角色 - Azure 服務連線的 AWS Identity and Access Management (IAM) 角色,可提供對私有 Amazon EKS 叢集上執行之代理程式的必要存取權。

  • Azure DevOps 服務連線 - Azure DevOps 帳戶中的服務連線,可使用 IAM 角色,為管道任務提供存取所需的存取權 AWS 服務。

下圖顯示在私有 Amazon EKS 叢集上部署自我託管 Azure DevOps 代理程式,以及在同一叢集上部署範例應用程式的架構。

部署私有 Amazon EKS 叢集上的自我託管 Azure DevOps 代理程式和範例應用程式。

該圖顯示以下工作流程:

  1. 將自我託管 Azure DevOps 代理程式部署為 Amazon EKS 叢集內的部署。

  2. Azure DevOps 代理程式會使用個人存取字符 (PAT) 進行身分驗證,連線到 Azure DevOps 帳戶上的代理程式集區。

  3. Azure Pipelines 會使用來自 GitHub 儲存庫的程式碼來設定要部署的管道。

  4. 管道會從管道組態中設定的代理程式集區在代理程式上執行。Azure DevOps 代理程式會持續輪詢至 Azure DevOps 帳戶,以取得管道的任務資訊。

  5. Azure DevOps 代理程式會在管道任務中建置 Docker 映像,並將映像推送至 Amazon ECR 儲存庫。

  6. Azure DevOps 代理程式會將範例應用程式部署在名為 的命名空間中的私有 Amazon EKS 叢集上webapp

工具

工具

其他工具

  • Docker 是一組平台即服務 (PaaS) 產品,可在作業系統層級使用虛擬化在容器中交付軟體。

  • kubectl 是一種命令列界面,可協助您針對 Kubernetes 叢集執行命令。

程式碼儲存庫

最佳實務

史詩

任務描述所需的技能

尋找 Azure DevOps 組織 GUID。

登入您的 Azure DevOps 帳戶,然後使用下列 URL 來尋找組織 GUID:在 URL https://dev.azure.com/{DevOps_Org_ID}/_apis/projectCollections?api-version=6.0 中,將 取代{DevOps_org_ID}為您的 Azure DevOps 組織 ID。

AWS DevOps

在 中設定 IdP AWS 帳戶。

若要在 中設定 Azure 服務連線 AWS 帳戶 的身分提供者 (IdP),請使用下列步驟:

  1. 登入 AWS Management Console,並在 https://https://console.aws.amazon.com/iam/ 開啟 IAM 主控台。

  2. 在左側窗格中,選擇身分提供者

  3. 選擇 Add Provider (新增提供商)。

  4. 選擇 OpenID Connect 作為提供者類型

  5. 針對提供者 URL,輸入 Azure DevOps 發行者 URL。Azure DevOps 的每個租用戶都有一個唯一OrganizationGUID,通常使用以下格式:將 https://vstoken.dev.azure.com/{OrganizationGUID} 取代{OrganizationGUID}為您的 Azure DevOps 組織 ID。

  6. 針對對象,輸入 api://AzureADTokenExchange。這是 Azure DevOps 的固定值。

  7. 選擇 Add Provider (新增提供商)。

  8. 請記下新建立供應商的 ARN,以供您在下一個任務中使用。

如需詳細資訊,請參閱如何使用 OpenID Connect AWS 從 Azure DevOps 聯合到

AWS DevOps

在 中建立 IAM 政策 AWS 帳戶。

若要建立 IAM 政策,為 Azure DevOps 管道使用的 IAM 角色提供必要的許可,請使用下列步驟:

  1. 在 IAM 主控台的左側窗格中,選擇政策

  2. 選擇建立政策

  3. 對於指定許可,在政策編輯器中,選取 JSON。使用下列 JSON 取代預設 JSON 政策:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Action": [ "ecr:*", "eks:DescribeCluster", "eks:ListClusters" ], "Resource": "*" } ] }
  4. 選擇下一步

  5. 政策名稱中,輸入 IAM 政策的名稱。此模式使用名稱 ADO-policy

  6. 選擇建立政策

AWS DevOps

在 中建立 IAM 角色 AWS 帳戶。

若要在 中 AWS 帳戶 為 Azure 服務連線設定 IAM 角色,請使用下列步驟:

  1. 在 IAM 主控台的左側窗格中,選擇角色

  2. 選擇建立角色

  3. 針對信任的實體類型,選取 Web Identity

  4. 從下拉式清單中選取正確的 IdP。IdP 名稱以 開頭vstoken.dev.azure.com/{OrganizationGUID}

  5. 對象下拉式清單中,選取 api://AzureADTokenExchange

  6. 若要將此角色限制為僅一個服務連線,請新增條件。在條件下,選取新增條件,然後針對金鑰選取 vstoken.dev.azure.com/{OrganizationGUID}:sub。在條件中,選取 StringEquals。對於,請使用下列格式:sc://{OrganizationName}/{ProjectName}/{ServiceConnectionName}。對於 ServiceConnectionName,請使用 aws-sc。您將在下一個任務中建立此服務連線。

  7. 選擇下一步

  8. 針對新增許可,選取 ADO-policy,這是您在上一個任務中建立的政策。

  9. 選擇下一步,然後在角色名稱中輸入 ado-role。對於選取信任的實體,請使用下列信任政策:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::{account_id}:oidc-provider/vstoken.dev.azure.com/{OrganizationGUID}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "vstoken.dev.azure.com/{OrganizationGUID}:aud": "api://AzureADTokenExchange", "vstoken.dev.azure.com/{OrganizationGUID}:sub": "sc://{OrganizationName}/{ProjectName}/{ServiceConnectionName}" } } } ] }

在政策中,提供下列預留位置的資訊:

  • {account_id} - AWS 帳戶 ID

  • {OrganizationGUID} - Azure DevOps Organization GUID

  • {OrganizationName} - Azure DevOps Organization 名稱

  • {ProjectName} - Azure DevOps 專案名稱

  • {ServiceConnectionName} - Azure DevOps 服務連線名稱。使用 aws-sc。您將在下一個任務中建立此服務連線。

AWS DevOps

在 Azure DevOps 帳戶中建立服務連線。

若要設定 Azure 服務連線,請使用下列步驟:

  1. 在 Azure DevOps 專案中,選取專案設定服務連線

  2. 選擇新增服務連線,選取服務連線的類型做為 aws,然後選取下一步

  3. 針對要擔任的角色,輸入 IAM 角色 ado-role 的 arn。您已在先前的任務中建立 ado-role 在 中建立 IAM 角色 AWS 帳戶

  4. 選取使用 OIDC 核取方塊。

  5. 針對服務連線名稱,在任務屬性中輸入 aws-sc

  6. 選擇儲存

如需詳細資訊,請參閱 Microsoft 文件中的建立服務連線

AWS DevOps

將 IAM 角色新增至 Amazon EKS 組態檔案。

IAM 角色必須具有必要的許可,才能在 Amazon EKS 叢集上執行必要的操作。由於它是管道角色,IAM 角色必須能夠管理叢集上幾乎所有類型的資源。因此,system:masters群組許可適用於此角色。

若要將必要的組態新增至 Kubernetes aws-auth ConfigMap中的 ,請使用下列程式碼:

- groups: - system:masters rolearn: arn:aws:iam::{account_id}:role/ADO-role username: ADO-role

{account_id} 以您的 AWS 帳戶 ID 取代 。

如需詳細資訊,請參閱 Amazon EKS 文件中的 Amazon EKS 如何與 IAM 搭配使用

AWS DevOps
任務描述所需的技能

建立自我託管代理程式集區。

若要在 Azure DevOps 帳戶中設定自我託管代理程式集區,請使用下列步驟:

  1. 登入 Azure DevOps 帳戶組織。

  2. 選擇 Azure DevOps Organization

  3. 選擇您的 Azure DevOps 專案。

  4. 選擇 Project settings (專案設定)

  5. 選擇客服人員集區

  6. 選擇新增集區

  7. 選取自我託管

  8. 名稱中,輸入 eks-agent

  9. 選取授予所有管道的存取許可核取方塊。

  10. 選擇建立

如需詳細資訊,請參閱 Microsoft 文件中的建立和管理代理程式集區。

任務描述所需的技能

建立 Amazon ECR 儲存庫。

用於在私有 Amazon EKS 叢集上部署 Azure DevOps 代理程式和範例應用程式 (webapp) 的 Docker 映像必須存放在 Amazon ECR 儲存庫中。若要建立 Amazon ECR 儲存庫,請使用下列步驟:

  1. https://console.aws.amazon.com/ecr/repositories 開啟 Amazon ECR 主控台。

  2. 從導覽列中,選擇要AWS 區域在其中建立儲存庫的 。

  3. 儲存庫頁面上,選擇私有儲存庫,然後選擇建立儲存庫

  4. 針對儲存庫名稱,輸入 webapp。若要讓此模式中的範例應用程式正常運作,Amazon ECR 儲存庫名稱必須使用 webapp。如果您為儲存庫使用不同的名稱,請參閱故障診斷

如需詳細資訊,請參閱 Amazon ECR 文件中的建立 Amazon ECR 私有儲存庫以存放映像

AWS DevOps

建立 Dockerfile 以建置 Azure DevOps 代理程式。

建立 Dockerfile 以建置已安裝 Azure DevOps 代理程式的 Docker 映像。將下列內容存放在名為 的檔案中Dockerfile

FROM ubuntu:22.04 ENV TARGETARCH="linux-x64" RUN apt update && apt upgrade -y && apt install -y curl git jq libicu70 unzip wget RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" RUN unzip awscliv2.zip RUN ./aws/install RUN rm -rf aws awscliv2.zip RUN curl -sSL https://get.docker.com/ | sh RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash RUN mkdir -p azp WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent RUN groupadd -f docker RUN usermod -aG docker agent USER agent ENTRYPOINT [ "./start.sh" ]
AWS DevOps

建立 Azure DevOps 代理程式的指令碼。

若要建立start.sh指令碼,請使用下列步驟:

  1. 前往 Microsoft 文件中的建立和建置 Dockerfile 程序,然後捲動至步驟 5。將下列內容儲存至 ~/azp-agent-in-docker/start.sh,請務必使用 Unix 樣式 (LF) 行尾

  2. 複製指令碼的內容,並將其儲存在與 Dockerfile start.sh 相同的目錄中名為 的檔案中。

AWS DevOps

使用 Azure DevOps 代理程式建置 Docker 映像。

若要建立 Docker 映像以安裝 Azure DevOps 代理程式,請使用您先前建立的 Dockerfile 來建置映像。在存放 Dockerfile 的相同目錄中,執行下列命令:

aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com docker build --platform linux/amd64 -t ado-agent:latest . docker tag ado-agent:latest aws_account_id.dkr.ecr.region.amazonaws.com/webapp:latest docker push aws_account_id.dkr.ecr.region.amazonaws.com/webapp:latest

aws_account_id和 取代region為您的 AWS 帳戶 ID 和 AWS 區域。

AWS DevOps
任務描述所需的技能

產生 Azure 個人存取字符。

在私有 Amazon EKS 叢集上執行的代理程式需要個人存取字符 (PAT),以便可以向 Azure DevOps 帳戶進行身分驗證。若要產生 PAT,請使用下列步驟:

  1. 使用您計劃在 Azure DevOps 組織中使用的使用者帳戶登入 (https://dev.azure.com/{Your_Organization})。

  1. 從您的首頁開啟您的使用者設定,然後選取個人存取字符

  2. 選擇新權杖。

  3. 輸入字符的名稱

  4. 選擇顯示所有範圍。

  5. 對於客服人員集區,選取讀取和管理核取方塊。

  6. 選擇建立

  7. 若要在私有 Amazon EKS 叢集上建立秘密,請使用下列組態:

apiVersion: v1 kind: Secret metadata: name: azdevops-pat namespace: default type: Opaque stringData: AZP_TOKEN: <PAT Token>
  1. 將組態儲存在名為 的檔案中ado-secret.yaml<PAT Token> 將 取代為您剛建立的個人存取字符。若要建立秘密,請執行下列命令:

kubectl create -f ado-secret.yaml

如需詳細資訊,請參閱 Microsoft 文件中的使用個人存取字符 (PAT) 註冊代理程式。

AWS DevOps

使用 Kubernetes 資訊清單檔案進行代理程式部署。

若要在私有 Amazon EKS 叢集上部署 Azure DevOps 代理程式,請複製下列資訊清單檔案,並將檔案儲存為 agent-deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: azure-pipelines-agent-eks labels: app: azure-pipelines-agent spec: replicas: 1 selector: matchLabels: app: azure-pipelines-agent template: metadata: labels: app: azure-pipelines-agent spec: containers: - name: docker image: docker:dind securityContext: privileged: true volumeMounts: - name: shared-workspace mountPath: /workspace - name: dind-storage mountPath: /var/lib/docker env: - name: DOCKER_TLS_CERTDIR value: "" - name: azure-pipelines-agent image: aws_account_id.dkr.ecr.region.amazonaws.com/webapp:latest env: - name: AZP_URL value: "<Azure account URL>" - name: AZP_POOL value: "eks-agent" - name: AZP_TOKEN valueFrom: secretKeyRef: name: azdevops-pat key: AZP_TOKEN - name: AZP_AGENT_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: DOCKER_HOST value: tcp://localhost:2375 volumeMounts: - mountPath: /workspace name: shared-workspace volumes: - name: dind-storage emptyDir: {} - name: shared-workspace emptyDir: {}

aws_account_id 和 取代<Azure account URL>為您的 AWS 帳戶 ID 和 Azure DevOps 帳戶 URL。

AWS DevOps

在私有 Amazon EKS 叢集上部署代理程式。

若要在私有 Amazon EKS 叢集上部署 Azure Devops 代理程式,請使用下列命令:

kubectl create -f agent-deployment.tf
AWS DevOps

驗證代理程式是否正在執行。

若要驗證 Azure DevOps 代理程式是否正在執行,請使用下列命令:

kubectl get deploy azure-pipelines-agent-eks

預期的輸出應類似於以下內容:

NAME READY UP-TO-DATE AVAILABLE AGE azure-pipelines-agent-eks 1/1 1 1 58s

請確定資料READY 欄顯示 1/1

AWS DevOps

確認代理程式已向 Azure DevOps 代理程式集區註冊。

若要確認代理程式已部署在私有 Amazon EKS 叢集上,並已向代理程式集區 註冊eks-agent,請使用下列步驟:

  1. 登入 Azure DevOps 組織 (https://dev.azure.com/{Your_Organization})。

  2. 選擇 Project settings (專案設定)

  3. 選擇客服人員集區

  4. 選取 eks-agent 集區,然後檢查 Agents 索引標籤。

您應該會看到一個以線上狀態列出的代理程式,而代理程式的名稱應以 azure-pipelines-agent-eks-* 開頭。

AWS DevOps
任務描述所需的技能

將範例應用程式儲存庫授與您的 GitHub 帳戶。

將下列 AWS 範例儲存庫授與您的 GitHub 帳戶:

https://github.com/aws-samples/deploy-kubernetes-resources-to-amazon-eks-using-azure-devops

AWS DevOps

建立管道。

若要在您的 Azure DevOps 帳戶中建立管道,請使用下列步驟:

  1. 使用您計劃在 Azure DevOps 組織中使用的使用者帳戶登入 (https://dev.azure.com/{Your_Organization})。

  2. 導覽至您的專案和管道主控台。

  3. 選擇新管道。

  4. 針對您的程式碼所在位置,選擇 GitHub。

  5. 提供管道連線至 GitHub 帳戶所需的登入資料

  6. 選取儲存庫 deploy-kubernetes-resources-to-amazon-eks-using-azure-devops

  7. 針對設定管道,選取現有的 Azure 管道 YAML 檔案

  8. 針對選取現有的 YAML 檔案,選取分支的主要 ,以及選取路徑的主要 azure_pipelines.yaml

  9. 選擇繼續

  10. 對於檢閱管道 YAML,請以awsEKSClusterName您的資訊取代 awsRegion和 的輸入參數值:

pool: name: eks-agent #pool: self-hosted # If you are running self-hosted Azure DevOps Agents stages: # Refering the pipeline template, input parameter that are not specified will be added with defaults - template: ./pipeline_templates/main_template.yaml parameters: serviceConnectionName: aws-sc awsRegion: <your region> awsEKSClusterName: <name of your EKS cluster> projectName: webapp
  1. 選擇 RUN

AWS DevOps

確認範例應用程式已部署。

管道完成後,請檢查 Amazon ECR 儲存庫和 Amazon EKS 叢集,以驗證範例應用程式是否成功部署。

若要驗證 Amazon ECR 儲存庫中的成品,請使用下列步驟:

  1. 導覽至 webapp Amazon ECR 儲存庫。

  2. 確認下列新成品是否存在:

  • Docker 映像 – <date>.<build_number>-image

  • Helm Chart – <date>.<build_number>-helm

例如,20250501.1-image20250501.1-helm

若要驗證命名空間 中私有 Amazon EKS 叢集上的部署webapp,請使用下列命令:

kubectl get deploy -n webapp

預期的輸出如下:

NAME READY UP-TO-DATE AVAILABLE webapp 1/1 1 1

注意:如果這是您的第一個管道執行,您可能需要授權服務連線和代理程式集區。在 Azure DevOps 管道界面中尋找許可請求,並核准它們以繼續。

AWS DevOps

故障診斷

問題解決方案

當 Amazon ECR 儲存庫名稱不相符時管道失敗 webapp

範例應用程式預期 Amazon ECR 儲存庫名稱符合 中的 projectName: webapp 參數azure_pipeline.yml

若要解決此問題,請將 Amazon ECR 儲存庫重新命名為 webapp,或更新下列項目:

  • 重新命名分支 GitHub 儲存庫中的webapp目錄,以符合您的 Amazon ECR 儲存庫名稱。

  • 更新 中的 projectName 參數azure_pipeline.yml,以符合您的 Amazon ECR 儲存庫名稱。

錯誤:Kubernetes 叢集無法連線:伺服器已要求用戶端提供登入資料

如果您在 Azure 管道的「提取和部署 Helm Chart」步驟中遇到此錯誤,根本原因通常是來自 Amazon EKS 叢集 中的不正確 IAM 角色組態aws-auth ConfigMap

若要解決此問題,請檢查下列項目:

  • 驗證您的aws-auth ConfigMap組態。

  • 檢查 Amazon EKS 叢集的身分驗證設定:開啟 Amazon EKS 主控台、叢集詳細資訊存取組態。確定身分驗證模式設定為 EKS API 和 ConfigMap (而不只是 EKS API)。

相關資源

AWS 部落格

AWS 服務 文件

Microsoft 文件