Zep*_*LUS 49 linux containers jenkins docker
我正在运行一个Jenkins集群,在Master和Slave中,它们都作为Docker容器运行.
主机是在MacOS上运行的最新boot2docker VM.
为了让Jenkins能够使用Docker执行部署,我已将docker.sock和docker客户端从主机安装到Jenkins容器,如下所示: -
docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -v $HOST_JENKINS_DATA_DIRECTORY/jenkins_data:/var/jenkins_home -v $HOST_SSH_KEYS_DIRECTORY/.ssh/:/var/jenkins_home/.ssh/ -p 8080:8080 jenkins
Run Code Online (Sandbox Code Playgroud)
将卷安装到在Jenkins容器内运行的Docker容器时,我遇到了问题.例如,如果我需要在Jenkins容器中运行另一个Container,我会执行以下操作: -
sudo docker run -v $JENKINS_CONTAINER/deploy.json:/root/deploy.json $CONTAINER_REPO/$CONTAINER_IMAGE
Run Code Online (Sandbox Code Playgroud)
上面运行容器,但文件"deploy.json"不是作为文件挂载,而是作为"目录"挂载.即使我将目录作为卷安装,我也无法查看生成的容器中的文件.
这是一个问题,因为Docker在Docker案例中由于文件权限?
任何指针都会有用!
谢谢!
Zep*_*LUS 73
Docker容器中的Docker容器使用父HOST的Docker守护程序,因此,"docker-in-docker"情况下安装的任何卷仍然是从HOST引用的,而不是从Container引用的.
因此,从主机中的Jenkins容器安装的实际路径"不存在".因此,在"docker-in-docker"容器中创建一个新目录,该目录为空.当目录安装到Container内的新Docker容器时,同样适用.
我错过了非常基本和明显的事情,但很快我就输入了问题.
Rya*_*ugh 11
另一种方法是使用命名卷或数据卷容器.这样,内部容器不必知道有关主机的任何信息,Jenkins容器和构建容器都以相同的方式引用数据卷.
我尝试过类似于你正在做的事情,除了使用代理而不是使用Jenkins master.问题是相同的,因为我无法在内部容器中安装Jenkins工作区.对我有用的是使用数据卷容器方法,工作区文件对代理容器和内部容器都是可见的.我喜欢这种方法的是两个容器以相同的方式引用数据量.使用内部容器挂载目录会很棘手,因为内部容器现在需要了解其父容器正在运行的主机.
我在这里有关于我的方法的详细博客文章:
以及代码在这里:
https://github.com/damnhandy/jenkins-pipeline-docker
在我的具体情况下,并非所有内容都按照Jenkins Pipeline插件的方式运行.但它确实解决了内部容器能够访问Jenkins工作空间目录的问题.
关于与Jenkins相关的用例,您可以通过在主机上创建符号链接来伪造路径:
ln -s $HOST_JENKINS_DATA_DIRECTORY/jenkins_data /var/jenkins_home
Run Code Online (Sandbox Code Playgroud)
这些帖子中有很多很好的信息,但我发现没有一个人非常清楚他们指的是哪个容器。因此,让我们标记 3 个环境:
我们都知道如何将文件夹从 H 挂载到 D:以 D 开头
docker run ... -v <path-on-H>:<path-on-D> -v /var/run/docker.sock:/var/run/docker.sock ...
Run Code Online (Sandbox Code Playgroud)
挑战是:您希望path-on-H在 D2 中作为path-on-D2.
但是当我们尝试将相同的path-on-H东西安装到 D2时我们都被咬了,因为我们开始 D2
docker run ... -v <path-on-D>:<path-on-D2> ...
Run Code Online (Sandbox Code Playgroud)
当你与 D 共享 H 上的 docker 套接字时,那么在 D 中运行 docker 命令本质上是在 H 上运行它们。 事实上,如果你像这样启动 D2,一切正常(一开始很意外,但仔细想想是有道理的):
docker run ... -v <path-on-H>:<path-on-D2> ...
Run Code Online (Sandbox Code Playgroud)
下一个棘手的一点是,对于我们中的许多人来说,path-on-H将根据运行它的人而改变。有很多方法可以将数据传递给 D,因此它知道要用于什么path-on-H,但最简单的方法可能是环境变量。为了使这种 var 的目的更清楚,我以DIND_. 然后从H开始 D 像这样:
docker run ... -v <path-on-H>:<path-on-D> --env DIND_USER_HOME=$HOME \
--env DIND_SOMETHING=blabla -v /var/run/docker.sock:/var/run/docker.sock ...
Run Code Online (Sandbox Code Playgroud)
从D开始 D2 像这样:
docker run ... -v $DIND_USER_HOME:<path-on-D2> ...
Run Code Online (Sandbox Code Playgroud)
如果你像我一样,不想搞乱 Jenkins 设置,或者懒得去经历所有这些麻烦,这里有一个简单的解决方法,我可以让这个工作适合我。
步骤 1 - 将以下变量添加到管道的环境部分
environment {
ABSOLUTE_WORKSPACE = "/home/ubuntu/volumes/jenkins-data/workspace"
JOB_WORKSPACE = "\${PWD##*/}"
}
Run Code Online (Sandbox Code Playgroud)
步骤 2 - 使用以下 Jenkins 管道命令运行容器,如下所示。
steps {
sh "docker run -v ${ABSOLUTE_WORKSPACE}/${JOB_WORKSPACE}/my/dir/to/mount:/targetPath imageName:tag"
}
Run Code Online (Sandbox Code Playgroud)
请注意上述语句中的双引号,如果引号格式不正确或添加了单引号,Jenkins 将不会转换环境变量。
每个变量代表什么意思?
ABSOLUTE_WORKSPACE 是我们在启动 Jenkins Docker 容器时安装的 Jenkins 卷的路径。就我而言,docker run 命令如下。
sudo docker run \
-p 80:8080 \
-v /home/ubuntu/volumes/jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-d -t jenkinsci/blueocean
因此变量 ABSOLUTE_WORKSPACE=/home/ubuntu/volumes/jenkins-data + /workspace
这是如何运作的 ?
这非常简单,正如@ZephyrPLUSPLUS(鸣谢)答案中提到的,在 Jenkins 管道中运行的 docker 容器的源路径不是当前容器中的路径,而是采用的路径是主机的路径。我们在这里所做的就是构建 Jenkins 管道运行的路径。并将其安装到我们的容器上。瞧!
| 归档时间: |
|
| 查看次数: |
14159 次 |
| 最近记录: |