我有一个 Jenkins 管道,我需要在 docker 容器中使用 ssh 从 Github 克隆存储库。在本例中,Jenkins Worker 是 Kubernetes Pod。因此,为了使用 SSH 克隆 git 存储库,我将 SSH_AUTH_SOCK 挂载到 docker 容器。下面是我的詹金斯管道。 (下面的示例只是为了检查 ssh 密钥在容器内是否可用而编写,这不是实际的用例)。
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: alpine
image: pgedara/alpine-docker:3.0
command:
- cat
tty: true
imagePullPolicy: Always
securityContext:
privileged: true
volumeMounts:
- name: docker-socket
mountPath: /var/run
- name: docker-daemon
image: docker:dind
securityContext:
privileged: true
volumeMounts:
- name: docker-socket
mountPath: /var/run
volumes:
- name: docker-socket
emptyDir: {}
'''
}
}
stages {
stage('ssh-auth-sock-test') {
steps {
container ('alpine') {
sshagent(['my-ssh-key']) {
sh (script: "docker run -v ${SSH_AUTH_SOCK}:/ssh_auth_sock -e SSH_AUTH_SOCK=/ssh_auth_sock pgedara/alpine-git:5.0 ssh-add -L")
}
}
}
}
}
}
因此,当我运行此命令时,在下载 docker 镜像 pgedara/alpine-git 后不久,我收到以下错误。
Status: Downloaded newer image for pgedara/alpine-git:5.0
Error connecting to agent: Connection refused
但是,如果我用标签替换代理块内的“kubernetes”块以便在 EC2 工作线程上运行作业,“ssh-add -L”会打印出公共 ssh 密钥。
pipeline {
agent {
label 'ubuntu' // This spins an EC2 instance as a worker node
}
stages {
stage('ssh-auth-sock-test') {
steps {
//container ('alpine') {
sshagent(['my-ssh-key']) {
sh (script: "docker run -v ${SSH_AUTH_SOCK}:/ssh_auth_sock -e SSH_AUTH_SOCK=/ssh_auth_sock pgedara/alpine-git:5.0 ssh-add -L")
}
//}
}
}
}
}
下面是 pgedara/alpine-docker:3.0 的 Dockerfile
FROM alpine
RUN apk add --no-cache --update bash docker openssh sudo acl git
RUN rm -f /etc/ssh/ssh_config
ADD config ~/.ssh
ADD ssh_config /etc/ssh/
RUN mkdir -p ~/.ssh && ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
以下是config和ssh_config文件的内容
Host *
ForwardAgent yes
下面是 pgedara/alpine-git:5.0 的 Dockerfile
FROM alpine
RUN apk add --no-cache --update git openssh sudo bash
RUN mkdir -p ~/.ssh && ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
因此,如果有人能解释为什么当我为 Jenkins 工作线程使用 pod 模板时会出现上述错误,我将不胜感激。如果有人需要更多详细信息来理解我的问题,请告诉我。
谢谢!
我在类似的设置中遇到了同样的问题,并且可能有解决方案。经过一番挖掘后,我发现为 SSH_AUTH_SOCK 创建的路径位于 /tmp 目录下。但是,该目录不在 Pod 声明中的两个容器之间共享。如果您在两个容器中设置另一个挂载在 /tmp 的 emptyDir 卷,类似于您对 docker-socket 挂载所做的操作,那么事情可能会开始工作。
帮助我解决这个问题的其他方法是将卷安装选项从 -v 切换到 --mount 。 -v 将为不存在的指定路径静默创建一个新卷,但该路径不是套接字。 --mount 在源路径不存在时有用地报告错误。