Azure DevOps:如何让单次安装的程序在所有阶段可用?
问题描述
我们在Azure DevOps中使用阶段功能,运行流水线时可选择要执行的阶段,但存在一个问题:在Stage 1中安装的程序无法在Stage 2中使用。
请问是否有办法仅安装一次程序,使其在所有阶段中都可用?
需求示例:
- 在Stage 1中安装kubectl
- 在Stage 2中使用kubectl
原流水线YAML:
trigger: - master pool: vmImage: ubuntu-22.04 stages: - stage: MakeK8sConfiguration jobs: - job: MakeK8sConfiguration steps: - script: | # 下载kubectl curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" # 安装kubectl sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl - stage: MakeK8sDeployment jobs: - job: MakeK8sDeployment steps: - script: | # 运行kubectl kubectl
解决方案
Azure DevOps的不同阶段默认会使用独立的代理机器(或容器),阶段间的运行环境完全隔离,所以直接在某一阶段安装的工具无法自动共享到其他阶段。要实现一次安装跨阶段可用,有两种实用方案:
方案1:使用作业级别缓存(推荐)
将安装好的kubectl缓存到流水线的共享存储中,后续阶段/作业可直接恢复缓存并使用,无需重复下载安装。
修改后的YAML示例:
trigger: - master pool: vmImage: ubuntu-22.04 stages: - stage: MakeK8sConfiguration jobs: - job: MakeK8sConfiguration steps: - script: | # 创建缓存目录 mkdir -p $(Pipeline.Workspace)/kubectl # 下载kubectl curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" # 赋予执行权限并移动到缓存目录 chmod +x kubectl mv kubectl $(Pipeline.Workspace)/kubectl/ displayName: '下载并准备kubectl' # 将kubectl目录缓存到共享存储 - task: Cache@2 inputs: key: 'kubectl | "$(Agent.OS)"' path: '$(Pipeline.Workspace)/kubectl' displayName: '缓存kubectl' - stage: MakeK8sDeployment jobs: - job: MakeK8sDeployment steps: # 从共享存储恢复kubectl缓存 - task: Cache@2 inputs: key: 'kubectl | "$(Agent.OS)"' path: '$(Pipeline.Workspace)/kubectl' displayName: '恢复kubectl缓存' # 将kubectl所在目录添加到系统PATH,确保全局可调用 - script: | echo "##vso[task.prependpath]$(Pipeline.Workspace)/kubectl" displayName: '添加kubectl到系统PATH' - script: | # 验证kubectl可用 kubectl version --client displayName: '运行kubectl命令'
方案2:绑定同一代理机器
如果所有阶段必须在同一台代理机器上运行,可以指定固定代理或使用代理需求约束,让所有阶段复用同一台代理的环境。这种方式灵活性较低,仅适合私有代理场景。
修改示例(指定固定私有代理):
trigger: - master pool: name: '你的私有代理池名称' demands: Agent.Name -equals '固定代理机器名称' stages: - stage: MakeK8sConfiguration jobs: - job: MakeK8sConfiguration steps: - script: | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl displayName: '安装kubectl' - stage: MakeK8sDeployment jobs: - job: MakeK8sDeployment steps: - script: kubectl version --client displayName: '验证kubectl可用性'
注意事项
- 方案1的缓存会根据设定的
key判断是否需要更新,当代理操作系统或kubectl版本变化时,会自动重新下载并缓存。 - 不要依赖托管代理的持久化存储,Azure DevOps托管代理每次作业结束后都会重置环境,所有临时修改会被清除。
内容的提问来源于stack exchange,提问作者Esben Eickhardt
相关产品推荐
相关产品推荐

