【问题标题】:Calling Git in Jenkins build script in Docker在 Docker 的 Jenkins 构建脚本中调用 Git
【发布时间】:2017-04-26 01:25:01
【问题描述】:

我有一个用于 Jekyll 网站(GH 页面)的构建脚本,该脚本需要调用 git 命令,这些命令需要从脚本内部进行 Github 身份验证。这是脚本:

#!/usr/bin/env bash

rm -rf _site/

git clone git@github.com:RIT-EVT/RIT-EVT.github.io.git --branch master --depth 1 _site

LIVE_VERSION_BUILD=`cat _site/version`

LIVE_VERSION=${LIVE_VERSION_BUILD%.*}
LIVE_BUILD=${LIVE_VERSION_BUILD##*.}
PACKAGE_VERSION=`sed -nE 's/^\s*"version": "(.*?)",$/\1/p' package.json`

if [[ "$LIVE_VERSION" == "$PACKAGE_VERSION" ]]; then
    LIVE_BUILD=`expr $LIVE_BUILD + 1`
else
    LIVE_VERSION=${PACKAGE_VERSION}
    LIVE_BUILD=0
fi

rm -rf _site/*

jekyll build
echo "$LIVE_VERSION.$LIVE_BUILD" > _site/version

cd _site/
git add -A
git commit -m "v$LIVE_VERSION.$LIVE_BUILD $(date)"
git push
cd ..

我在从 docker hub 拉取的 Docker 容器中运行 Jenkins。我通过添加 Jenkins 用于执行存储库的初始克隆的相同私钥信息来修改容器。但是,当我从脚本调用 git 命令时,它说它是未经身份验证的:

Started by user evt
Building in workspace /var/jenkins_home/workspace/Website Deploy
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url git@github.com:RIT-EVT/RIT-EVT.github.io.git # timeout=10
Fetching upstream changes from git@github.com:RIT-EVT/RIT-EVT.github.io.git
 > git --version # timeout=10
using GIT_SSH to set credentials GitHub - ssh
 > git fetch --tags --progress git@github.com:RIT-EVT/RIT-EVT.github.io.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/develop^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/develop^{commit} # timeout=10
Checking out Revision 85084620e62b5b03f02c610e33880eeb94b12531 (refs/remotes/origin/develop)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 85084620e62b5b03f02c610e33880eeb94b12531
 > git rev-list 85084620e62b5b03f02c610e33880eeb94b12531 # timeout=10
[Website Deploy] $ /bin/bash -xe /tmp/hudson9119924045433544873.sh
+ rm -rf _site/
+ git clone git@github.com:RIT-EVT/RIT-EVT.github.io.git --branch master --depth 1 _site
Cloning into '_site'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Build step 'Execute shell' marked build as failure
Finished: FAILURE

因此,密钥信息显然适用于 jenkins 的 git 插件,但无论出于何种原因,容器中的 git 二进制文件都没有获取密钥。更奇怪的是,我可以通过 SSH 连接到运行容器的机器,docker exec -it jenkins bash 进入容器,然后运行相同的 git 命令,它运行良好。

这让我想到这可能是用户和权限的问题。所以我试图找出运行脚本的用户 jenkins 是什么。这是我运行的非常小的脚本:

echo ${USER}
echo hello # Just a sanity test to make sure that echo works :p

这是我得到的输出:

misc. Jenkins stuff...
[Website Deploy] $ /bin/sh -xe /tmp/hudson1343134234815638946.sh
+ echo

+ echo hello
hello
Finished: SUCCESS

所以它似乎无法访问加载到ssh-agent 中的密钥信息,因为脚本不是在加载密钥的同一用户下运行(?)

任何帮助将不胜感激:)

更新:

我运行whoami 看看这是否可以在脚本中运行,结果它给了我jenkins

[Website Deploy] $ /bin/bash -xe /tmp/hudson2652666458388248519.sh
+ whoami
jenkins
Finished: SUCCESS

所以我很困惑为什么 git 不能从 ssh-agent 获取私钥。

【问题讨论】:

  • 因为 echo ${USER} 似乎没有帮助,你可以尝试用 whoami 命令替换它,你应该得到 jenkins 正在运行的用户名。
  • 另外,我不确定从 bash 脚本调用 git 是否会与 jenkins 插件交互。这取决于插件是否将密钥存储在用户的 .ssh 目录中以及如何存储。如果您使用了 -i 标志并提供了您要使用的密钥的路径,那么您应该可以在家了。
  • 我不需要它来与 jenkins 插件交互。这就是为什么我还将私钥加载到容器本身的 ssh 密钥存储中,因为这通常是 git 获取它们的方式。
  • 好的,所以运行whoami 给了我jenkins,但我很困惑为什么它无法访问 ssh-agent。
  • 您可以使用您的 SSH 密钥和 SSH 代理,请在此处查看答案:stackoverflow.com/questions/47870282/…

标签: git bash docker jenkins ssh


【解决方案1】:

虽然这可能对您有用,但完全可以从 Jenkins 上的 Docker 容器中调用 git 命令。只需在配置构建作业时使用 SSH 代理插件。这不仅会从 Jenkins 凭证存储中提供您需要的 SSH 密钥,还会为您配置和设置 SSH 代理。

我始终建议只使用 SSH 密钥,因为它们更安全且更难破解。

此外,SSH 代理插件也可以在 Jenkins 流水线脚本中调用。只需使用 sshagent 块包装任何需要访问密钥的命令。

例如:

sshagent(credentials: ['jenkins-credential-id']) {
  sh 'git clone git@github.com:RIT-EVT/RIT-EVT.github.io.git'
  sh 'jekyll build'
}

【讨论】:

  • 查看更多上下文会很有用。你在哪里写这个?分步骤?
【解决方案2】:

我知道出了什么问题。如果我使用docker exec -it jenkins bash 登录到容器,运行eval `ssh-agent -s` 来启动ssh-agent,然后运行ssh-add <keyFile>,我可以在shell 中运行git clone

但是,如果退出 shell 并通过运行相同的 docker 命令重新登录,ssh-agent 将不会启动并且不会加载私钥,这让我相信 ssh-agent 实际上不是在 Jenkins 构建运行时运行。

所以,我切换到在 git 中使用 https,并通过使用凭据绑定插件在 repo 的 URL 中提供用户名和密码。

所以本质上,您不能从 Jenkins 构建脚本调用 git 命令并期望能够使用您的 SSH 密钥。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2023-01-14
    • 2020-10-18
    • 2023-03-03
    相关资源
    最近更新 更多