前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版

Docker入门基础篇 镜像容器网络数据卷与Compose全梳理

首页2018-11-20 10:12:08Back-End
Docker部署容器运维

第一次接手一台要上线的服务器,最容易卡住的不是写业务代码,而是「环境」两个字。本地跑得好好的服务,传到测试机上就报缺库;测试机调通了,生产机的系统版本又不一样。我自己那会儿最狼狈的一次,是照着一份环境搭建文档一条条敲命令,敲到第 30 行发现前面某个包装错了版本,只能推倒重来。

Docker 就是来终结这种循环的。它把「环境」本身变成一个可以打包、可以传输、可以版本化的东西。

这篇是我系统过一遍 Docker 基础时整理的笔记,内容源自掘金小册的 Docker 资料,我按自己实际用到的场景重新归了类。它不是命令速查表,而是按「你在什么时候会用到这一组命令」来组织的:先搞清楚镜像和容器是什么关系,再按容器生命周期、网络、数据卷、Dockerfile、Compose 的顺序往下走。读完你应该能独立把一套 MySQL + Redis + 应用的开发环境用 Compose 跑起来,并且知道出问题时该往哪儿看。

在本篇文章中,我们将从浅入深,和大家一起学习以下知识:

  • Docker 的四大对象(镜像、容器、网络、数据卷)分别在解决什么问题
  • 各系统下安装 Docker Engine 的方式,以及 Docker Desktop 在 Windows/macOS 上到底做了什么
  • 镜像的命名规则、拉取、搜索、查看与删除,以及 ID 前缀匹配这个省事的小机制
  • 容器的五种状态与主进程机制,create / start / run / exec / attach 各自的适用场景
  • 容器网络的三个核心概念,容器互联、端口暴露与端口映射的区别
  • 三种挂载方式(Bind Mount、Volume、Tmpfs Mount)怎么选
  • 镜像的提交、命名、导出导入与批量迁移
  • Dockerfile 的结构与常见指令,构建缓存、命令合并、ENTRYPOINT 与 CMD 的配合
  • 怎么读懂 Docker Hub 上的镜像标签,Alpine 镜像的取舍
  • Docker Compose 的配置写法与常用配置项,以及一个完整的 PHP 项目目录结构
  • 用 Docker Swarm 搭 Overlay 网络,让跨主机的容器互相看见

本文写于 2018 年,命令与写法保留当时的原貌。文中凡是已经过时的部分(比如 docker-compose 带横线的命令、compose 文件的 version 字段、MAINTAINER 指令、国内镜像加速地址),我都另起一小段标注了现在的情况,具体细节以官方文档为准。

# 一、Docker 的四大组成对象

先说结论,Docker 后面所有的命令,docker images、docker run、docker network create、docker volume,本质都是在操作这四个对象中的某一个。把这四个对象的关系理顺,命令是什么形状你基本能猜个八九不离十,反过来如果一上来就背命令,很快就会记混。

在 Docker 体系里,有四个对象 (Object) 是我们不得不进行介绍的,因为几乎所有 Docker 以及周边生态的功能,都是围绕着它们所展开的。它们分别是:镜像 ( Image )、容器 ( Container )、网络 ( Network )、数据卷 ( Volume )…

这一节不涉及任何命令,纯粹是建立心智模型。你可以把它当成后面十五章的地图。

# 1.1 镜像

所谓镜像,可以理解为一个只读的文件包,其中包含了虚拟环境运行最原始文件系统的内容

只读这两个字是关键。镜像一旦构建出来就不会再变,所有对它的「修改」都不是原地改,而是往上叠一层。这个设计后面会反复出现,构建缓存、镜像层共享、docker commit,讲的都是同一件事。

# 1.2 容器

容器就是用来隔离虚拟环境的基础设施,而在 Docker 里,它也被引申为隔离出来的虚拟环境。

  • 如果把镜像理解为编程中的类,那么容器就可以理解为类的实例。镜像内存放的是不可变化的东西,当以它们为基础的容器启动后,容器内也就成为了一个「活」的空间

Docker 的容器应该有三项内容组成

  • 一个 Docker 镜像
  • 一个程序运行环境
  • 一个指令集合

类和实例这个类比很好用,但有一点要拎清楚:同一个镜像可以起出几十个容器,它们共享底下那几层只读镜像层,各自只多出一层可读写的沙盒。所以起十个 nginx 容器并不会占十份 nginx 镜像的磁盘。这个我一开始也想岔过,以为容器多了硬盘就会被吃光。

# 1.3 网络

在 Docker 中,实现了强大的网络功能,我们不但能够十分轻松的对每个容器的网络进行配置,还能在容器间建立虚拟网络,将数个容器包裹其中,同时与其他网络环境隔离

Docker 能够在容器中营造独立的域名解析环境,这使得我们可以在不修改代码和配置的前提下直接迁移容器,Docker 会为我们完成新环境的网络适配。对于这个功能,我们甚至能够在不同的物理服务器间实现,让处在两台物理机上的两个 Docker 所提供的容器,加入到同一个虚拟网络中,形成完全屏蔽硬件的效果…

# 1.4 数据卷

  1. 除了网络之外,文件也是重要的进行数据交互的资源。在以往的虚拟机中,我们通常直接采用虚拟机的文件系统作为应用数据等文件的存储位置。然而这种方式其实并非完全安全的,当虚拟机或者容器出现问题导致文件系统无法使用时,虽然我们可以很快的通过镜像重置文件系统使得应用快速恢复运行,但是之前存放的数据也就消失了。
  2. 为了保证数据的独立性,我们通常会单独挂载一个文件系统来存放数据。这种操作在虚拟机中是繁琐的,因为我们不但要搞定挂载在不同宿主机中实现的方法,还要考虑挂载文件系统兼容性,虚拟操作系统配置等问题。值得庆幸的是,这些在 Docker 里都已经为我们轻松的实现了,我们只需要简单的一两个命令或参数,就能完成文件系统目录的挂载。
  3. 能够这么简单的实现挂载,主要还是得益于 Docker 底层的 Union File System 技术。在 UnionFS 的加持下,除了能够从宿主操作系统中挂载目录外,还能够建立独立的目录持久存放数据,或者在容器间共享。
  4. 在 Docker 中,通过这几种方式进行数据共享或持久化的文件或目录,我们都称为数据卷 ( Volume )…

四个对象串起来看是这样的:镜像决定了容器里有什么,容器决定了程序怎么跑,网络决定了容器能和谁说话,数据卷决定了哪些东西在容器被删掉之后还能留下来。后面每一章其实都在展开其中一个。

# 二、搭建运行Docker环境

这一组内容什么时候用得上?拿到一台新的云主机、换新电脑、或者给团队新同事配开发机的时候。装 Docker 本身不难,难的是装完发现内核版本不够、或者拉镜像卡在 0%,这两个坑下面都会讲到。

# 2.1 Docker Engine 的版本

对于 Docker Engine 来说,其主要分为两个系列

  • 社区版 ( CE, Community Edition )
  • 企业版 ( EE, Enterprise Edition )
  1. 社区版 ( Docker Engine CE ) 主要提供了 Docker 中的容器管理等基础功能,主要针对开发者和小型团队进行开发和试验。而企业版 ( Docker Engine EE ) 则在社区版的基础上增加了诸如容器管理、镜像管理、插件、安全等额外服务与功能,为容器的稳定运行提供了支持,适合于中大型项目的线上运行…

  2. 社区版和企业版的另一区别就是免费与收费了。对于我们开发者来说,社区版已经提供了 Docker 所有核心的功能,足够满足我们在开发、测试中的需求,所以我们直接选择使用社区版进行开发即可。在这本小册中,所有的内容也是围绕着社区版的 Docker Engine 展开的…

  3. 从另外一个角度,Docker Engine 的迭代版本又会分为稳定版 ( Stable release ) 和预览版 ( Edge release )。不论是稳定版还是预览版,它们都会以发布时的年月来命名版本号,例如如 17 年 3 月的版本,版本号就是 17.03…

  4. Docker Engine 的稳定版固定为每三个月更新一次,而预览版则每月都会更新。在预览版中可以及时掌握到最新的功能特性,不过这对于我们仅是使用 Docker 的开发者来说,意义并不是特别重大的,所以我还是更推荐安装更有保障的稳定版本。

  5. 在主要版本之外,Docker 官方也以解决 Bug 为主要目的,不定期发布次要版本。次要版本的版本号由主要版本和发布序号组成,如:17.03.2 就是对 17.03 版本的第二次修正…

现状补充:Docker Engine CE / EE 这套命名后来调整过,社区版就叫 Docker Engine,商业形态归到 Docker Desktop 的订阅里;年月式版本号(17.03 这种)也换成了普通的语义化版本。安装命令的包名 docker-ce 在主流发行版仓库里目前还在用,但要不要装、装哪个包,还是以你所用发行版对应的官方安装文档为准。下面这几段安装命令保留 2018 年的原样,看的时候留意一下就行。

# 2.2 Docker 的环境依赖

  • 由于 Docker 的容器隔离依赖于 Linux 内核中的相关支持,所以使用 Docker 首先需要确保安装机器的 Linux kernel中包含 Docker 所需要使用的特性。以目前 Docker 官方主要维护的版本为例,我们需要使用基于 Linux kernel 3.10 以上版本的 Linux 系统来安装 Docker.…
  • 也许 Linux kernel 的版本还不够直观,下面的表格就直接展示了 Docker 对主流几款 Linux 系统版本的要求
操作系统 支持的系统版本
CentOS CentOS 7
Debian Debian Wheezy 7.7 (LTS)
Debian Jessie 8 (LTS)
Debian Stretch 9
Debian Buster 10
Fedora Fedora 26 、Fedora 27
Ubuntu Ubuntu Trusty 14.04 (LTS)
Ubuntu Xenial 16.04 (LTS)
Ubuntu Artful 17.10...

# 2.3 在 Linux 系统中安装 Docker

因为 Docker 本身就基于 Linux 的核心能力,同时目前主流的 Linux 系统中所拥有的软件包管理程序,已经可以很轻松的帮助我们处理各种依赖问题,所以在 Linux 中安装 Docker 并非什么难事

下面四组命令做的是同一件事,只是包管理器不同:先装上添加第三方仓库所需要的工具,再把 Docker 官方仓库地址加进去,然后装 docker-ce,最后把服务设成开机自启并立刻启动。你只需要照着自己机器的发行版挑一组执行。

CentOS

$ sudo yum install yum-utils device-mapper-persistent-data lvm2
$
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce
$
$ sudo systemctl enable docker
$ sudo systemctl start docker...
@前端进阶之旅: 代码已经复制到剪贴板

Debian

fe
  • 一、Docker 的四大组成对象
    • 1.1 镜像
    • 1.2 容器
    • 1.3 网络
    • 1.4 数据卷
  • 二、搭建运行Docker环境
    • 2.1 Docker Engine 的版本
    • 2.2 Docker 的环境依赖
    • 2.3 在 Linux 系统中安装 Docker
    • 2.4 上手使用
  • 三、在 Windows 和 Mac 中使用 Docker
    • 3.1 Docker Desktop
    • 3.2 启动 Docker
    • 3.3 Docker Desktop 的实现原理
    • 3.4 主机文件挂载
  • 四、镜像与容器的关系
    • 4.1 Docker 镜像
    • 4.2 查看镜像
    • 4.3 镜像命名
    • 4.4 容器的生命周期
    • 4.5 主进程
  • 五、从镜像仓库获得镜像
    • 5.1 镜像仓库
    • 5.2 获取镜像
    • 5.3 Docker Hub
    • 5.4 搜索镜像
    • 5.5 管理镜像
    • 5.6 删除镜像
  • 六、运行和管理容器
    • 6.1 容器的创建和启动
    • 6.2 创建容器
    • 6.3 启动容器
    • 6.4 管理容器
    • 6.5 停止和删除容器
    • 6.6 随手删除容器
    • 6.7 进入容器
    • 6.8 衔接到容器
  • 七、为容器配置网络
    • 7.1 容器网络
    • 7.2 浅析 Docker 的网络实现
    • 7.3 容器互联
    • 7.4 暴露端口
    • 7.5 通过别名连接
    • 7.6 管理网络
    • 7.7 创建网络
    • 7.8 端口映射
    • 7.9 在 Windows 和 macOS 中使用映射
  • 八、管理和存储数据
    • 8.1 数据管理实现方式
    • 8.2 挂载方式
    • 8.3 挂载文件到容器
    • 8.4 挂载临时文件目录
    • 8.5 使用数据卷
  • 九、保存和共享镜像
    • 9.1 提交容器更改
    • 9.2 为镜像命名
    • 9.3 镜像的迁移
    • 9.4 导入镜像
    • 9.5 批量迁移
    • 9.6 导出和导入容器
  • 十、通过 Dockerfile 创建镜像
    • 10.1 关于 Dockerfile
    • 10.2 环境搭建与镜像构建
    • 10.3 编写 Dockerfile
    • 10.4 Dockerfile 的结构
    • 10.5 常见 Dockerfile 指令
    • 10.6 构建镜像
  • 十一、常见 Dockerfile 使用技巧
    • 11.1 构建中使用变量
    • 11.2 环境变量
    • 11.3 合并命令
    • 11.4 构建缓存
    • 11.5 搭配 ENTRYPOINT 和 CMD
    • 11.6 临摹案例
  • 十二、使用 Docker Hub 中的镜像
    • 12.1 选择镜像与程序版本
    • 12.2 Alpine 镜像
    • 12.3 对容器进行配置
    • 12.4 共享自己的镜像
  • 十三、使用 Docker Compose 管理容器
    • 13.1 解决容器管理问题
    • 13.2 安装 Docker Compose
    • 13.3 Docker Compose 的基本使用逻辑
  • 十四、常用的 Docker Compose 配置项
    • 14.1 定义服务
    • 14.2 文件挂载
    • 14.3 配置网络
  • 十五、编写一个完整的 Docker Compose 项目
    • 15.1 设计项目的目录结构
    • 15.2 编写 Docker Compose 配置文件
    • 15.3 编写辅助脚本
  • 十六、应用于服务化开发
    • 16.1 服务开发环境
    • 16.2 搭建本地环境
    • 16.3 跨主机网络
  • 总结
  • 参考

← Docker小结篇pm2使用小结 →