Docker容器内部的Docker容器

12

我想在正在运行的Docker容器内安装Docker。

docker run -it centos:centos7

我的基础容器使用的是CentOS,我可以使用docker exec登录运行中的容器。但是当我尝试在其中安装Docker并使用yum install -y docker进行安装时,出现问题。

但是无论如何,我都无法使用docker -d &启动Docker服务,它会给我报错:

INFO[0000] Option DefaultNetwork: bridge 
WARN[0000] Running modprobe bridge nf_nat br_netfilter failed with message: , error: exit status 1 
FATA[0000] Error starting daemon: Error initializing network controller: Error initializing bridge driver: Setup IP forwarding failed: open /proc/sys/net/ipv4/ip_forward: read-only file system

有没有一种方法可以在Docker容器内安装Docker,或者构建已经运行Docker的镜像?我已经看过这些示例,但对我都不起作用。

主机机器上uname -r的输出:

[fedora@ ~]$ uname -r
4.2.6-200.fc22.x86_64

任何帮助都将不胜感激。

先行致谢。


你能提供一下你用来启动基础和内部 Docker 容器的完整命令吗?你传递的参数可能有问题。 - michaelbahr
嗨Michaelbar,以下是我尝试过的:docker run -it centos:centos7 bash 在CentOS中安装Docker: - priyank
1
请在您的问题中添加命令以进行扩展(编辑)。 - michaelbahr
yum install -y docker , docker -d & ,以下是输出: INFO[0000] 选项 DefaultNetwork: bridge WARN[0000] 运行 modprobe bridge nf_nat br_netfilter 失败,错误信息为:,错误:退出状态 1 FATA[0000] 启动守护程序时出错:初始化网络控制器时出错:初始化桥接驱动程序时出错:设置 IP 转发失败:打开 /proc/sys/net/ipv4/ip_forward:只读文件系统 - priyank
1
请在你的问题中附加 uname -r 的输出。 - michaelbahr
显示剩余2条评论
4个回答

11

更新

感谢https://dev59.com/TFsX5IYBdhLWcg3wFsEa#38016704,我想展示另一种方法。

不要挂载主机的docker二进制文件,而是应该复制或安装容器特定版本的docker二进制文件。由于您只是以客户端模式使用它,因此不需要将其安装为系统服务。仍然需要将Docker套接字挂载到容器中,以便可以轻松地与主机的Docker引擎进行通信。

假设您有一个带有可运行的Docker二进制文件的基础映像(例如官方的docker映像),则示例现在如下所示:

docker run\ -v /var/run/docker.sock:/var/run/docker.sock\ docker:1.12 docker info


虽然没有真正回答您的问题,但我建议您阅读在CI或测试环境中使用Docker-in-Docker?三思而后行。

它解释了为什么应该用基于容器的设置替换运行docker-in-docker,并链接到原始https://github.com/jpetazzo/dind项目,其中您可以找到如何在Docker中运行Docker的工作示例 - 如果您仍然想要Docker-in-Docker。

一个启用容器访问主机Docker守护进程的示例如下:

docker run\
  -v /var/run/docker.sock:/var/run/docker.sock\
  -v /usr/bin/docker:/usr/bin/docker\
  busybox:latest /usr/bin/docker info

2
如果您正在使用Docker toolbox的Mac系统上。
以下命令不起作用
docker run\
  -v /var/run/docker.sock:/var/run/docker.sock\
  -v /usr/bin/docker:/usr/bin/docker\
  busybox:latest /usr/bin/docker info

因为/var/run/docker.sock不在您的OSX文件系统中,Docker守护程序正在boot2docker VM内运行 - 这就是Unix套接字所在的位置。因此,您必须从boot2docker VM中运行容器。
$ docker-machine ssh default
$ docker run\ 
         -v /var/run/docker.sock:/var/run/docker.sock\ 
         -v $(which docker):/usr/bin/docker\ 
         busybox:latest /usr/bin/docker info
$ exit

这看起来像是Docker-in-Docker,感觉像是Docker-in-Docker,但它并不是Docker-in-Docker。当这个容器创建更多的容器时,这些容器将在最高级别的Docker中创建。


感谢您提醒我有关平台特定示例的问题。您的示例确实有所改进,但仍不具备平台独立性。一旦主机系统和容器基础镜像使用不同的架构,您将会迷失方向。我将用更灵活的方法更新我的答案。 - gesellix

1
你需要使用--privileged参数。
默认情况下,Docker容器是“非特权”的,例如不能在Docker容器内运行Docker守护程序。 来源 使用命令docker run --privileged -it centos:centos7 bash运行基础镜像。然后,您可以在该容器内安装和运行另一个Docker容器。

嘿,感谢您的快速回复。我尝试使用“--privilaged”,但当我在CentOS7容器内运行Docker守护程序时,出现以下错误,请问您有什么想法? - priyank
INFO[0000] 在unix上监听HTTP (/var/run/docker.sock) WARN[0000] 不支持Udev同步。这将导致意外行为、数据丢失和错误。有关更多信息,请参见https://docs.docker.com/reference/commandline/cli/#daemon-storage-driver-option ERRO[0000] 警告:未指定--storage-opt dm.thinpooldev,使用回环;强烈不建议在生产中使用此配置 ERRO[0000] [graphdriver] 先前的存储驱动程序“devicemapper”失败:exec:“mkfs.ext4”:$PATH中找不到可执行文件 - priyank
1
不,您需要使用 --privileged 启动 基础 Docker 容器。内部容器则无需该参数启动。请始终提供您执行的完整命令。 - michaelbahr
抱歉回复晚了,是的,我正在做完全相同的事情,以以下方式启动基础容器: docker run --privileged -it centos:centos7 bash [root@67b98a863bc5 /]# yum install -y docker [root@67b98a863bc5 /]#docker -d & 之后我收到了如我之前评论中提到的错误消息。有什么指针吗? - priyank

0

我的虚拟机也遇到了类似的问题。

我通过将存储文件系统从镜像更改为vfs(在daemon.json文件中)来解决了这个问题,就像下面的图片一样。

enter image description here

对于图像处理,首先需要创建一个基础镜像,在我的情况下是使用CentOS7。

FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

使用已构建的镜像(在我的情况下,我称之为local/c7-systemd),创建第二个镜像,安装Docker并将daemon.json移动到内部。
FROM local/c7-systemd
RUN yum install -y yum-utils
RUN yum-config-manager  --add-repo https://download.docker.com/linux/centos/docker-ce.repo
RUN yum install -y docker-ce docker-ce-cli containerd.io
RUN curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
RUN ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
COPY daemon.json /etc/docker/daemon.json
RUN yum install -y nano
RUN systemctl enable docker

EXPOSE 80
EXPOSE 8080
EXPOSE 8161
EXPOSE 6379
EXPOSE 8761
CMD ["/usr/sbin/init"]

享受!


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