天天5分钟玩转Docker容器技术(二)

容器核心知识

本篇经过 Docker 讨论容器的核心知识。docker

概述

容器核心知识主要回答有关容器 What、Why 和 How 三个问题。其中 How 是重点,将从架构、镜像、容器、网络和存储几个方面进行讲解。数据库

What - 什么是容器?

容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序能够在几乎任何地方以相同的方式运行。开发人员在本身笔记本上建立并测试好的容器,无需任何修改就可以在生产系统的虚拟机、物理服务器或公有云主机上运行。django

容器与虚拟机安全

谈到容器,就不得不将它与虚拟机进行对比,由于二者都是为应用提供封装和隔离。服务器

容器由两部分组成:网络

  1. 应用程序自己
  2. 依赖:好比应用程序须要的库或其余软件

容器在 Host 操做系统的用户空间中运行,与操做系统的其余进程隔离。这一点显著区别于的虚拟机。架构

传统的虚拟化技术,好比 VMWare, KVM, Xen,目标是建立完整的虚拟机。为了运行应用,除了部署应用自己及其依赖(一般几十 MB),还得安装整个操做系统(几十 GB)。负载均衡

下图展现了两者的区别。运维

如图所示,因为全部的容器共享同一个 Host OS,这使得容器在体积上要比虚拟机小不少。另外,启动容器不须要启动整个操做系统,因此容器部署和启动速度更快,开销更小,也更容易迁移。socket

Why - 为何须要容器?

为何须要容器?容器到底解决的是什么问题?
简要的答案是:容器使软件具有了超强的可移植能力

容器解决的问题

咱们来看看今天的软件开发面临着怎样的挑战?

现在的系统在架构上较十年前已经变得很是复杂了。之前几乎全部的应用都采用三层架构(Presentation/Application/Data),系统部署到有限的几台物理服务器上(Web Server/Application Server/Database Server)。

而今天,开发人员一般使用多种服务(好比 MQ,Cache,DB)构建和组装应用,并且应用极可能会部署到不一样的环境,好比虚拟服务器,私有云和公有云。

一方面应用包含多种服务,这些服务有本身所依赖的库和软件包;另外一方面存在多种部署环境,服务在运行时可能须要动态迁移到不一样的环境中。这就产生了一个问题:

如何让每种服务可以在全部的部署环境中顺利运行?

因而咱们获得了下面这个矩阵:

各类服务和环境经过排列组合产生了一个大矩阵。开发人员在编写代码时须要考虑不一样的运行环境,运维人员则须要为不一样的服务和平台配置环境。对他们双方来讲,这都是一项困难而艰巨的任务。

如何解决这个问题呢?

聪明的技术人员从传统的运输行业找到了答案。

几十年前,运输业面临着相似的问题。

每一次运输,货主与承运方都会担忧因货物类型的不一样而致使损失,好比几个铁桶错误地压在了一堆香蕉上。另外一方面,运输过程当中须要使用不一样的交通工具也让整个过程痛苦不堪:货物先装上车运到码头,卸货,而后装上船,到岸后又卸下船,再装上火车,到达目的地,最后卸货。一半以上的时间花费在装、卸货上,并且搬上搬下还容易损坏货物。

这一样也是一个 NxM 的矩阵。

幸运的是,集装箱的发明解决这个难题。

任何货物,不管钢琴仍是保时捷,都被放到各自的集装箱中。集装箱在整个运输过程当中都是密封的,只有到达最终目的地才被打开。标准集装箱能够被高效地装卸、重叠和长途运输。现代化的起重机能够自动在卡车、轮船和火车之间移动集装箱。集装箱被誉为运输业与世界贸易最重要的发明。

Docker 将集装箱思想运用到软件打包上,为代码提供了一个基于容器的标准化运输系统。Docker 能够将任何应用及其依赖打包成一个轻量级、可移植、自包含的容器。容器能够运行在几乎全部的操做系统上。

其实,“集装箱” 和 “容器” 对应的英文单词都是 “Container”。
“容器” 是国内约定俗成的叫法,多是由于容器比集装箱更抽象,更适合软件领域的原故吧。

我我的认为:在老外的思惟中,“Container” 只用到了集装箱这一个意思,Docker 的 Logo 不就是一堆集装箱吗?


Docker 的特性

咱们能够看看集装箱思想是如何与 Docker 各类特性相对应的。

容器的优点

对于开发人员 - Build Once, Run Anywhere

容器意味着环境隔离和可重复性。开发人员只需为应用建立一次运行环境,而后打包成容器即可在其余机器上运行。另外,容器环境与所在的 Host 环境是隔离的,就像虚拟机同样,但更快更简单。

对于运维人员 - Configure Once, Run Anything

只须要配置好标准的 runtime 环境,服务器就能够运行任何容器。这使得运维人员的工做变得更高效,一致和可重复。容器消除了开发、测试、生产环境的不一致性。

How - 容器是如何工做的?

接下来学习容器核心知识的最主要部分。

咱们首先会介绍 Docker 的架构,而后分章节详细讨论 Docker 的镜像、容器、网络和存储。

Docker 架构详解

Docker 的核心组件包括:

  1. Docker 客户端 - Client
  2. Docker 服务器 - Docker daemon
  3. Docker 镜像 - Image
  4. Registry
  5. Docker 容器 - Container

Docker 架构以下图所示:

Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器能够运行在同一个 Host 上,客户端也能够经过 socket 或 REST API 与远程的服务器通讯。

Docker 客户端

最经常使用的 Docker 客户端是 docker 命令。经过 docker 咱们能够方便地在 Host 上构建和运行容器。

docker 支持不少操做(子命令),后面会逐步用到。

除了 docker 命令行工具,用户也能够经过 REST API 与服务器通讯。

Docker 服务器

Docker daemon 是服务器组件,以 Linux 后台服务的方式运行。

Docker daemon 运行在 Docker host 上,负责建立、运行、监控容器,构建、存储镜像。

默认配置下,Docker daemon 只能响应来自本地 Host 的客户端请求。若是要容许远程客户端请求,须要在配置文件中打开 TCP 监听,步骤以下:

1.编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service,在环境变量 ExecStart 后面添加 -H tcp://0.0.0.0,容许来自任意 IP 的客户端链接。

若是使用的是其余操做系统,配置文件的位置可能会不同。

2.重启 Docker daemon。

3.服务器 IP 为 192.168.56.102,客户端在命令行里加上 -H 参数,便可与远程服务器通讯。

info 子命令用于查看 Docker 服务器的信息。

Docker 镜像

可将 Docker 镜像当作只读模板,经过它能够建立 Docker 容器。

例如某个镜像可能包含一个 Ubuntu 操做系统、一个 Apache HTTP Server 以及用户开发的 Web 应用。

镜像有多种生成方法:

  1. 能够从无到有开始建立镜像
  2. 也能够下载并使用别人建立好的现成的镜像
  3. 还能够在现有镜像上建立新的镜像

咱们能够将镜像的内容和建立步骤描述在一个文本文件中,这个文件被称做 Dockerfile,经过执行 docker build <docker-file> 命令能够构建出 Docker 镜像,后面咱们会讨论。

Docker 容器

Docker 容器就是 Docker 镜像的运行实例。

用户能够经过 CLI(docker)或是 API 启动、中止、移动或删除容器。能够这么认为,对于应用软件,镜像是软件生命周期的构建和打包阶段,而容器则是启动和运行阶段。

Registry

Registry 是存放 Docker 镜像的仓库,Registry 分私有和公有两种。

Docker Hub(https://hub.docker.com/) 是默认的 Registry,由 Docker 公司维护,上面有数以万计的镜像,用户能够自由下载和使用。

出于对速度或安全的考虑,用户也能够建立本身的私有 Registry。后面咱们会学习如何搭建私有 Registry。

docker pull 命令能够从 Registry 下载镜像。 docker run 命令则是先下载镜像(若是本地没有),而后再启动容器。

Docker 组件如何协做?

一个完整的例子

还记得咱们运行的第一个容器吗?如今经过它来体会一下 Docker 各个组件是如何协做的。

容器启动过程以下:

  1. Docker 客户端执行 docker run 命令。
  2. Docker daemon 发现本地没有 httpd 镜像。
  3. daemon 从 Docker Hub 下载镜像。
  4. 下载完成,镜像 httpd 被保存到本地。
  5. Docker daemon 启动容器。

docker images 能够查看到 httpd 已经下载到本地。

docker ps 或者 docker container ls 显示容器正在运行。

小结

Docker 借鉴了集装箱的概念。标准集装箱将货物运往世界各地,Docker 将这个模型运用到本身的设计哲学中,惟一不一样的是:集装箱运输货物,而 Docker 运输软件。

每一个容器都有一个软件镜像,至关于集装箱中的货物。容器能够被建立、启动、关闭和销毁。和集装箱同样,Docker 在执行这些操做时,并不关心容器里到底装的什么,它无论里面是 Web Server,仍是 Database。

用户不须要关心容器最终会在哪里运行,由于哪里均可以运行。

开发人员能够在笔记本上构建镜像并上传到 Registry,而后 QA 人员将镜像下载到物理或虚拟机作测试,最终容器会部署到生产环境。

使用 Docker 以及容器技术,咱们能够快速构建一个应用服务器、一个消息中间件、一个数据库、一个持续集成环境。由于 Docker Hub 上有咱们能想到的几乎全部的镜像。

不知你们是否意识到,潘多拉盒子已经被打开。容器不但下降了咱们学习新技术的门槛,更提升了效率。

若是你是一个运维人员,想研究负载均衡软件 HAProxy,只须要执行 docker run haproxy,无需繁琐的手工安装和配置既能够直接进入实战。

若是你是一个开发人员,想学习怎么用 django 开发 Python Web 应用,执行 docker run django,在容器里随便折腾吧,不用担忧会搞乱 Host 的环境。

不夸张的说:容器大大提高了 IT 人员的幸福指数。

最小的镜像

镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器。

本章内容安排以下:

  1. 首先经过研究几个典型的镜像,分析镜像的内部结构。
  2. 而后学习如何构建本身的镜像。
  3. 最后介绍怎样管理和分发镜像。

镜像的内部结构

为何咱们要讨论镜像的内部结构?

若是只是使用镜像,固然不须要了解,直接经过 docker 命令下载和运行就能够了。

但若是咱们想建立本身的镜像,或者想理解 Docker 为何是轻量级的,就很是有必要学习这部分知识了。

咱们从一个最小的镜像开始吧。

hello-world - 最小的镜像

hello-world 是 Docker 官方提供的一个镜像,一般用来验证 Docker 是否安装成功。

咱们先经过 docker pull 从 Docker Hub 下载它。

docker images 命令查看镜像的信息。

hello-world 镜像居然还不到 2KB!

经过 docker run 运行。

其实咱们更关心 hello-world 镜像包含哪些内容。

Dockerfile 是镜像的描述文件,定义了如何构建 Docker 镜像。Dockerfile 的语法简洁且可读性强,后面咱们会专门讨论如何编写 Dockerfile。

hello-world 的 Dockerfile 内容以下:

只有短短三条指令。

  1. FROM scratch
    此镜像是从白手起家,从 0 开始构建。
  2. COPY hello /
    将文件“hello”复制到镜像的根目录。
  3. CMD ["/hello"]
    容器启动时,执行 /hello

镜像 hello-world 中就只有一个可执行文件 “hello”,其功能就是打印出 “Hello from Docker ......” 等信息。

/hello 就是文件系统的所有内容,连最基本的 /bin,/usr, /lib, /dev 都没有。

hello-world 虽然是一个完整的镜像,但它并无什么实际用途。一般来讲,咱们但愿镜像能提供一个基本的操做系统环境,用户能够根据须要安装和配置软件。

这样的镜像咱们称做 base 镜像。

做者:cloudman6

原文

相关文章
相关标签/搜索