问题描述
想要在使用Jenkins Kubernetes插件配置的Jenkins代理节点旁边运行一个Docker-in-Docker(dind)容器。他目前正在运行一个普通的代理节点,已经安装了所有的工具,包括Docker客户端,但没有运行Docker服务器/守护进程。他的想法是添加另一个容器,该容器运行Docker守护进程。这两个容器共享相同的工作目录,因此它们可以操作相同的数据。他之所以选择使用两个容器,是因为Docker守护进程需要特权访问,并且他希望尽可能限制它的权限。
他遇到的第一个问题是,当代理节点构建完成后,Jenkins并没有”杀死pod”,而只是结束了代理进程。现在有另一个容器在运行,pod仍然保持活动状态。他通过在代理pod停止时向另一个共享卷写入一个文件来解决了这个问题,然后dind pod读取该文件,并在文件存在时退出。
以下是他当前Pod配置的摘录:
apiVersion: "v1"
kind: "Pod"
spec:
serviceAccountName: jenkins-agent
containers:
- image: "jenkins-jnlp-image"
command: [ "/bin/sh", "-c" ]
args:
- |
trap 'touch /usr/share/pod/done' EXIT
/entrypoint.sh
name: "jnlp"
env:
- name: DOCKER_HOST
value: tcp://localhost:2375
securityContext:
privileged: false
tty: true
volumeMounts:
- mountPath: "/home/jenkins/agent"
name: "workspace-volume"
readOnly: false
- mountPath: /usr/share/pod
name: tmp-pod
workingDir: "/home/jenkins/agent"
- image: "dind-image"
name: "dind"
command: [ "/bin/sh", "-c" ]
args:
- |
dockerd-entrypoint.sh &
while ! test -f /usr/share/pod/done; do
echo 'Waiting for the jnlp to finish...'
sleep 5
done
echo "Agent pod finished, exiting"
exit 0
securityContext:
privileged: true
tty: false
volumeMounts:
- mountPath: "/home/jenkins/agent"
name: "workspace-volume"
readOnly: false
- mountPath: /usr/share/pod
name: tmp-pod
workingDir: "/home/jenkins/agent"
volumes:
- emptyDir:
medium: ""
name: "workspace-volume"
- emptyDir: {}
name: tmp-pod
用户想知道这种做法是否正确,是否有更好的方法来实现这个目标。另外,他使用的是官方Helm chart进行安装,他想知道是否有一种好的方法来添加另一个容器,而不需要覆盖整个pod模板。如果没有,他可能会创建一个PR来添加这个功能。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
你可以使用Docker-in-Docker代理来实现在Jenkins代理节点旁边运行Docker-in-Docker容器。这种方法使用两个容器,一个是带有Docker客户端的代理容器,另一个是带有Docker守护进程的容器。
以下是实现这种方法的步骤:
1. 在Jenkins Kubernetes插件的配置文件(JCasC)中,将Docker-in-Docker代理添加为额外的代理。
2. 在Jenkins的Helm chart中,添加一个容器来运行Docker守护进程。
下面是一个示例的Jenkins Kubernetes插件配置文件(JCasC)的部分内容:
jenkins:
agents:
kubernetes:
containers:
- name: jnlp
image: jenkins/jnlp-agent-docker
args: ["$(JENKINS_SECRET)", "$(JENKINS_NAME)"]
- name: dind
image: docker:dind
securityContext:
privileged: true
在上面的示例中,我们在Jenkins Kubernetes插件的配置文件中添加了一个名为dind
的容器,使用docker:dind
镜像运行Docker守护进程。同时,我们还保留了原来的jnlp
容器,它是带有Docker客户端的代理容器。
请注意,这只是一个示例配置,你需要根据你的实际需求进行相应的修改。
方案2
如果你使用的是官方Helm chart进行安装,你可以通过修改Helm chart的values.yaml文件来添加另一个容器,而不需要覆盖整个pod模板。
以下是一个示例的values.yaml文件的部分内容:
agent:
additionalAgents:
- name: dind
image: docker:dind
securityContext:
privileged: true
在上面的示例中,我们在additionalAgents
中添加了一个名为dind
的容器,使用docker:dind
镜像运行Docker守护进程。这样就可以在Jenkins的Helm chart中添加另一个容器,而不需要覆盖整个pod模板。
请注意,这只是一个示例配置,你需要根据你的实际需求进行相应的修改。
总结
在Jenkins代理节点旁边运行Docker-in-Docker容器可以通过使用两个容器来实现,一个是带有Docker客户端的代理容器,另一个是带有Docker守护进程的容器。你可以根据你的实际需求选择适合你的方法,并根据需要进行相应的配置。
希望这些解决方案对你有帮助!如果你有任何其他问题,请随时提问。