在运行于Openshift的Docker容器中安装和运行Docker

4
我目前正在处理以下情景:
我正在尝试在OpenShift中设置一个容器,其中运行的Jenkins可以运行docker,以利用声明性流水线,在其自己的docker容器中运行构建。这基本上需要在此容器内安装和运行docker。
我已经花了相当长的时间在这方面工作。查看了数十篇在线文章和帖子,但我还没有成功。基本上我做到了以下几点:
- 我可以在我的容器中安装docker(从baseimage openshift/jenkins-2-centos7:latest) - 但是我无法使docker运行,因为它使用systemctl,而systemctl在系统中干扰PID 1,因此在docker容器内不起作用,或者至少不被推荐使用。
systemctl start docker

这将导致Docker无法连接到守护程序(预期的情况)并显示以下错误消息:

无法连接到Docker守护程序。此主机上是否运行了“docker -d”?

因此,我尝试使用以下内容在我的Dockerfile中自己设置守护程序:

RUN usermod -aG docker $(whoami)
RUN dockerd -H unix:///var/run/docker.sock

无法挂载cgroups,因此无法使用docker。 经过一些研究,发现可以使用来自https://github.com/tianon/cgroupfs-mount/tree/master的cgroupfs-mount脚本来解决此问题。 但是,即使在这里也没有成功,出现以下错误:“启动守护程序时出错:初始化网络控制器时出错:获取控制器实例时出错:创建NAT链DOCKER失败:iptables失败:iptables -t nat -N DOCKER:iptables v1.4.21:无法初始化iptables表“nat”:权限被拒绝(必须是root用户)。 可能需要升级iptables或内核。” 现在经过数小时的努力,我已经没有任何想法了。 有人有关于如何在OpenShift中使docker工作的想法吗? 将不胜感激。
3个回答

2
我正在尝试在OpenShift中设置一个容器,其中运行的Jenkins能够运行docker以利用声明性流水线,在其中构建在其自己的docker容器中运行。这基本上需要在该容器内安装和运行docker。

我认为您的结论不是唯一的可能性,下面我将描述一种更简单的方法来实现您想要的内容! :) 如果您有任何其他用例,请让我知道,我会尝试更新以涵盖它们:

  • 在它们自己的容器中运行管道
  • 从管道中运行其他容器
  • 从管道中构建容器镜像

在其自己的容器中运行的管道

对于这种情况,有一个出色的Kubernetes插件

使用此插件,您可以将Kubernetes/OpenShift云添加到Jenkins全局配置中。这可以是Jenkins正在运行的云(如果您使用OpenShift提供的Jenkins镜像,则默认情况下会添加该云),也可以是外部集群。

在该配置内,您可以定义PodTemplates(同样,在OpenShift提供的Jenkins镜像中提供了一些示例),或者您还可以直接在管道中指定。当您的管道请求具有与其中之一匹配的标签的节点/代理时(并且没有匹配的长时间运行代理),则将从该模板创建一个pod,并且您的管道执行将在其中的一个容器中发生。不再需要时,它将被取消配置。

此插件公开的管道步骤如下:https://jenkins.io/doc/pipeline/steps/kubernetes/

从管道运行其他容器

作为您的流水线的一部分,您可能想要运行一些测试,并且这些测试可能希望能够与数据库等进行交互。您可以在OpenShift项目中创建这些资源(例如,使用Deployment创建资源并使用Service公开它),然后在完成后将其拆除。openshift-client插件在此非常有用,并且有关如何与OpenShift交互的文档。

从流水线构建容器镜像

如果您的目标是从流水线构建容器镜像,请记住,OpenShift也通过Builds公开了这种功能(取决于安全配置)。就像在前面的部分中一样,您可以使用openshift-client插件来创建和触发构建。


关于由OpenShift维护的Jenkins镜像(以及如何在OpenShift上执行有用的Jenkins操作),请参阅OpenShift文档中的此专用页面获取更多信息。

谢谢。我会看一下Kubernetes插件。听起来很有前途。第三个选项实际上是我目前的做法。我的问题在于,一旦我通过流水线启动容器运行例如集成测试,如果成功了等等,我无法得到结果呈现回来。 - relief.melone

2
您已经阅读了Docker团队的@jpetazzo关于Docker In Docker(DinD)的这篇文章
文章:
“Docker-in-Docker的主要目的是帮助开发Docker本身。许多人使用它来运行CI(例如使用Jenkins),这起初似乎很好,但他们会遇到许多可以通过将Docker套接字绑定到Jenkins容器中而避免的有趣问题。”
DinD仓库:
“由于一些惊人的人(如@jfrazelle和@tianon)的共同努力,这项工作现在已经过时,他们也是组装宜家家具的黑带高手。 如果您今天想运行Docker-in-Docker,您所需要做的就是:”
docker run --privileged -d docker:dind

这是一篇文章,使用另一种方法在Docker容器中构建带有Jenkins的Docker容器。here
docker run -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --name jenkins \
  jenkins/jenkins:lts

所以你可能想要根据您的OpenShift情况调整其中一个解决方案。我希望它能解决您的问题。

谢谢您的输入。我会认真处理的。同时,希望这能澄清一些事情。使用OpenShift需要一个相当陡峭的学习曲线,而我在Linux方面也只是个中级水平。 - relief.melone
这绝对听起来是一个很好的方法,将docker.sock进行bind-mount。我会测试一下这个方法。希望它不会受到OpenShift限制的影响。 - relief.melone
让我知道进展如何 ;) - Exadra37
目前还不太好。我的问题是,我无法在OpenShift中运行docker -v命令。在这里找到了另一个有趣的东西https://lists.openshift.redhat.com/openshift-archives/users/2016-March/msg00216.html,但它已经很旧了,目前我的docker.sock挂载不起作用。没有错误,但文件就是无法挂载。我会继续尝试,并在有进展时进行更新。 - relief.melone
我对OpenShift不是很有经验... 如果可以的话,请尝试使用 docker --mount=...,如果可以的话,我会更新我的答案并在此处阅读关于它的更多信息 here - Exadra37
问题在于OpenShift运行docker。我无法访问参数,此外似乎我也无法将容器设置为特权模式,这会防止我挂载docker.sock。我会继续努力解决它,并在找到答案后回来的;) - relief.melone

0

您需要一个特权的 Pod 运行 Jenkins,该 Pod 挂载了 OpenShift 节点的 Docker 套接字。这是一个不好的想法,因为 Jenkins 将在 Kubernetes 语义和控制之外启动容器。

为什么不使用 OpenShift 随附的 s2i 服务

此致敬意。


特权容器对我来说不是一个可行的选择。我想在该Pod上同时使用Jenkins和Docker的原因是我想自动化部署Jenkins,并能够在其特定环境中运行隔离的构建任务。 - relief.melone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接