Docker

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的cgroup,namespace,以及AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker优势

更高效的利用系统资源

容器不需要进行硬件虚拟以及运行完整操作系统等额外开销

更快速的启动时间

Docker 容器应用直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间

一致的运行环境

Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性

持续交付和部署

Docker 通过定制应用镜像来实现持续集成、持续交付、部署

  • 通过 Dockerfile 来进行镜像构建
  • 结合 持续集成(Continuous Integration) 系统进行集成测试
  • 可以直接在生产环境中快速部署该镜像
  • 结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署
  • 使用 Dockerfile 使镜像构建透明化
更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易

更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。

基本概念

镜像

Docker 镜像(Image),就相当于是一个 root 文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数。

镜像不包含任何动态数据,其内容在构建之后也不会被改变。

分层存储

在Docker 设计时,就充分利用 Union FS的技术,将其设计为分层存储的架构。

镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。

分层存储的特征还使得镜像的复用、定制变的更为容易。

容器

镜像( Image )和容器( Container )的关系,就像是面向对象程序设计中的实例 一样,镜像是静态的定义,容器是镜像运行时的实体。

容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,容器进程运行于属于自己的独立的 命名空间

容器内的进程是运行在一个隔离的环境里。这种特性使得容器封装的应用比直接在宿主运行更加安全。

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。容器存储层的生存周期和容器一样。

所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器。

Docker Registry

如果需要在其它服务器上镜像,我们就需要一个集中的存储、分发镜像的服务,即 Docker Registry。

一个 Docker Registry 中可以包含多个 仓库( Repository );每个仓库可以包含多个 标签( Tag );每个标签对应一个镜像

一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的
各个版本,通过 <仓库名>:<标签> 的格式来指定,如ubuntu:16.04 或者 ubuntu:18.04,如果忽略标签,比如 ubuntu ,那将视为
ubuntu:latest

安装 Docker

以Windows为例,安装Docker的步骤如下:

要求

确保自己的电脑开启 了Hyper-V功能,可在控制面板-程序-程序和功能的启用或关闭Windows中找到,此操作安装CenterOS 7 时,Hyper-V不能与WMware一起使用。

下载

  1. 可在Docker官网下载最新的Docker for Windows版本。
  2. 或是直接点击链接下载 Stable 或 Edge 版本。

镜像加速

在 Docker 菜单选择Settings ,左侧导航菜单选择Daemon 。在 Registrymirrors 一栏中填写加速器地址 ++https://dockerhub.azk8s.cn++ ,点击Apply 保存, Docker 重启并应用配置的镜像地址。

使用镜像

获取镜像

从Docker 镜像仓库获取镜像的命令是 docker pull 。其命令格式为:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
  • Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub。
  • 仓库名:仓库名格式是两段式名称,即 <用户名>/<软件名> 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。

以下载CenterOS 为例

docker pull daocloud.io/centos:latest

即从 daocloud.io 中的 centos仓库来下载标记为 latest的最新镜像

使用镜像

有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。

运行容器的命令是 docker run ,以下示例是启动一个 bash 终端 , 切记,路径前不要加 /

docker run -it --rm ubuntu:18.04 /bin/bash
    或
docker run -it --rm centos:latest /bin/bash

进入centeros系统也可以使用命令
docker exec -it centos7 /bin/bash

列出镜像

docker images ls 可以列出已经下载下来的镜像

列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。

可以用 docker system df 来便捷的查看镜像、容器、数据卷所占用的空间

虚悬镜像

当使用 docker pulldocker build 得到新镜像时,由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image)。

一般来说,虚悬镜像是可以随意删除的,可以用 docker image prunedocker image rm 删除

中间层镜像

由于 Docker 镜像是多层存储结构,因此同镜像会利用 中间层镜像

docker images ls 只会列出顶层镜像,使用 docker image ls -a 列出所有镜像(包括中间层镜像)

过滤器

可以使用 –filter-f 设定参数列出部分镜像
如仅列出虚悬镜像

docker image ls -f dangling=true
特定格式

一般而言,列出镜像会列出以下内容

  • REPOSITORY
  • TAG
  • IMAGE ID
  • CREATED
  • SIZE

通过 docker image ls -q 仅列出镜像id,或通过

docker image ls --format "{{.ID}}: {{.Repository}}"

列出指定格式的镜像列表

删除本地镜像

使用 docker image rm 删除本地的镜像,其格式为

docker image rm [选项] <镜像1> [<镜像2> ...]

其中, <镜像> 可以是 镜像长/短ID、镜像名或镜像摘要
可以使用 docker image ls --digests列出镜像摘要

操作容器

启动

让容器输出“Hello world”

docker run ubuntu:18.04 /bin/echo 'Hello world'

启动一个 bash 终端,允许用户进行交互

docker run -it --rm ubuntu:18.04 /bin/bash
    或
docker run -it --rm centos:latest /bin/bash

docker run命令运行时,Docker会进行如下操作,

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载(也就是说,可以不先获取镜像直接运行,Docker会帮你自动下载镜像)
  • 利用镜像创建并启动一个容器(类似于为一个类创建一个对象)
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序(如/bin/echo 'Hello world’和/bin/bash)
  • 执行完毕后容器被终止

启动已终止容器

利用 docker container start 重启已经终止的容器

  • 并且,像上述新建启动/bash,容器中仅运行了指定的 bash应用。

这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。

后台(守护态)运行

可以通过 docker run-d参数让容器在Docker的后台运行,而不影响当前宿主机

docker run -dit --name=[NAME] centos:latest /usr/sbin/init
  或
docker run -dit --privileged --name=[NAME] centos:latest /usr/sbin/init

开启 –privileged可以修改容器的内核参数

为一个centos:latest建立容器在后台运行,并制定别名。
之后可以通过

docker exec -it [NAME] /bin/bash

进入容器

要获取容器的输出信息,可以通过

docker container logs [container ID or NAMES]

查看结果

后台运行的容器可以通过 docker container lsdocker container ls -a 进行查看

终止容器(进行容器状态更改)

并且可以通过 docker container start , docker container stop , docker container restart 来进行容器状态的更改

进入容器

可以使用 docker attachdocker exec(推荐) 两种命令进入容器

上述两种方式的区别在于 exec 可以跟多个参数 如 -it(会进入到熟悉的Linux命令界面) ,这与直接使用 attach结果相似。但 attach进入容器后, exit退出容器会导致容器终止,但 exec 不会。

导出和导入容器

使用 docker export 命令导出容器快照到本地文件。

docker export [docker container] > ubuntu.tar

使用 docker import 从容器快照文件中再导入为镜像(示例在Linux环境下)。

cat ubuntu.tar | docker import - test/ubuntu:v1.0

也可以通过指定 URL 或者某个目录来导入

docker import http://example.com/exampleimage.tgz example/imagerepo

同样的,也可以使用 docker load 导入镜像存储文件到本地镜像库,但这样的文件比较完整,相较于快照体积较大。

删除容器

使用 docker container rm 来删除一个处于终止状态的容器

要删除一个运行中的容器,可以添加 -f 参数

使用 docker container prune 可以清理掉所有处于终止状态的容器