Jenkins kubernetes 代理结帐 scm 未使用配置的密钥
Posted
技术标签:
【中文标题】Jenkins kubernetes 代理结帐 scm 未使用配置的密钥【英文标题】:Jenkins kubernetes agent checkout scm not using configured key 【发布时间】:2021-05-03 14:44:40 【问题描述】:由于两个问题,我在管道中使用 checkout scm
时遇到错误。
设置:
私有 Kubernetes 集群 - 1 个控制器,2 个工作器,在 Ubuntu 20.04 虚拟机上 在 Kubernetes pod 中运行的 Jenkins 用于实例化 Jenkins 构建代理的 Kubernetes 插件 集群外控制器 VM 上的私有 GIT 服务器,ssh 访问 在 Jenkins 凭据中配置的 GIT 的 ssh 私钥 Jenkins 项目“hello”配置为使用此私有 GIT 和关联的 ssh 密钥 要构建的 Jenkinsfile(管道)我想在 Jenkinsfile 中使用一个简单的checkout scm
步骤。
问题 1 构建失败并显示 Host key verification failed.
,因为 Kubernetes 代理 pod 在其 known_hosts
中没有 GIT 服务器。
问题 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.
【问题讨论】:
【参考方案1】:一个合理的解决方案是将密钥放在 Kubernetes secrets 中,并将 secrets 挂载到 Jenkins pod 中。
在您的控制器机器上:
创建一个临时用户帐户并进入其中
制作秘密(典型的 ssh-keygen)
将id_rsa.pub
添加到git服务器authorized_users
连接git ssh一次,产生known_hosts
,例如
git ls-remote ssh://git@kube-master.cluster.dev:/git/hello.git
将scratch用户的~/.ssh/id_rsa
私钥和~/.ssh/known_hosts
文件复制到kubectl可以读取的地方,比如/tmp/scratchuser
退出临时用户帐户并将其删除
sudo chown -R $USER:$USER /tmp/scratchuser/
将id_rsa
和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
使用包含一些特定内容的 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
创建的秘密的定义。
还有一个提示。有关实例化构建代理 pod 的 Jenkinsfile
,请参阅 Declarative Pipeline。您可能需要放弃 podTemplate()
并完全指定代理 pod yaml:
pipeline
agent
kubernetes
yamlFile 'KubernetesPod.yaml'
... your build steps ...
在KubernetesPod.yaml
中,将jnlp
容器(jenkins/inbound-agent
映像)包含在您自己的 yaml 中,而不是 Kubernetes 插件。这将允许您在构建代理中使用fsGroup
,就像上面针对 Jenkins 主服务器所描述的那样。
【讨论】:
以上是关于Jenkins kubernetes 代理结帐 scm 未使用配置的密钥的主要内容,如果未能解决你的问题,请参考以下文章
Jenkins-Kubernetes插件实现使用Pod作为 Agent-超详细
带有 git 私有仓库的 Jenkins kubernetes 插件