Docker 概述

云计算基础概念

云计算的三种服务模式

  • SaaS(Software as a Service,软件即服务):表示软件的开发、管理、部署都交给第三方,不需要关心技术问题,可以拿来即用。普通用户接触到的互联网服务,几乎都是 SaaS。
  • PaaS(Platform as a Service,平台即服务):PaaS 提供软件部署平台(runtime),抽象掉了硬件和操作系统细节,可以无缝地扩展。开发者只需要关注自己的业务逻辑,不需要关注底层。
  • IaaS(Infrastructure as a Service,基础设施即服务):IaaS 是云服务的最底层,主要提供一些基础资源。它与 PaaS 的区别是,用户需要自己控制底层,实现基础设施的使用逻辑。

img

上图中,绿色的部分是云服务商决定的,灰色的部分是用户决定的。可以看到,SaaS 模式下用户没有任何自主权,只能使用给定的应用程序;PaaS 模式下可以自己安装应用程序,但是不能定制操作系统;IaaS 模式下则是云服务商提供(虚拟的)硬件,从操作系统开始都可以自己选择和定制。

(该部分内容转载自阮一峰的IaaS,PaaS,SaaS 的区别,原文有更生动的描述。)

Docker Platform

Docker 提供了在隔离环境中打包和运行应用的能力,这里“隔离的环境”指的就是容器(container)。容器的隔离性是通过Linux Namespace技术实现的,它使得我们可以在一个宿主机上同时运行多个容器。容器是轻量级的,因为容器与容器之间共享宿主机的内核(host machine’s kernel),而不需要 Hypervisor。

关于Hypervisor,简单了解如下:

通俗来讲,Hypervisor是一种将操作系统与硬件抽象分离的方法,以达到host machine的硬件能同时运行一个至多个虚拟机作为guest machine的目的,这样能够使得这些虚拟机高效地分享主机硬件资源。

最主要的,我们需要搞清楚“容器”与“虚拟机”的区别。

容器 vs 虚拟机

VM 利用 Hypervisor 虚拟化技术来模拟 CPU、内存等硬件资源,这样就可以在宿主机上建立一个 Guest OS,就是常说的安装一个虚拟机。

每一个 Guest OS 都有一个独立的内核,比如 Ubuntu、CentOS 甚至是 Windows 等,在这样的 Guest OS 之下,每个应用都是相互独立的,VM 可以提供一个更好的隔离效果。但这样的隔离效果需要付出一定的代价,因为需要把一部分的计算资源交给虚拟化,这样就很难充分利用现有的计算资源,并且每个 Guest OS 都需要占用大量的磁盘空间,比如 Windows 操作系统的安装需要 10~30G 的磁盘空间,Ubuntu 也需要 5~6G,同时这样的方式启动很慢。正是因为虚拟机技术的缺点,催生出了容器技术。

容器是针对于进程而言的,因此无需 Guest OS,只需要一个独立的文件系统提供其所需要文件集合即可。所有的文件隔离都是进程级别的,因此启动时间快于 VM,并且所需的磁盘空间也小于 VM。当然了,进程级别的隔离并没有想象中的那么好,隔离效果相比 VM 要差很多

Docker Engine

Docker Engine 是一个client-server 应用,主要有以下组件:

  • server:一个始终在运行的后台进程(docker daemon),即dockerd命令(这个命令一般用不到);
  • REST API:应用程序通过调用REST API与docker daemon进程交互;
  • command line interface(CLI) client:即docker run...这个命令中的docker

Docker architecture

Docker 使用典型的 client-server 架构,Docker client 与 Docker daemon 交互,后者负责 Docker container 的构建、运行和分发工作。Docker client 可以与 daemon 运行在同一个系统上,或者,Docker client 也可以与远程的 daemon 进行连接交互。

架构图如下:(图片来自官网)

Docker daemon

Docker daemon(dockerd) 监听Docker client的请求,并管理Docker的对象,比如镜像(images)、容器(container)、网络(networks)和数据卷(volume)。daemon 同时也会与其他 daemon 进行通信,以此支撑起整个Docker服务。

Docker client

当你发送诸如docker run命令时,Docker client(docker)便会把这些命令发送给 dockerd,由后者来真正的执行。

Docker registry

Docker registry(注册表/注册中心?) 是存放Docker images的地方,Docker Hub 是任何人都可以使用的公共注册中心。默认情况下,Docker 就是从 Docker Hub 中拉取镜像的。当然,对于国内的网络环境而言,很多时候拉取镜像会非常慢,于是就要配置成国内的镜像源,需要在 /etc/docker/daemon.json文件(一开始并不存在这个文件,需手动创建之)中配置如下内容。这个问题新手经常遇到,比如docker pull执行失败,往往配置成国内的镜像源就可以解决了。

{
        "registry-mirrors": [
                "https://kfwkfulq.mirror.aliyuncs.com",
                "https://2lqq34jg.mirror.aliyuncs.com",
                "https://pee6w651.mirror.aliyuncs.com",
                "https://registry.docker-cn.com",
                "http://hub-mirror.c.163.com"
        ]
}

当执行docker pulldocker run命令时,会从配置好的registry中拉取镜像;当执行docker push命令时,就会把你的镜像推到相应的registry上去。

Docker objects

image

镜像是用于创建Docker container的只读(read-only)模板。

我们可以自行构建镜像(通过docker build命令或docker commit命令),或者直接从registry上拉取别人的镜像(通过docker pull的方式)。这里主要说一下镜像的构建。

如果采用docker build的方式构建镜像,就需要编写Dockerfile文件,每执行一行Dockerfile指令,就会在镜像中创建一层(layer)。如果改动Dockerfile文件重新build,只会在发生变化的层重建,这也是为何容器如此轻量的原因。

而采用docker commit的方式构建镜像,是基于当前容器进行构建的。

container

container是运行着的镜像实例。

总结:可以这么理解,Docker镜像是Docker容器的静态视角,而Docker容器是Docker镜像的运行状态。

示例:分析docker run命令的执行流程

$ docker run -i -t ubuntu /bin/bash

当执行这条命令时,会发生什么?

  1. 如果在本地不存在ubuntu这个镜像,那么,Docker首先会从你配置的registry中拉取镜像,就像你手动执行了一次docker pull ubuntu命令一样;
  2. 随后Docker就会创建一个新的容器,就像你手动执行了docker container create命令一样;
  3. Docker分配一个可读写子文件系统给容器,作为容器的最上层。这使得运行着的容器能够创建或修改本地的文件和目录;(注:这一步非常关键,理解起来也比较抽象,涉及到镜像的分层机制,可以说是容器最重要的一个部分)
  4. Docker创建一个网络接口,把容器与指定的网络进行连接(由于该例子的命令没有指定网络参数,就采用默认的网络模式,即bridge模式;如果docker run命令中指定了--net参数,就会选择对应的网络模式)。这一步会给容器分配一个ip地址。(注:这一步则涉及到了容器网络相关的知识,也是非常重要~)
  5. Docker启动容器并执行/bin/bash命令。由于容器以交互的方式运行并连接到终端(-i, -t参数),相当于此时我们已经进入到了这个容器里面,可以在里面执行一些其他操作;
  6. 当输入exit命令时,表示结束/bin/bash进程,此时容器停止,但不会被移除。可以执行上述命令重新启动它,当然也可以通过docker rm container_id删除它。

构建镜像、拉取镜像、提交镜像等命令的执行示意图:

总结

  1. 本节内容首先了解了一下云计算的基础概念,虽然在我学习云计算之初,该领域便进入了“容器时代”,但了解SaaS/PaaS/IaaS这些基本概念还是非常有必要;在容器出现之前,都是通过虚拟机来实现资源隔离,因此,从面试的角度来讲,面试官肯定会问你”虚拟机与容器的区别“,而在出现容器技术之后,就有了各种应用”容器化“的故事;
  2. 随后参照官网简述了“什么是 Docker”,我们平时所说的Docker一般指的就是容器,虽然这并不影响日常工作,但请注意,不要把”Docker“和”容器“的概念混淆。Docker 其实是一个基于容器技术的平台(比如它提供了镜像的分发、管理功能,还提供了REST API和CLI等等);而容器本身只是一个基于Linux内核(namespace & cgroup)的技术,从本质上它就是操作系统的一个进程而已。
  3. 随后简单了解镜像(image)和容器(container)的概念,并知道了docker run ...背后的执行流程,对这个流程理解的越细,就对Docker的各个组件、原理掌握的越深。

参考:

  1. https://docs.docker.com/get-started/overview/
  2. https://edu.aliyun.com/lesson_1651_13082?spm=5176.254948.1334973.4.306bcad2EKcDZy#_13082
  3. http://www.ruanyifeng.com/blog/2017/07/iaas-paas-saas.html
posted @ 2020-05-23 15:38  kkbill  阅读(302)  评论(0编辑  收藏  举报