3000 字了解什么是 Docker

104 阅读9分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Docker

一个项目在 windows 上开发完成后, 要想部署在 linux 上, 还需要重新搭建一套一模一样的环境, 不但费时费力, 而且运行环境的一致性难以保证, 不同环境之间迁移成本太高.

Docker 则从根本上解决了这个问题, 软件可以带环境安装. 也就是说, 安装软件的时候, 带有软件的运行环境. 利用 Docker 可以消除不同系统之间的配置问题.

Docker是 解决了运行环境和配置问题的一个软件容器, 方便做持续集成并有助于整体发布的一种容器虚拟化技术.

传统上软件开发产出的成果是程序或能够编译执行的二进制字节码文件, 而为了让程序执行, 需要准备完整的配置文件+软件环境. Docker 镜像的设计, 可以 通过镜像(images)将作业系统核心除外, 运作应用程序所需要的系统环境, 由下而上打包, 达到应用程式跨平台间的无缝接轨运行.

Docker 通过对应用程序的部署, 运行等生命周期的管理, 使项目及其运行环境能够做到一次封装, 到处运行. 将应用运行在 Docker 容器上面, 而 Docker 容器在任何操作系统上都是一致的, 这就实现了跨平台, 跨服务器. 只需要一次配置好环境, 换到别的机子上就可以一键部署好, 大大简化了操作.

虚拟化技术

虚拟机技术

虚拟机就是带环境安装的一种解决方案. 它可以在一种操作系统里面运行另一种操作系统, 应用程序对此毫无感知, 因为虚拟机看上去跟真实系统一模一样, 而对于底层系统来说, 虚拟机就是一个普通文件, 不需要了就删掉, 对其他部分毫无影响. 这类虚拟机完美的运行了另一套系统, 能够使应用程序, 操作系统和硬件三者之间的逻辑不变.

虚拟机的缺点:    1.资源占用多    2.冗余步骤多    3.启动慢

容器虚拟化技术

由于虚拟机存在上述缺点, Linux 发展出了另一种内核虚拟化技术:Linux 容器(Linux Containers, 缩写为LXC).

Linux 容器不是模拟一个完整的操作系统, 而是对进程进行隔离. 有了容器, 就可以将软件运行所需的所有资源打包到一个隔离的容器中. 容器与虚拟机不同, 不需要捆绑一整套操作系统, 只需要软件工作所需的库资源和设置. 系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行.

二者对比

传统虚拟机技术是虚拟出一套硬件后, 在其上运行一个完整操作系统, 在该系统上再运行所需应用进程.

Docker 不需要 Hypervisor 实现硬件资源虚拟化. 运行在 docker 容器上的程序使用的都是实际物理机的硬件资源. 因此在 CPU, 内存利用率上 docker 有明显优势. 当新建一个虚拟机时. 虚拟机软件需要加载 GuestOS. 这个新建过程是分钟级别的. 而 docker 直接利用宿主机的操作系统内核. 不需要 GuestOS. 因此新建一个 docker 容器只需要几秒钟.

容器要比传统虚拟机更为轻便. 每个容器之间互相隔离, 每个容器有自己的文件系统, 容器之间进程不会相互影响, 能区分计算资源. 传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机, 而 Docker 只需要启动 10 个隔离的应用即可.

Docker容器虚拟机(VM)
操作系统与宿主机共享OS宿主机OS上运行虚拟机OS
存储大小镜像小. 便于存储与传输镜像庞大(wmdk, vdi 等)
运行性能几乎无额外性能损失操作系统额外的CPU, 内存消耗
移植性轻便, 灵活. 适应于Linux笨重. 与虚拟化技术耦合度高
硬件亲和性面向软件开发者面向硬件运维者
部署速度快速. 秒级较慢. 10s以上

Docker 安装与配置

安装 ( CentOS7 )

① Docker 要求 CentOS 系统的内核版本高于 3.10.

uname -r 查看当前的内核版本

② 使用 root 权限登录 Centos. 确保 yum 包更新到最新.

yum update

③ 卸载旧版本 Docker ( 如果安装过旧版本的话 )

yum remove docker docker-common docker-selinux docker-engine

④ 安装需要的软件包, yum-util 提供 yum-config-manager 功能, 另外两个是 devicemapper 驱动依赖的.

yum install -y yum-utils device-mapper-persistent-data lvm2

⑤ 设置 yum 源

yum-config-manager --add-repo mirrors.aliyun.com/docker-ce/l…

⑥ 查看所有仓库中所有 docker 版本. 可以选择指定版本进行安装.

yum list docker-ce --showduplicates | sort -r

⑦ 安装 docker

方式一 : 安装最新版本,由于 repo 中默认只开启 stable 仓库, 故这里安装的是最新稳定版

yum install docker-ce

方式二 : 安装指定版本

yum install docker-ce-18.06.0.ce

⑧ 启动 docker

service docker start

⑨ 验证安装是否成功 ( 有 client 和 service 两部分表示 docker 安装启动都成功了 )

docker version

配置

① 配置 Docker 镜像国内源

在 /etc/docker/daemon.json 文件 ( 若没有该文件, 请自行创建 ) 中添加下面参数, 此处使用的是中国科技大学的docker镜像源 :

{
   "registry-mirrors" : ["https://docker.mirrors.ustc.edu.cn"]
}

② 设置 Docker 开机自启

systemctl enable docker

③ Docker 如何卸载 ?

yum remove docker docker-common docker-selinux docker-engine

Docker 的 helloworld 镜像

hello world 镜像

现在开始运行 Docker 的 hello-world 镜像.

① 登入 Linux, 启动 Docker 服务.

service docker start

② 运行 hello-world 镜像

docker run hello-world

由于本地还不存在该镜像文件, 所以会先从 Docker 仓库上下载该镜像, 然后在容器内运行.

hello-world 的 Dockerfile 内容如下,只有短短三条指令 :

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

执行 run 命令 Docker 做了什么?

当使用 docker run 来创建容器时. Docker 在后台运行的标准操作包括:

1.检查本地是否存在指定的镜像. 不存在就从公有仓库 Docker Hub 上下载.

2.利用镜像创建并启动一个新的容器. 以该镜像为模板创建新的容器实例运行

3.分配一个文件系统. 并在只读的镜像层外面挂载一层可读写层.

4.从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去.

5.从地址池配置一个 ip 地址给容器.

6.执行用户指定的应用程序.

7.执行完毕后容器被终止.

Docker 架构

Docker 架构图:

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

  • docker 主机 ( Host ):安装了 Docker 程序的机器(Docker 直接安装在操作系统之上)
  • docker 客户端 ( Client ):连接 Docker 主机进行操作;最常用的 Docker 客户端是 docker 命令.
  • docker 服务器 ( Docker deamon ) : Docker daemon 是服务器组件, 以 Linux 后台服务的方式运行在 docker 主机上. 负责创建, 运行, 监控容器, 构建, 存储镜像.

默认配置下, Docker daemon 只能响应来自本地 Host 的客户端请求. 如果要允许远程客户端请求, 需要在配置文件中打开 TCP 监听.

Docker 的基本组成

镜像 image 镜像类似于面向对象中的类.

容器 container 容器类似于面向对象中的对象 ( 类的实例 ).

仓库 repository 仓库类似于 Github.

从应用软件的角度来看, Dockerfile , Docker 镜像, Docker 容器分别代表了软件的三个不同阶段:

  • Dockerfile 是软件的原材料.
  • Docker 镜像是软件的交付品.
  • Docker 容器则是可以认为是软件的运行态.

Dockerfile 面向开发, Docker 镜像成为交付标准, Docker 容器则涉及部署与运维, 三者缺一不可, 合力充当 Docker 体系的基石.

镜像

镜像 image : 将应用程序和运行环境打包形成一个可交付的程序, 这个打包好的程序就是 Docker 的镜像文件. Docker 镜像是一个只读的模板. 镜像可以用来创建 Docker 容器, 一个镜像可以创建多个容器.

镜像有多种生成方法:

  • 可以从无到有开始创建镜像.
  • 可以下载并使用别人的镜像.
  • 可以在现有镜像上创建新的镜像.

容器

容器 Container : Docker 利用容器独立运行的一个或一组应用. 容器是用镜像创建的运行实例. 在启动的时候创建一层可写层作为最上层( 因为镜像是只读的 ).

容器的定义和镜像几乎一模一样, 也是一堆层的统一视角, 唯一区别在于容器的最上面那一层是可读可写的.

容器可以被启动, 开始, 停止, 删除. 并且每个容器都是相互隔离的.

可以把容器看能是一个简易版的 Linux 环境( 包括 root 用户权限, 进程空间, 用户空间和网络空间等 )和运行在其中的应用程序.

仓库

仓库 repository : 仓库是集中存放统像文件的场所. 可以类比 Github.

可以将自己的镜像上传到公有或者私有仓库, 在其他机器上使用这个镜像的时候, 只需要从仓库上 pull 下来就可以了.

仓库分为公开仓库(Public)和私有仓库(Private)两种形式. 最大的公开仓库是 Docker Hub, 存放了数量庞大的镜像供用户下载. 国内的公开仓库包括阿里云, 网易云等.