【问题标题】:Get output from Azure DevOps Deploy to Kubernetes task从 Azure DevOps Deploy to Kubernetes 任务获取输出
【发布时间】:2019-06-20 13:08:24
【问题描述】:

设置说明

我有以下场景:在 Azure DevOps 中创建了一个构建管道,在设置我的 Kubernetes 集群后,我想使用 kubectl 获取特定的 pod 名称。我通过“部署到 Kubernetes”任务 V1 执行此操作,如下所示:

steps:
- task: Kubernetes@1

  displayName: 'Get pod name'
  inputs:
    azureSubscriptionEndpoint: 'Azure Pay-as-you-Go (anonymized)'
    azureResourceGroup: MyK8sDEV
    kubernetesCluster: myCluster
    command: get
    arguments: 'pods -l "app=hlf-ca,release=ca" -o jsonpath="{.items[0].metadata.name}"'

所以任务运行成功,我想得到上面命令的输出字符串。在 Pipeline 可视化设计器中,它向我显示了一个正在写入的 undefined.KubectlOutput 输出变量。

问题陈述

我在上面的 kubectl 任务之后直接创建了一个后续的 Bash 脚本任务。如果我读取变量 $KUBECTLOUTPUT 或 $UNDEFINED_KUBECTLOUTPUT 它只会返回一个空字符串。我究竟做错了什么?我只需要上一个命令的输出作为变量。

我的行动目标

我正在尝试确保我在上一步中使用 helm 图表部署的应用程序已启动并正在运行。在下一步中,我需要在应用程序 pod 中运行一些脚本(使用 kubectl exec),因此我想确保至少 1 个托管应用程序的 pod 已启动并运行,以便我可以对其执行命令。与此同时,我意识到如果在部署 helm chart 时使用 --wait 标志,我可以跳过检查步骤,但我仍然在 bash 脚本中使用 kubectl 时遇到问题。

【问题讨论】:

  • 你能退后一步,描述一下你想要达到的目标吗
  • 当然,我正在努力确保我在上一步中使用 helm 图表部署的应用程序已启动并正在运行。在下一步中,我需要在应用程序 pod 中运行一些脚本(使用 kubectl exec),因此我要确保至少 1 个托管应用程序的 pod 已启动并运行,以便我可以对其执行命令。
  • 您为什么不想一口气完成所有操作?所以你不必在步骤之间传递变量?
  • 如果我知道怎么做,我会很乐意这样做,因为我以后的管道需要几个额外的这样的步骤,所以我会付出相当多的努力。我可以通过以某种方式或使用 kubernetes 自己的方法参数化掌舵图来做到这一点吗?

标签: kubernetes azure-devops


【解决方案1】:

这是我一直在使用的:

config=`find . -name config`

kubectl --kubeconfig $config get -n $(k8sEnv) deploy --selector=type=$(containerType) -o | jq '.items[].metadata.name' \
  | xargs -L 1 -i kubectl --kubeconfig $config set -n $(k8sEnv) image deploy/{} containername=registry.azurecr.io/$(containerImage):$(BUILD.BUILDNUMBER) --record=true

这将找到具有特定标签的所有部署并在每个部署上运行 kubectl set,您可以轻松地根据自己的需要进行调整。唯一的先决条件,您必须在此任务之前拥有 kubectl 任务,因此您的代理会从 Azure Devops 下载 kubectl 配置。
上面的这个必须在这个目录中运行:

/home/vsts/work/_temp/kubectlTask

【讨论】:

  • 感谢您的指点,但是找不到配置文件。我已经尝试了一段时间,但我只能得到一个 Visual Studio 配置文件或 git 配置文件作为查找结果。将工作目录更改为 /home/vsts/work/_temp/kubectlTask​​ 不会带来任何东西。我检查了该文件夹,它只包含两个名称神秘的文件:1548619950257 和 1548619970089。按照您的建议,我在脚本任务之前放置了一个 kubectl 任务。接下来我应该看哪里?
  • 您是否使用最新的 kubectl 任务版本,如果没有,请尝试使用它?您可以扩大搜索范围,只需执行 find / -name config 或尝试使用诊断日志记录运行构建,看看您是否可以发现 kubectl 任务从哪里放置(或获取)其配置
  • 我试图扩大搜索范围并研究 kubectl 任务本身如何访问集群(请参阅下面的详细帖子),但除非我明确使用 az aks get-credentials,否则不会编写配置文件在我的脚本中。之后它似乎确实有效,但我对微软托管代理的配置文件中未加密的访问数据感到不安。
【解决方案2】:

如果您为 kubectl 任务提供名称,例如。 SomeNameForYourTask 如下所示

- task: Kubernetes@1
   name: SomeNameForYourTask 
   displayName: some display name
   inputs:
     connectionType: Kubernetes Service Connection
  ...

您将能够使用

访问 kubectl 命令输出
echo $(SomeNameForYourTask.KubectlOutput)

或

echo $(SomeNameForYourTask.KUBECTLOUTPUT)

或

echo $SOMENAMEFORYOURTASK_KUBECTLOUTPUT

在以下脚本任务中。当然,输出不应超过 32766 个字符(根据代码https://github.com/microsoft/azure-pipelines-tasks/blob/b0e99b6d8c7d1b8eba65d9ec08c118832a5635e3/Tasks/KubernetesV1/src/kubernetes.ts)。

【讨论】:

    【解决方案3】:

    经过几个小时的不同尝试来弄清楚 azure devops 如何连接到 AKS 集群,据我所知,我发现它正在使用 OAuth 访问令牌。可以使用 System.AccessToken 变量访问此令牌(如果允许代理作业访问令牌 - 这是一个配置选项,默认情况下它是关闭的)。我想不通的是如何在脚本中使用这个令牌和 kubectl,所以我暂时放弃了这条路。

    此外,该作业在托管的 Ubuntu 代理(如 Microsoft 托管)上运行,因此出于安全原因,它可能会避免下载配置文件,尽管 Microsoft 自己坚持认为代理是一次性 VM,并且“虚拟机器在使用一次后被丢弃”see MS docs here。

    托管代理的工作原理(我仍然建议对生产场景进行一些加密) - 使用 azure CLI 命令登录并获取集群凭据:

    az login
    az aks get-credentials --resource-group=MyClusterDEV --name myCluster
    kubectl […]
    

    我使用的替代解决方案是在已经预先配置了 Kubernetes 配置文件的本地代理上运行脚本。为此,我只是创建了一个额外的代理作业来运行我的脚本,所以现在我有了:

    1. 执行 helm init 和其他基本设置任务的一般代理作业(托管 Ubuntu 16)
    2. 针对特定 pod 运行更复杂脚本的本地代理作业 (Windows)

    【讨论】:

      猜你喜欢
      • 2022-10-20
      • 2020-07-18
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      • 2019-05-12
      • 2019-09-01
      • 2020-10-07
      • 1970-01-01
      相关资源
      最近更新 更多