Tektons git-clone忽略了我的ssh配置



我正在学习用Tekton克隆git仓库教程,并尝试使用ssh克隆git仓库。

管道工作正常,使用HTTPS,但对于ssh,它抱怨ssh配置丢失。从日志中我可以看到它找到了ssh文件的秘密。但是几行之后,它抱怨没有ssh配置。

任何想法?

我的管道。Yaml(与教程相同)

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: clone-read
spec:
description: | 
This pipeline clones a git repo, then echoes the README file to the stout.
params:
- name: repo-url
type: string
description: The git repo URL to clone from.
workspaces:
- name: shared-data
description: | 
This workspace contains the cloned repo files, so they can be read by the
next task.
- name: git-credentials
description: My ssh credentials
tasks:
- name: fetch-source
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-data
- name: ssh-directory
workspace: git-credentials
params:
- name: url
value: $(params.repo-url)
- name: verbose
value: true
- name: show-readme
runAfter: ["fetch-source"]
taskRef:
name: show-readme
workspaces:
- name: source
workspace: shared-data

我pipelinerun。Yaml(与教程相同):

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: clone-read-run-
spec:
pipelineRef:
name: clone-read
podTemplate:
securityContext:
fsGroup: 65532
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- name: git-credentials
secret:
secretName: git-credentials
params:
- name: repo-url
value: git@github.com:tektoncd/website.git

我sevret.yaml:

apiVersion: v1
kind: Secret
metadata:
name: git-credentials
data:
id_rsa: LS0tLS...
id_rsa.pub: c3NoLXJ...
known_hosts: Z2l0aH...

Logoutput:

$ tkn pipelinerun logs clone-read-run-72zlj -f
[fetch-source : clone] + '[' false '=' true ]
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cp -R /workspace/ssh-directory /home/git/.ssh
[fetch-source : clone] + chmod 700 /home/git/.ssh
[fetch-source : clone] + chmod -R 400 /home/git/.ssh/id_rsa /home/git/.ssh/id_rsa.pub /home/git/.ssh/known_hosts
[fetch-source : clone] + '[' false '=' true ]
[fetch-source : clone] + CHECKOUT_DIR=/workspace/output/
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cleandir
[fetch-source : clone] + '[' -d /workspace/output/ ]
[fetch-source : clone] + rm -rf '/workspace/output//*'
[fetch-source : clone] + rm -rf '/workspace/output//.[!.]*'
[fetch-source : clone] + rm -rf '/workspace/output//..?*'
[fetch-source : clone] + test -z
[fetch-source : clone] + test -z
[fetch-source : clone] + test -z
[fetch-source : clone] + git config --global --add safe.directory /workspace/output
[fetch-source : clone] + /ko-app/git-init '-url=git@github.com:tektoncd/website.git' '-revision=' '-refspec=' '-path=/workspace/output/' '-sslVerify=true' '-submodules=true' '-depth=1' '-sparseCheckoutDirectories='
[fetch-source : clone] {"level":"warn","ts":1671382236.5119827,"caller":"git/git.go:271","msg":"URL("git@github.com:tektoncd/website.git") appears to need SSH authentication but no SSH credentials have been provided"}
[fetch-source : clone] {"level":"error","ts":1671382237.3406594,"caller":"git/git.go:53","msg":"Error running git [fetch --recurse-submodules=yes --depth=1 origin --update-head-ok --force ]: exit status 128ngit@github.com: Permission denied (publickey).rnfatal: Could not read from remote repository.nnPlease make sure you have the correct access rightsnand the repository exists.n","stacktrace":"github.com/tektoncd/pipeline/pkg/git.runntgithub.com/tektoncd/pipeline/pkg/git/git.go:53ngithub.com/tektoncd/pipeline/pkg/git.Fetchntgithub.com/tektoncd/pipeline/pkg/git/git.go:156nmain.mainntgithub.com/tektoncd/pipeline/cmd/git-init/main.go:53nruntime.mainntruntime/proc.go:250"}
[fetch-source : clone] {"level":"fatal","ts":1671382237.340791,"caller":"git-init/main.go:54","msg":"Error fetching git repository: failed to fetch []: exit status 128","stacktrace":"main.mainntgithub.com/tektoncd/pipeline/cmd/git-init/main.go:54nruntime.mainntruntime/proc.go:250"}

我在测试git-clone任务和taskRun时也面临同样的问题(下面的文件可以很容易地与pipeline和pipelineRun相适应)。

第一个问题是git-clone任务使用的git-init docker镜像使用了一些硬编码的路径。当更改git-init docker映像标记时,会有一些内部更改,例如用户和主文件夹(在较新的映像v0.40中,用户是git,位于/home/git,在较早的映像中,非root位于/home/nonroot)。

由于git-clone-task是公共的,没有一个大的脚本,我选择编辑它并删除不必要的代码。

apiVersion: v1
kind: Secret
metadata:
name: github-repo-credentials-secret
data:
id_rsa: LS0tLS...
known_hosts: Z2l0aH...

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: github-repo-clone-task
spec:
workspaces:
- name: clonedDirectoryFolder
description: Github cloned repo shared folder
- name: githubSshFolder
description: GitHub SSH credentials shared folder
params:
- name: repoUrl
description: Repository URL to clone from.
type: string
- name: revision
description: Branch, tag .... etc
type: string
default: "main"
- name: deleteExisting
description: Clean out the contents of the destination directory if it already exists before cloning.
type: string
default: "true"
- name: userHome
description: Absolute path to the user's home directory.
type: string
default: "/home/git"
- name: gitInitImage
description: The image providing the git-init binary that this Task runs.
type: string
default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.25.0"
steps:
- name: clone-git-repo-ssh
image: "$(params.gitInitImage)"
#image: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.21.0"
env:
- name: PARAM_URL
value: $(params.repoUrl)
- name: PARAM_REVISION
value: $(params.revision)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.clonedDirectoryFolder.path)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.githubSshFolder.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.githubSshFolder.path)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: GIT_SSH_COMMAND
#  value: "ssh -i $(params.userHome)/.ssh/id_rsa -F /dev/null -o 'IdentitiesOnly yes'"  # both values work
value: "ssh -i $(params.userHome)/.ssh/id_rsa"
script: |
#!/usr/bin/env sh
set -eu
set -x

if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*

chmod 600 "${PARAM_USER_HOME}"/.ssh/config         

fi

# ln -s "${PARAM_USER_HOME}"/.ssh /tekton/creds  # uncomment this to get rid of this warming: appears to need SSH authentication but no SSH credentials have been provided

CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}

if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir || true
fi

git config --global --add safe.directory "${WORKSPACE_OUTPUT_PATH}"

# uncomment the two lines below if the GIT_SSH_COMMAND env variable is not set

#eval "$(ssh-agent -s)"

#ssh-add "${PARAM_USER_HOME}"/.ssh/id_rsa

/ko-app/git-init 
-url="${PARAM_URL}" 
-revision="${PARAM_REVISION}" 
-path="${CHECKOUT_DIR}"
cd "${CHECKOUT_DIR}"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
# Verify clone is success by reading readme file.
cat ${CHECKOUT_DIR}/README.md

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: github-repo-clone-task-run
spec:
workspaces:
- name: clonedDirectoryFolder
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- name: githubSshFolder
secret:
secretName: github-repo-credentials-secret
params:
- name: repoUrl
value: "git@github.com:tektoncd/website.git"  #git ssh clone Url
- name: revision
value: "main"
- name: userHome
value: "/home/git"
#value: "/root"  # use this when the security context is set root
#value: "/home/nonroot"  # use this value for ealier git-init:v0.29.0
- name: gitInitImage
#value: "alpine/git:latest"
value: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2"
#value: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.29.0"  # if you use this image, set the userHome to /home/nonroot
taskRef:
name: github-repo-clone-task
# uncomment this part to run the task as root

#podTemplate:
#  securityContext:
#    runAsNonRoot: false
#    runAsUser: 0

GIT_SSH_COMMAND环境变量用于强制git使用提供的私钥。

如果您想使用alpine git docker映像,我只是完成我的答案。在这种情况下,对以前的Yaml文件进行了很少的修改。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: github-repo-clone-task-git-alpine
spec:
workspaces:
- name: clonedDirectoryFolder
description: Github cloned repo shared folder
- name: githubSshFolder
description: GitHub SSH credentials shared folder
params:
- name: repoUrl
description: Repository URL to clone from.
type: string
- name: revision
description: Branch, tag .... etc
type: string
default: "main"
- name: deleteExisting
description: Clean out the contents of the destination directory if it already exists before cloning.
type: string
default: "true"
- name: userHome
description: Absolute path to the user's home directory.
type: string
default: "/root"
- name: gitInitImage
description: The image providing the git-init binary that this Task runs.
type: string
default: "alpine/git:latest"
steps:
- name: clone-git-repo-ssh
image: "$(params.gitInitImage)"
env:
- name: PARAM_URL
value: $(params.repoUrl)
- name: PARAM_REVISION
value: $(params.revision)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.clonedDirectoryFolder.path)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.githubSshFolder.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.githubSshFolder.path)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: GIT_SSH_COMMAND
#  value: "ssh -i $(params.userHome)/.ssh/id_rsa -F /dev/null -o 'IdentitiesOnly yes'"  # both values work
value: "ssh -i $(params.userHome)/.ssh/id_rsa"
script: |
#!/usr/bin/env sh
set -eu
set -x

if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*

chmod 600 "${PARAM_USER_HOME}"/.ssh/config         

fi

CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}

if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir || true
fi

# uncomment the two lines below if the GIT_SSH_COMMAND env variable is not set

#eval "$(ssh-agent -s)"

#ssh-add "${PARAM_USER_HOME}"/.ssh/id_rsa

git clone "${PARAM_URL}" --branch="${PARAM_REVISION}" "${CHECKOUT_DIR}"
cd "${CHECKOUT_DIR}"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
# Verify clone is success by reading readme file.
cat ${CHECKOUT_DIR}/README.md

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: github-repo-clone-task-run-git-alpine
spec:
workspaces:
- name: clonedDirectoryFolder
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- name: githubSshFolder
secret:
secretName: github-repo-credentials-secret
params:
- name: repoUrl
value: "git@github.com:tektoncd/website.git"  #git ssh clone Url
- name: revision
value: "main"
- name: userHome
value: "/root"
- name: gitInitImage
value: "alpine/git:latest"
taskRef:
name: github-repo-clone-task-git-alpine

注意,这个映像使用root用户,还有一个映像使用非root用户:gcr。最新的,要在这些Yaml文件中使用这个图像,只需在TaskRun中设置gitInitImage参数值,并将userHome设置为/home/nonroot

更多信息可以在这个github页面找到:https://github.com/tektoncd/pipeline/blob/main/examples/v1beta1/taskruns/authenticating-git-commands.yaml

最新更新