本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
將工作負載從 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 代理程式,以及在同一叢集上部署範例應用程式的架構。
該圖顯示以下工作流程:
將自我託管 Azure DevOps 代理程式部署為 Amazon EKS 叢集內的部署。
Azure DevOps 代理程式會使用個人存取字符 (PAT) 進行身分驗證,連線到 Azure DevOps 帳戶上的代理程式集區。
Azure Pipelines 會使用來自 GitHub 儲存庫的程式碼來設定要部署的管道。
管道會從管道組態中設定的代理程式集區在代理程式上執行。Azure DevOps 代理程式會持續輪詢至 Azure DevOps 帳戶,以取得管道的任務資訊。
Azure DevOps 代理程式會在管道任務中建置 Docker 映像,並將映像推送至 Amazon ECR 儲存庫。
Azure DevOps 代理程式會將範例應用程式部署在名為 的命名空間中的私有 Amazon EKS 叢集上webapp
。
工具
其他工具
程式碼儲存庫
最佳實務
史詩
任務 | 描述 | 所需的技能 |
---|
尋找 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),請使用下列步驟: 登入 AWS Management Console,並在 https://https://console.aws.amazon.com/iam/ 開啟 IAM 主控台。 在左側窗格中,選擇身分提供者。 選擇 Add Provider (新增提供商)。 選擇 OpenID Connect 作為提供者類型。 針對提供者 URL,輸入 Azure DevOps 發行者 URL。Azure DevOps 的每個租用戶都有一個唯一OrganizationGUID ,通常使用以下格式:將 https://vstoken.dev.azure.com/{OrganizationGUID} 取代{OrganizationGUID} 為您的 Azure DevOps 組織 ID。 針對對象,輸入 api://AzureADTokenExchange。這是 Azure DevOps 的固定值。 選擇 Add Provider (新增提供商)。 請記下新建立供應商的 ARN,以供您在下一個任務中使用。
如需詳細資訊,請參閱如何使用 OpenID Connect AWS 從 Azure DevOps 聯合到 。 | AWS DevOps |
在 中建立 IAM 政策 AWS 帳戶。 | 若要建立 IAM 政策,為 Azure DevOps 管道使用的 IAM 角色提供必要的許可,請使用下列步驟: 在 IAM 主控台的左側窗格中,選擇政策。 選擇建立政策。 對於指定許可,在政策編輯器中,選取 JSON。使用下列 JSON 取代預設 JSON 政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"ecr:*",
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
}
]
}
選擇下一步。 在政策名稱中,輸入 IAM 政策的名稱。此模式使用名稱 ADO-policy。 選擇建立政策。
| AWS DevOps |
在 中建立 IAM 角色 AWS 帳戶。 | 若要在 中 AWS 帳戶 為 Azure 服務連線設定 IAM 角色,請使用下列步驟: 在 IAM 主控台的左側窗格中,選擇角色。 選擇建立角色。 針對信任的實體類型,選取 Web Identity。 從下拉式清單中選取正確的 IdP。IdP 名稱以 開頭vstoken.dev.azure.com/{OrganizationGUID} 。 在對象下拉式清單中,選取 api://AzureADTokenExchange。 若要將此角色限制為僅一個服務連線,請新增條件。在條件下,選取新增條件,然後針對金鑰選取 vstoken.dev.azure.com/{OrganizationGUID}:sub。在條件中,選取 StringEquals。對於值,請使用下列格式:sc://{OrganizationName}/{ProjectName}/{ServiceConnectionName} 。對於 ServiceConnectionName ,請使用 aws-sc。您將在下一個任務中建立此服務連線。 選擇下一步。 針對新增許可,選取 ADO-policy,這是您在上一個任務中建立的政策。 選擇下一步,然後在角色名稱中輸入 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 服務連線,請使用下列步驟: 在 Azure DevOps 專案中,選取專案設定、服務連線。 選擇新增服務連線,選取服務連線的類型做為 aws ,然後選取下一步。 針對要擔任的角色,輸入 IAM 角色 ado-role 的 arn。您已在先前的任務中建立 ado-role 在 中建立 IAM 角色 AWS 帳戶。 選取使用 OIDC 核取方塊。 針對服務連線名稱,在任務屬性中輸入 aws-sc。 選擇儲存。
如需詳細資訊,請參閱 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 帳戶中設定自我託管代理程式集區,請使用下列步驟: 登入 Azure DevOps 帳戶組織。 選擇 Azure DevOps Organization。 選擇您的 Azure DevOps 專案。 選擇 Project settings (專案設定)。 選擇客服人員集區。 選擇新增集區。 選取自我託管。 在名稱中,輸入 eks-agent。 選取授予所有管道的存取許可核取方塊。 選擇建立。
如需詳細資訊,請參閱 Microsoft 文件中的建立和管理代理程式集區。 | |
任務 | 描述 | 所需的技能 |
---|
建立 Amazon ECR 儲存庫。 | 用於在私有 Amazon EKS 叢集上部署 Azure DevOps 代理程式和範例應用程式 (webapp ) 的 Docker 映像必須存放在 Amazon ECR 儲存庫中。若要建立 Amazon ECR 儲存庫,請使用下列步驟: 如需詳細資訊,請參閱 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 指令碼,請使用下列步驟: 前往 Microsoft 文件中的建立和建置 Dockerfile 程序,然後捲動至步驟 5。將下列內容儲存至 ~/azp-agent-in-docker/start.sh ,請務必使用 Unix 樣式 (LF) 行尾。 複製指令碼的內容,並將其儲存在與 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,請使用下列步驟: 使用您計劃在 Azure DevOps 組織中使用的使用者帳戶登入 (https://dev.azure.com/{Your_Organization} )。
從您的首頁開啟您的使用者設定,然後選取個人存取字符。 選擇新權杖。 輸入字符的名稱。 選擇顯示所有範圍。 對於客服人員集區,選取讀取和管理核取方塊。 選擇建立。 若要在私有 Amazon EKS 叢集上建立秘密,請使用下列組態:
apiVersion: v1
kind: Secret
metadata:
name: azdevops-pat
namespace: default
type: Opaque
stringData:
AZP_TOKEN: <PAT Token>
將組態儲存在名為 的檔案中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 ,請使用下列步驟: 登入 Azure DevOps 組織 (https://dev.azure.com/{Your_Organization} )。 選擇 Project settings (專案設定)。 選擇客服人員集區。 選取 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 帳戶中建立管道,請使用下列步驟: 使用您計劃在 Azure DevOps 組織中使用的使用者帳戶登入 (https://dev.azure.com/{Your_Organization} )。 導覽至您的專案和管道主控台。 選擇新管道。 針對您的程式碼所在位置,選擇 GitHub。 提供管道連線至 GitHub 帳戶所需的登入資料 選取儲存庫 deploy-kubernetes-resources-to-amazon-eks-using-azure-devops。 針對設定管道,選取現有的 Azure 管道 YAML 檔案。 針對選取現有的 YAML 檔案,選取分支的主要 ,以及選取路徑的主要 azure_pipelines.yaml。 選擇繼續。 對於檢閱管道 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
| AWS DevOps |
確認範例應用程式已部署。 | 管道完成後,請檢查 Amazon ECR 儲存庫和 Amazon EKS 叢集,以驗證範例應用程式是否成功部署。 若要驗證 Amazon ECR 儲存庫中的成品,請使用下列步驟: 導覽至 webapp Amazon ECR 儲存庫。 確認下列新成品是否存在:
例如,20250501.1-image 和 20250501.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 ,或更新下列項目: |
錯誤:Kubernetes 叢集無法連線:伺服器已要求用戶端提供登入資料 | 如果您在 Azure 管道的「提取和部署 Helm Chart」步驟中遇到此錯誤,根本原因通常是來自 Amazon EKS 叢集 中的不正確 IAM 角色組態aws-auth ConfigMap 。 若要解決此問題,請檢查下列項目: |
相關資源
AWS 部落格
AWS 服務 文件
Microsoft 文件