0

checkout scm由于两个问题,我在管道中使用时遇到错误。

设置:

  • 私有 Kubernetes 集群 - 1 个控制器,2 个工作器,在 Ubuntu 20.04 虚拟机上
  • Jenkins 在 Kubernetes pod 中运行
  • Kubernetes 插件实例化 Jenkins 构建代理
  • 集群外控制器 VM 上的私有 GIT 服务器,ssh 访问
  • 在 Jenkins 凭证中配置的 GIT 的 ssh 私钥
  • Jenkins 项目 'hello' 配置为使用此私有 GIT 和关联的 ssh 密钥
  • Jenkinsfile(管道)构建

我想checkout scm在 Jenkinsfile 中使用一个简单的步骤。

问题 1构建失败,Host key verification failed.因为 Kubernetes 代理 pod 的known_hosts.

问题 2如果我强制控制器证书进入known_hosts(例如,将 echo 硬编码到 Jenkinsfile 中,然后添加一个git ls-remote步骤),它会失败,Permission denied因为代理 pod 中不存在配置的 ssh 私钥。

我找到了解决这两种方法的方法:

podTemplate(
...
{
  node(POD_LABEL) {
    stage('Checkout') {
      withCredentials([sshUserPrivateKey(
          credentialsId: 'private_git', 
          keyFileVariable: 'PRIVATE_GIT_KEY',
          passphraseVariable: '',
          usernameVariable: ''
      )]) {
        sh 'mkdir -p ~/.ssh'
        sh 'cp $PRIVATE_GIT_KEY ~/.ssh/id_rsa'
        sh '/usr/bin/ssh-keyscan -t rsa kube-master.cluster.dev >> ~/.ssh/known_hosts'
        sh 'chown -R $USER:$USER ~/.ssh'
        sh '/usr/bin/git ls-remote ssh://git@kube-master.cluster.dev:/git/hello.git'
      }
      checkout scm
    }
  ...
  }
}

我需要什么来避免这种解决方法并按checkout scm预期使用?

失败日志示例:

Running on build-pod-xdh86-53wh7 in /home/jenkins/agent/workspace/hello
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Checkout)
[Pipeline] checkout
Selected Git installation does not exist. Using Default
The recommended git tool is: NONE
using credential private_git
Cloning the remote Git repository
ERROR: Error cloning remote repo 'origin'
hudson.plugins.git.GitException: Command "git fetch --tags --force --progress -- ssh://git@kube-master.cluster.dev/git/hello.git +refs/heads/*:refs/remotes/origin/*" returned status code 128:
stdout: 
stderr: Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
4

1 回答 1

0

一个合理的解决方案是将密钥放在 Kubernetes Secret 中,并将 Secret 挂载到 Jenkins pod 中。

在您的控制器机器上:

  1. 创建一个临时用户帐户并进入其中

  2. 制作秘密(典型的 ssh-keygen)

  3. 添加id_rsa.pub到 git 服务器authorized_users

  4. 连接到 git ssh 一次即可生产known_hosts,例如

    git ls-remote ssh://git@kube-master.cluster.dev:/git/hello.git

  5. 将scratch用户的~/.ssh/id_rsa私钥和~/.ssh/known_hosts文件复制到kubectl可以读取的地方,比如/tmp/scratchuser

  6. 退出临时用户帐户并将其删除

  7. sudo chown -R $USER:$USER /tmp/scratchuser/

  8. id_rsa使用类似的命令将and添加known_hosts到 Kubernetes

    kubectl create secret -n jenkins generic private-git --from-file=id_rsa=/tmp/scratchuser/.ssh/id_rsa --from-file=known_hosts=/tmp/scratchuser/.ssh/known_hosts

  9. 使用包含一些特定内容的 yaml 部署 Jenkins:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: jenkins
      namespace: jenkins
    spec:
      ... your other options such as replicas, selector, etc ...
      template:
        metadata: ... your metadata section ...
        spec:
          securityContext:
            fsGroup: 1000
          containers:
          - name: jenkins
            image: jenkins/jenkins:lts
            ports:
              ... standard jenkins ports ...
            volumeMounts:
              - name: jenkins-vol
                mountPath: /var/jenkins_home
              - name: private-git-vol
                mountPath: "/var/jenkins_home/.ssh"
                readOnly: true
          volumes:
            - name: jenkins-vol
              ... your persistent volume details ...
            - name: private-git-vol
              secret:
                secretName: private-git
                defaultMode: 0600
          ... your other options such as dnsPolicy, etc. ...
    

上面 yaml 中的关键点是fsGroup让 pod 用户jenkins可以访问挂载的秘密卷,private-git-vol将秘密文件放入.ssh路径的挂载,以及private-git-vol引用上面创建的秘密的定义kubectl

再来一个提示。对于Jenkinsfile实例化构建代理 pod,请参阅声明式管道。您可能需要完全放弃podTemplate()并指定代理 pod yaml:

pipeline {
  agent {
    kubernetes {
      yamlFile 'KubernetesPod.yaml'
    }
  ... your build steps ...
}

并在 中KubernetesPod.yaml,使用您自己的 yaml 包含jnlp容器(jenkins/inbound-agent图像)而不是 Kubernetes 插件。这将允许您fsGroup在构建代理中使用,就像上面针对 Jenkins 主服务器所描述的那样。

于 2021-05-05T15:48:08.057 回答