Docker 入门

480 阅读5分钟

前言

最近在学习 Docker 和使用 Docker,不过脑海里对 Docker 还没有一个高层次的理解,所以有了这篇文章。

文章为了保证语义,语言表达上尽量保留了一些 docker 概念,避免翻译不恰当误导读者。

注意,文章大量参考 Docker 官网文档,读者可以选择看官方文档。

Docker Overview

Docker 是一个开放的平台,通过它可以开发、发送和运行应用。

Docker 可以分离应用程序和基础设施,以便于快速交付软件。

像管理应用程序一样管理基础设施

基础设施即代码(Infrastructure as Code)

Docker Platform

提供了称为“容器”的松散隔离环境中打包和运行应用程序的功能。

轻量级容器,因为管理程序的额外负担大部分被 Docker 接管。

可以在主机和实际的虚拟机中 同时运行多个容器。

Docker Engine

  • C/S 架构
  • Server 是一个 daemon process
  • Docker daemon 进程可以创建和管理 Docker object,包括 Images、Containers、Network 和 Volumes。
  • REST API 是用来与 Docker daemon 通信,并指示 Docker daemon 做点什么的接口
  • 使用编写 Docker REST API 的脚本或者 docker 命令与 Server 交互
  • 命令行界面(CLI)客户端(docker 命令)

What Can I use Docker for

快速且一致的去交付应用程序

响应式部署和伸缩

同一机器上可运行多个 workloads

workloads 指的是计算机处理工作的能力,包括内存、CPU、I/O 等

Docker architecture

  • Docker 使用 C/S 架构。

  • Docker daemon 负责构建、运行和分发 Docker containers。

  • Docker client 和 Docker daemon 可以运行在相同的系统,Docker client 也可以连接远程 Docker daemon。

  • Docker client 和 Docker daemon 使用 REST API、UNIX sockets 或者网络接口通信。

Docker daemon

Docker daemon 负责监听 Docker API 的请求和管理 Docker object,包括 Images、Containers、Network 和 Volumes。一个 Docker daemon 可以与另一个 Docker daemon 进行交互,因此可以去管理 Docker services.

Docker client

Docker client(docker)是与 Docker daemon 交互的主要方式,交互使用的是 docker api,例如当我们执行 docker rundocker pulldocker push等命令时,Docker client 会负责把这些命令发送给 Docker daemon,由 Docker daemon 去执行这些命令,

Docker registries

  • Docker registries 是存储 Docker image 的地方。
  • Docker Hub 是一个全世界公用的 Docker registry。
  • Docker 默认从 Docker Hub 拉取 Image,或者推送 Image 到 Docker Hub。
  • 可以部署私人的 Docker Registry,例如使用 Docker Datacenter ,就包含了 Docker Trusted Registry。

Docker objects

IMAGES(镜像)

Docker image 是一个分层的结构,它作为一个只读(read-only)模板存在。公开发布的镜像可以被其他人使用,根据需要还可以被包含到另一个自定义的镜像中。

Docker image 通过编写 Dockerfile 文件并执行 docker build 来构建,构建好的 image 可以 push 到 docker registry 存储起来,需要的时候可以 pull 下来。

Dockerfile 提供了一些简单的语法用于声明 docker image 的结构,每声明一条命令,就会相应的增加一个层(layer),所以 docker image 是一个分层结构。

这种分层结构的好处是,当我们在 Dockerfile 文件中修改了某几条命令后,docker 只会重建发生变更的层就好,其它的层不需要重新构建,所以会显著提升构建速度。缺点是,层越多,Image 的体积就会越大,所以优化 Image 体积的方式之一可以从 减少层 入手。

CONTAINERS(容器)

Docker container 是 image 的运行时实例,通过 docker run <option> image 把镜像运行起来,docker daemon 就会帮我们重建一个 container,并分配网络、分配 IP 地址、隔离读写文件系统等底层操作。

可以使用 CLI 提供的 docker api 来管理 container,可以通过docker container --help来查看所有的 api 以及相应的描述

默认情况下,docker daemon 会使用宿主机网络来访问外部网络.

默认情况下,容器与其他容器及其主机相对隔离。可以控制容器的网络、存储或其他底层子系统与其他容器或主机的隔离程度。

SERVICES(服务)

通过使用 Docker Swarm 可以集群多个 Docker daemon,Services 允许您跨多个 Docker daemon 进程扩展 containers,每个 Docker daemon 都是通过 Docker API 进行互相通信。

Services 允许我们在 docker-compose.yml 中自定义所需的配置,例如指定时间的服务副本数量、当CPU达到某个值时自动增加服务副本数量,当 CPU 低于某个值时自动减少服务副本数量等,在一定程度上做到服务的自治和伸缩。

The underlying technology(底层技术)

Docker 是用 go 编写的,它利用 Linux 内核的几个特性来提供其功能,这些特性分别为:

Namespaces

Docker 使用了一个叫做 Namespaces 的技术为 Docker container 提供相互隔离的工作区。当我们运行 docker container 时,Docker 会为 Docker container 创建一系列的 namespaces

Namespaces 为 Docker container 提供了一个隔离层,Docker container 的访问权限仅限于当前 namespace

Docker引擎在Linux上使用如下名称空间:

  • The pid namespace: Process isolation (PID: Process ID).
  • The net namespace: Managing network interfaces (NET: Networking).
  • The ipc namespace: Managing access to IPC resources (IPC: InterProcess Communication).
  • The mnt namespace: Managing filesystem mount points (MNT: Mount).
  • The uts namespace: Isolating kernel and version identifiers. (UTS: Unix Timesharing System).

Control groups

用于约束 Docker container 运行时资源,例如可以限制特性容器的可用内存.

Union file systems

Docker Engine 使用 UnionFS 为 container 提供构建块。 Docker 引擎 可以使用多种 UnionFS 变体,包括 AUFS,btrfs,vfs 和 DeviceMapper。

详细的介绍可以看看维基百科的介绍,也可以看看外文。

Container format

Docker Engine 将命名空间,控制组和 UnionFS 组合成一个称为容器格式的包装器。 默认容器格式是 libcontainer。 将来,Docker 可以通过与 BSD Jails 或 Solaris Zones 等技术的集成来支持其他容器格式。

总结

Docker 提供了一种 Infrastructure as Code 的理念来帮助我们管理和配置硬件环境,通过使用 Docker CLI 来提高开发、发送和运行我们的应用,通过 Docker daemon 来管理我们的容器,通过 Docker registry 来存储我们的镜像,通过 Docker daemon 集群来搭建分布式可伸缩环境,通过使用 Linux 底层 技术来分配资源和构建互相隔离的运行环境等。