摘要

构建一个包含python mysql redis的镜像的用于系统进行基础环境的测试与引用。

一、Docker in Docker的原理

Docker-in-Docker的方式主要是为了帮助核心团队更快地进行 Docker 开发。在 Docker-in-Docker 之前,典型的开发周期是:

  • 黑客攻击
  • 建造
  • 停止当前运行的 Docker 守护进程
  • 运行新的 Docker 守护进程
  • 测试
  • 重复

如果你想要一个漂亮的、可重复的构建(即在容器中),那就有点复杂了:

  • 黑客攻击
  • 确保 Docker 的可用版本正在运行
  • 用旧的 Docker 构建新的 Docker
  • 停止 Docker 守护进程
  • 运行新的 Docker 守护进程
  • 测试
  • 停止新的 Docker 守护进程
  • 重复

1.1 Docker in Docker的缺点

Docker-in-Docker 并非 100% 有几个问题需要注意。

  • 关于 LSM(Linux 安全模块),AppArmor 和 SELinux:当启动容器时,“内部 Docker”可能会尝试应用会与“外部 Docker”冲突或混淆的安全配置文件。这实际上是尝试合并 -privileged 标志的原始实现时最难解决的问题。在Debian 机器和 Ubuntu 测试 VM 上有效(并且所有测试都通过了),但它会在 Michael Crosby 的机器(如果我没记错的话是 Fedora)上崩溃。可能是可以使用配置 SELINUX=enforce运行,而我的更改没有考虑 SELinux 配置文件。
  • 存储驱动程序有关。当你在 Docker 中运行 Docker 时,外部 Docker 运行在普通文件系统(EXT4、BTRFS、你有什么)之上,但内部 Docker 运行在写时复制系统(AUFS、BTRFS、设备映射器等)之上.,取决于外部 Docker 设置使用的内容)。有很多组合是行不通的。例如,您不能在 AUFS 之上运行 AUFS。如果你在 BTRFS 之上运行 BTRFS,它首先应该可以工作,但是一旦你有嵌套的子卷,删除父子卷就会失败。 Device Mapper 没有命名空间,因此如果 Docker 的多个实例在同一台机器上使用它,它们都将能够看到并影响彼此的镜像和容器支持设备。许多这些问题都有解决方法;例如,如果您想在内部 Docker 中使用 AUFS,只需将 /var/lib/docker 提升为卷即可。 Docker 为 Device Mapper 目标名称添加了一些基本的命名空间,这样如果 Docker 的多个调用在同一台机器上运行,它们就不会相互影响。
  • 对于构建缓存也存在很大问题。如果运行 Docker-in-Docker;如何使用位于我的主机上的images,而不是在内部 Docker 中再次拉取所有内容?”,或许你尝试将 /var/lib/docker 从主机绑定挂载到 Docker-in-Docker 容器中。有时他们与多个容器共享 /var/lib/docker。但是对于Docker 守护进程被明确设计为具有对 /var/lib/docker 的独占访问权限。任何其他东西都不应触及、戳或挠隐藏在那里的任何 Docker 文件。这是为什么?这是从 dotCloud 时代吸取的教训之一。 dotCloud 容器引擎通过让多个进程同时访问 /var/lib/dotcloud 来工作。例如像原子文件替换(而不是就地编辑),或者是代码中添加咨询和强制锁定,以及对 SQLite 和 BDB 等安全系统的试验;当我们重构我们的容器引擎(最终成为 Docker)时,一个重大的设计决策就是将所有容器操作集中在一个守护进程下,并完成所有并发访问的请求。如果您在多个 Docker 实例之间共享 /var/lib/docker 目录,获取它可能会起作用,尤其是在早期测试期间。但是尝试做一些更复杂的事情(从两个不同的实例中提取相同的镜像.....)。如果您的 CI 系统进行构建和重建,每次您将重新启动 Docker-in-Docker 容器时,您都可能会破坏它的缓存.

1.2 Docker run in Docker 方法

Docker run Docker的方式有三种

1.2.1 使用Sysbox运行时的Docker中的Docker

因为在特权模式下运行容器。Nestybox尝试通过使用sysbox Docker运行时来解决该问题。如果使用Nestybox sysbox运行时创建容器,则它可以在能够运行systemd,docker,kubernetes的容器内创建虚拟环境,而无需特权访问基础主机系统。解释sysbox需要足够的理解力,因此我不在本文的讨论范围之内。请参考此页面以全面了解sysbox。

Sysbox 是一个 OCI 运行时,可以用来代替 runc,或者作为 runc 的补充。它可以运行通常需要特权标志的“系统容器”,而无需特权标志;并在这些容器之间以及这些容器与其宿主之间提供足够的隔离。Sysbox 还提供了运行容器中容器的优化。具体来说,当并排运行多个 Docker 实例时,可以使用一组共享的镜像“播种”它们。这节省了大量磁盘空间和大量时间,我认为这在运行时会产生巨大的差异,例如容器中的 Kubernetes 节点。(在容器中运行 Kubernetes 节点对于 CI/CD 尤其有用,当您想要部署 Kubernetes 暂存应用程序或在其自己的集群中运行测试时,无需在专用机器上部署完整集群的基础架构成本和时间开销。)

步骤1:安装sysbox运行时环境。请参阅此页面以获取有关安装sysbox运行时的最新官方说明。sysbox:https://github.com/nestybox/sysbox
​
第2步:一旦拥有sysbox运行时可用,您要做的就是使用sysbox运行时标志启动docker容器,如下所示。在这里,我们使用的是官方docker dind映像。docker run --runtime=sysbox-runc --name sysbox-dind -d docker:dind步骤3:现在将exec会话带到sysbox-dind容器。docker exec -it sysbox-dind /bin/sh

1.2.2 Docker out of Docker

如果您只是希望能够从 CI 系统运行 Docker(特别是:构建、运行,有时推送容器和映像),而该 CI 系统本身位于容器中?您想要的只是一个解决方案,以便您的 CI 系统(如 Jenkins)可以启动容器。最简单的方法是将 Docker 套接字公开给 CI 容器,方法是使用 -v 标志绑定挂载它。简而言之,当您启动 CI 容器(Jenkins 或其他)时,不要使用 Docker-in-Docker 来破解某些东西,而是从以下内容开始:现在这个容器将可以访问 Docker 套接字,因此能够启动容器。除了启动“子”容器之外,它将启动“兄弟”容器。你可以是使用 docker 官方镜像(包含 Docker 二进制文件):

#启动的容器docker run -it -d -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker docker(镜像ID)#进入容器并使用docker sudo docker exec -it 容器(ID) /bin/bash#使用的docker的相关指令docker pulldocker pull busybox  

这看起来像 Docker-in-Docker,感觉像 Docker-in-Docker,但它不是 Docker-in-Docker:当这个容器将创建更多容器时,这些容器将在顶级 Docker 中创建。您不会遇到嵌套副作用,并且构建缓存将在多个调用之间共享。

Dockerfile内容以从容器内部测试映像构建。

​# 基础镜像FROM ubuntu:18.04# 安装依赖RUN apt-get update && apt-get install -y  apt-transport-https   ca-certificates   curl  gnupg-agent  software-properties-common# 安装秘钥RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -# 添加仓库RUN add-apt-repository   "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs) stable"# 安装docker RUN apt-get install docker-ce docker-ce-cli containerd.io -y
​
编译Dockerfiledocker build -t images_name .​Docker 的启动命令docker container run -it -v /var/run/docker.sock:/var/run/docker.sock testabc:1.0 /bin/bash
​

1.2.3 Docker In Docker(不推荐使用)

此方法实际上在容器内部创建一个子容器。仅当您确实要在容器中包含容器和镜像时才使用此方法。否则,我建议您使用第一种方法。为此,您只需要使用带有dind标签的官方docker镜像即可。该dind映像使用Docker所需的实用程序进行制作以在Docker容器中运行。

注意:这要求您的容器以特权模式运行。步骤1:建立dind-test以docker:dind镜像命名的容器docker run --privileged -d --name dind-test docker:dind步骤2:使用exec登录到容器。docker exec -it dind-test /bin/sh

现在,您可以尝试使用Dockerfile构建映像,如先前方法所示。关键注意事项

  • 仅在必要时在Docker中使用Docker。在将任何工作流程迁移到Docker-in-Docker方法之前,请进行足够的测试。
  • 如果您打算使用Nestybox(Sysbox),请确保已通过企业架构师/安全团队的测试和批准。
  • 在特权模式下使用容器时,请确保您已获得企业安全团队有关计划执行的必要批准。
  • 在带有kubernetes容器的Docker中使用Docker时,存在一些挑战。请参阅此博客以了解更多信息。

二、dockerfile制作python3.6.5+mysql5.6+redis的多镜像

2.1 dockerfile制作编写

# 基础镜像
FROM silverlogic/python3.6# 描述
MAINTAINER python3.6+mysql5.6+redis# 添加必要秘钥,以便添加apt库 archive.ubuntu.comRUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5# 换中国源,其中archive.ubuntu.com用于安装mysqlRUN mv /etc/apt/sources.list /etc/apt/sources.list.bak \
&& echo "deb http://mirrors.163.com/debian/ stretch main non-free contrib" >> /etc/apt/sources.list \
&& echo "deb http://mirrors.163.com/debian/ stretch-updates main non-free contrib" >>/etc/apt/sources.list \
&& echo "deb-src http://mirrors.163.com/debian/ stretch main non-free contrib" >>/etc/apt/sources.list \
&& echo "deb-src http://mirrors.163.com/debian/ stretch-updates main non-free contrib" >>/etc/apt/sources.list \
&& echo "deb http://archive.ubuntu.com/ubuntu trusty universe" >>/etc/apt/sources.list \
&& apt-get update# 安装mysql5.6
RUN { \
echo mysql-server mysql-server/root_password password '123456'; \
echo mysql-server mysql-server/root_password_again password '123456'; \
} | debconf-set-selections \
&& apt-get install -y mysql-server-5.6 mysql-client-5.6# 装redis
RUN apt install -y redis-server# 启动命令
ENTRYPOINT service mysql start && redis-server # 让进程一直跑, 否则容器会exit

2.2 dockerfile的构建

sudo docker build -t python3.6-mysql-redis .
# 创建+启动容器, 如果启动不了, 需要调试并修改dockerfile或启动脚本.需要外部连接的就用-p 暴露端口sudo docker run -itd -p 3308:3306 --name py_mysql_redis py_mysql_redis# 进入bashsudo docker exec -it python3.6-mysql-redis bash# 在容器里测试是否成功:mysql -uroot -p123456
redis-cli
python# 数据库端口暴露之后,在容器内部可以访问,但是外部还是无法连接进到 docker 容器里面修改一下mysql账号允许从远程登录就行,#by 后面是密码, 可自行修改。也是远程登录的密码 两条命令如下:grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;#刷新配置flush privileges;

博文参考

是否能在docker中装ubuntu,再嵌套部署启动一个docker? - 知乎
Using Docker-in-Docker for your CI or testing environment? Think twice.

Docker——Docker in Docker原理与实战相关推荐

  1. 深入浅出Docker原理及实战(三)——制作Dockerfile

    声明:这是我在大学毕业后进入第一家互联网公司学习的内容 深入浅出Docker原理及实战系列第三篇,我主要分享如何制作一个Dockerfile,以及基本命令格式. Dockerfile简介 Docker ...

  2. Java Spring Boot 2.0实战Docker容器与架构原理,视频与课件,基于Linux环境...

    Java Spring Boot 2.0实战Docker容器Linux与架构原理 内容摘要:Docker是最流行的开源容器引擎,Go语言开发,在互联网大规模集群.云计算.微服务等架构中广泛使用.本次课 ...

  3. Docker容器化实战第七课 容器编排Docker Compose、Docker Swarm 和 Kubernetes

    19 如何使用 Docker Compoe 解决开发环境的依赖? 前两个模块,我们从 Docker 的基本操作到 Docker 的实现原理,为你一步一步揭开了 Docker 神秘的面纱.然而目前为止, ...

  4. 老司机实战Windows Server Docker:2 docker化现有iis应用的正确姿势

    前言 上一篇老司机实战Windows Server Docker:1 初体验之各种填坑介绍了安装docker服务过程中的一些小坑.这一篇,我们来填一些稍大一些的坑:如何docker化一个现有的iis应 ...

  5. Docker学习总结(29)——Docker核心技术与实现原理

    提到虚拟化技术,我们首先想到的一定是 Docker,经过四年的快速发展 Docker 已经成为了很多公司的标配,也不再是一个只能在开发阶段使用的玩具了.作为在生产环境中广泛应用的产品,Docker 有 ...

  6. 转载与积累系列 - Docker 核心技术与实现原理

    目录 Namespaces 进程 网络 Libnetwork 挂载点 Chroot CGroups UnionFS 存储驱动 AUFS 其他存储驱动 总结 提到虚拟化技术,我们首先想到的一定是 Doc ...

  7. Docker 核心技术与实现原理

    提到虚拟化技术,我们首先想到的一定是 Docker,经过四年的快速发展 Docker 已经成为了很多公司的生产环境中大规模使用,也不再是一个只能在开发阶段使用的玩具了.作为在生产环境中广泛应用的产品, ...

  8. 后端技术杂谈10:Docker 核心技术与实现原理

    Docker 核心技术与实现原理 30 NOV 2017  docker  namespaces  cgroups  unionfs  aufs  server Namespaces 进程 网络 挂载 ...

  9. Docker教程(一):docker安装及运行原理

    前言 本文根据狂神说视频资料整理.https://www.bilibili.com/video/BV1og4y1q7M4?from=search&seid=164476847288957195 ...

最新文章

  1. Linux中的日志系统介绍
  2. MinGW安装与使用简介
  3. python编程做什么工作-学习Python编程后在成都可以做哪些工作?
  4. MultiByteToWideChar和WideCharToMultiByte用法详解
  5. mysql中标记某条数据库_一个关系数据库表中的各条记录可以什么
  6. Flot使用文档(转)
  7. jsp页面整体无法居中问题的解决方案
  8. Linux命令行中的特殊符号_特殊字符
  9. 微信小程序的不同函数调用的几种方法
  10. win7 能下node什么版本_微软从未公开的win10版本,3GB+极度精简,老爷机有救了
  11. vmware下Ubuntu屏幕分辨率设置
  12. 循序渐进之Spring AOP(2) - 基本概念
  13. 利用composer搭建PHP框架(三.模板引擎)
  14. 谷歌账号在谷歌浏览器无法登录,提示此浏览器或应用可能不安全的一种解决办法
  15. [Slackware13.0学习笔记]上网问题
  16. 应急指挥中心建设方案
  17. 视唱练耳——调式调号听辨
  18. python图像降噪
  19. 基于视觉的机器人抓取:从物体定位、物体姿态估计到平行抓取器抓取估计
  20. Matlab||EGM2008模型计算GOCE沿轨重力梯度及全球重力梯度分布

热门文章

  1. 23.Position-Aware Tagging for Aspect Sentiment Triplet Extraction阅读笔记
  2. 关于textrank算法
  3. python循环代码
  4. “在深圳,从工资5000到主管,我依然很焦虑”
  5. Matlab调用Python读取Abaqus模型操作
  6. GPS术语 -- 词汇与概念解释(四)
  7. PKUSC2022 游记
  8. iPad Air 2全然评測:可怕的三核CPU、六核GPU
  9. 一线城市java人才前景_2020年5大一线城市Java薪资水平汇总,你还差多少呢?
  10. C++基础---string类的构造函数