K8S 上的 Jenkins - Kubernetes 秘密作为构建步骤环境变量

问题描述 投票:0回答:1

经过太多搜索后,我仍然不确定如何在声明性 Jenkins 管道中使用 K8S 密钥作为环境变量。我们尝试了几种不同的方法,包括以下方法。构建涉及设置一个 Python 容器,将 Python 轮子推送到我们的私有 ECR 注册表。

build_pod_config = '''
apiVersion: "v1"
kind: "Pod"
metadata:
  namespace: "jenkins"
spec:
  containers:
    # ...
    - name: 'python'
      image: '870326185936.dkr.ecr.us-east-2.amazonaws.com/605data/build-tools-python:3.12'
      command:
        - 'sleep'
      args:
        - 'infinity'
      env:  
        - name: PYPI_PWD
          valueFrom:
            secretKeyRef:
              name: 'secret-credentials'
              key: 'pypi-admin-pwd'
   # ... 

  nodeSelector:
    kubernetes.io/os: "linux"
  restartPolicy: "Never"
  securityContext:
    fsGroup: 1000
    runAsGroup: 1000
    runAsUser: 1000
  serviceAccountName: "dev-jenkins"
  volumes:
   # ...
'''
pipeline {
  agent {
    kubernetes {
      yaml build_pod_config
      defaultContainer 'python'
    }
  }  // agent

  stages {
    stage("Setup") {
      steps {
        script {
          // we don't clone here, the job definition handles everything
          this_branch = "${GIT_BRANCH}".trim()
          echo "Building branch ${this_branch}..."
          currentBuild.displayName = "${this_branch}"
          push_branches = [
              "origin/master"
          ]
        }
      }
    }

    // ...

    stage("Publish") {
      when {
        expression { push_branches.contains(this_branch) }
      }
      steps {
        echo "Pushing wheel and Docker image"
        container("python") {
          echo "Pushing wheel, src distributions to PyPi"
          // From the Kubernetes plugin, but currently not working
          secretEnvVar(key: 'PYPI_PWD', secretName: 'secret-credentials', secretKey: 'pypi-pwd', optional: false) {
            // sh("""python -m pip install '.[publish]'""")
            sh("""python -m twine upload --repository-url https://pypi.shared-services.605.nu dist/* --user admin --password ${PYPI_PWD}""")
          }
        }
      }
    }
  }

  post {
    // ...
  }
}

问题是,虽然上面的 K8S 秘密值在 Python 容器中显示为环境变量,但在将轮子推向注册表的管道步骤中无法使用它。我们希望在我们的管道中使用此类 K8S 秘密值作为环境变量。

我们已经尝试了所有能想到的或在网上找到的方法,但没有成功。 Jenkins Kubernetes 插件确实定义了“secretEnvVar”,但它似乎仅在脚本化管道中可用,而不是声明性管道。关于如何在我们的构建步骤中设置基于 K8S 秘密的环境变量有什么想法吗?

我们希望继续使用带有 YAML 构建 Pod 配置的声明式方法,因为我们有一些工具可以帮助用户创建此类管道。如果可能的话,我们也不希望涉及 Jenkins 凭证。

有什么想法吗?

kubernetes jenkins environment-variables pipeline
1个回答
0
投票

我有一种感觉,它确实有效,但不是以你期望的方式。根据管道类型,如果环境变量定义了两次,Jenkins 可以更改环境变量的名称。即使是声明式管道和声明式多分支管道在这方面的工作方式也不同。

为了确保这一点,您可以通过在容器中运行

printenv
来检查它。这些值可能会被屏蔽,但您很可能会看到类似这样的内容:

...
PYPI_PWD=*****
pypi_pwd=*****
...

无论如何,我不确定您是否需要使用

secretEnvVar
提取该环境变量 - 此外,如果我没记错(并阅读 docs),它甚至不会像那样工作,而是旨在当您没有 YAML 文件时构建 pod 模板。这种定义 pod 模板的方式已被弃用,取而代之的是 YAML、AFAIR。

因此,考虑到这一点,以及

twine upload
能够利用环境变量本身的事实,我会尝试 只需在 pod 模板中定义
TWINE_PASSWORD
环境变量,而不是自定义
PYPI_PWD
。这也更安全,因为您不使用 Groovy 字符串插值,这使得 CLI 上使用的秘密以纯文本形式提供:

build_pod_config = '''
apiVersion: "v1"
kind: "Pod"
metadata:
  namespace: "jenkins"
spec:
  containers:
    # ...
    - name: 'python'
      image: '870326185936.dkr.ecr.us-east-2.amazonaws.com/605data/build-tools-python:3.12'
      command:
        - 'sleep'
      args:
        - 'infinity'
      env:  
        - name: TWINE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: 'secret-credentials'
              key: 'pypi-admin-pwd'
   # ... 
'''
pipeline {
  agent {
    kubernetes {
      yaml build_pod_config
      defaultContainer 'python'
    }
  }  // agent

  stages {
    // I omitted the unrelated parts for brevity 
    // ...

    stage("Publish") {
      when {
        expression { push_branches.contains(this_branch) }
      }
      steps {
        echo "Pushing wheel and Docker image"
        container("python") {
          echo "Pushing wheel, src distributions to PyPi"
          sh 'python -m twine upload --repository-url https://pypi.shared-services.605.nu dist/* --user admin'         
        }
      }
    }
  }

  post {
    // ...
  }
}

您可以以相同的方式设置其他选项,这样您的 Pod 模板就可以与任何管道共享并随时可用,并且管道更简单。

旁注:您可以使用 label

 步骤的 
sh
 参数来避免混乱的 
echo
步骤。 Jenkins 将自动在构建日志中的命令日志前面添加以下文本:

sh script: 'python -m twine upload dist/*',
  label: 'Pushing wheel, src distributions to PyPi'
© www.soinside.com 2019 - 2024. All rights reserved.