笔记 - 转 Docker 原理篇

本贴最后更新于 2222 天前,其中的信息可能已经天翻地覆

原文地址:

前提


docker 是 linux 系统上的,虽然官网提供了 windows 和 MacOS 版本的安装包,但它们都是靠虚拟机或类似的技术支撑的。换句话说,为了方便你的阅读,希望你已经了解些许 linux 的知识。

共识


docker 和容器不是一个意思,docker 包含实现虚拟化技术的一系列技术,而容器(container)只是其中的一个组件。

Docker 可以给你带来什么?


  1. 更快交付你的应用(Faster delivery of your applications)
  2. 让部署和测试更简单(Deploying and scaling more easily)
  3. 实现更高密度和更多的负载(Achieving higher density and running more workloads)

目标


Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案,创建软件程序可移植的轻量容器。

底层实现


  1. Docker 的基础是 Linux 容器(LXC)等技术。
  2. 在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。
  3. Docker 使用 Cgroups 来提供容器隔离,而 union 文件系统用于保存镜像并使容器变得短暂。

Cgroups:Cgroups 是 Linux 内核功能,它让两件事情变成可能:限制 Linux 进程组的资源占用(内存、CPU);为进程组制作 PID、UTS、IPC、网络、用户及装载命名空间。
Union 文件系统:在 union 文件系统里,文件系统可以被装载在其他文件系统之上,其结果就是一个分层的积累变化。如下图:

union 文件系统

与虚拟机的关系


用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
但是它们还是有很大的区别的,看下面两幅图:

virtualization 应用

docker 应用

官网的说法是:虚拟机上的应用不仅包含了应用本身、必要的依赖(二进制和库包等),还包括整个操作系统;而 docker 应用不同,共享系统内核,仅仅包含应用本身和依赖。

docker 的优势:

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于原生
系统支持量 单机支持上千个容器 一般几十个

docker 的特性:

  • 交互式 Shell:Docker 可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互 shell
  • 文件系统隔离:每个进程容器运行在完全独立的根文件系统里
  • 写时复制:采用写时复制方式创建根文件系统,这让部署变得极其快捷,并且节省内存和硬盘空间
  • 资源隔离:可以使用 cgroup 为每个进程容器分配不同的系统资源
  • 网络隔离:每个进程容器运行在自己的网络命名空间里,拥有自己的虚拟接口和 IP 地址
  • 日志记录:Docker 将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索
  • 变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置

详情请看:破修电脑的

打个比方


上面的概念很抽象吧,我说得通俗一些。

一般情况下

Linux(如 ubuntu)运行一个应用,如 tomcat,它需要依赖 Java 环境吧,其实就(可能)是把 Java 放在/usr/lib 下,然后配置用户环境,使你可以在 shell(如 bash)上使用 java 指令,(可选)然后关联 tomcat 的 bin 目录下的 startup.sh 到用户环境上,完成上面两个步骤,就可以把 tomcat 运行起来。

docker 方面

相对上面的 tomcat 例子,Docker 就是通过

  1. 使用 Cgroups 隔离计算机资源,使计算机可以运行很多的服务;

  2. 使用 Namespace 分离打包服务运行时需要的所有依赖——java、tomcat,方便移植到新的计算机上,可以看下图(MacOS 系统上运行 docker),你会发现此容器已经有 java 和 tomcat;

    MacOS 上 docker 运行 tomcat

  3. 使用 Union 文件系统,把所有的操作记录在 Dockerfile(构建镜像的蓝图);

  4. 还有两个特别重要的功能,映射端口和外挂数据卷,映射端口负责接受把 docker 容器里的某个端口与主机某个端口绑定(请看下面的注意),外挂数据卷就是把 war 包放置的路径映射到主机上的某个路径,达到业务逻辑和数据持久化分割开,是不是颇有 MVC 的熟悉感。

注意:这里的端口映射有一个坑,在非 Linux 上安装 docker(比如 Windows 和 MacOS),都是在本机上安装 Linux 的虚拟机,所有当你在 docker 运行 tomcat 时,访问“localhost:8080”是不会有响应的,你应该把 localhost 换成运行此 docker 的 Linux 虚拟机的 IP 地址。但是在 Linux 上,就可以通过"localhost:8080"访问到 tomcat。这坑很深,我刚接触 docker 就因为此坑差点放弃了。

Docker 结构引擎


引擎组件图

注意上图,显示的是 docker 主要组件。

  1. Server,就是一个守护进程,它会一直运行在后台;

  2. REST API,说明如何与 server 交互和指示它执行命令;

  3. Client,是客户书写指令的地方,也俗称 shell,看下图:

    iTerm 运行 docker

  4. Image,俗称镜像;

  5. Container,俗称容器,装载和运行镜像;

  6. Network,俗称网络,容器通过暴露端口与主机端口绑定,达到接受来自主机的信号;

  7. Volume,俗称外挂,为了能够持久化数据以及共享容器间的数据,Docker 提出了 Volume 的概念。

正如上面提到的内容,docker 的基础就是这几块内容。往深一点,就是 swarm 之类的云计算概念了。

Docker 运行流程


docker 运行流程

正如上图所示,当我们想运行一个容器的时候,docker 会:

  1. 拉取镜像,若本地已经存在该镜像,则不用到网上去拉取
  2. 创建新的容器
  3. 分配 union 文件系统并且挂着一个可读写的层,任何修改容器的操作都会被记录在这个读写层上,你可以保存这些修改成新的镜像,也可以选择不保存,那么下次运行改镜像的时候所有修改操作都会被消除
  4. 分配网络\桥接接口,创建一个允许容器与本地主机通信的网络接口
  5. 设置 ip 地址,从池中寻找一个可用的 ip 地址附加到容器上,换句话说,localhost 并不能访问到容器
  6. 运行你指定的程序
  7. 捕获并且提供应用输出,包括输入、输出、报错信息

参考 chareice 写的 Docker 介绍以及其相关术语、底层原理和技术
不知道你发现没有,镜像(image)很想 maven 里的依赖,它们有着异曲同工之妙。

作者:Mr_Alpha
链接:https://www.jianshu.com/p/7a58ad7fade4
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    492 引用 • 926 回帖
  • 容器
    12 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...