在了解 Docker 之前,我们可以看一个小故事。
容器技术的起源
假设我们公司正在秘密研发 DataEase 2.0,我们的程序员自己从头到尾搭建了一套环境开始写代码,写完代码后程序员要把代码交给测试同学测试,这时测试同学开始从头到尾搭建这套环境,测试同学测完后终于可以上线了,这时运维同学又要重新从头到尾搭建这套环境,费了九牛二虎之力搭建好环境开始上线。
从整个过程可以看到,我们重复搭建了三套环境,是不是非常麻烦,影响公司的效率,聪明的程序员是永远不会满足现状的,因此又到了程序员改变世界的时候了,容器技术应运而生。
有聪明的小明同学可能会说:“等等,先别改变世界,我们有虚拟机啊,VMware 好用的飞起,先搭好一套虚拟机环境然后给测试和运维 clone 出来不就可以了吗?”。
在没有容器技术之前,这确实是一个好办法,只不过这个办法还没有那么好。
那为什么这个方法没有那么好呢?
容器 VS 虚拟机
因为相对于其它的应用程序,操作系统是一个非常耗费资源的程序。以 Windows 举例,一个 Windows 操作系统动辄需要几十 G 的存储,几 G 的内存,Linux 操作系统可能要好一些,但是也比普通的程序占用资源大。
这里假设我们有一个 16 G 内存的机器,要部署两个应用,用虚拟机技术的话我们可以这么划分,一个给 10 G,一个给 6 G,假设操作系统都占 2 G,那最后我们就只有 12 G 的内存可以给应用程序用,有 4 G 的内存是“浪费的”。
而且还有一个问题,就是操作系统的启动是比较慢的,可能动辄几分钟,那么时间的浪费也是很大的,那有没有什么东西,可以既有虚拟机的好处,将依赖和配置完全复制过来,又没有虚拟机的坏处,不浪费我们的资源和时间呢?
答案是肯定的,就是我们的容器技术。
什么是容器?
容器技术只隔离应用程序的运行时环境,但容器之间可以共享同一个操作系统。这里的运行时环境指的是程序运行依赖的各种库以及配置。
从图中我们可以看到容器更加的轻量,与操作系统动辄几 GB 的内存占用相比,容器技术只需数 MB 空间,因此我们可以在同样规格的硬件上大量部署容器,这是虚拟机所不能比拟的,而且不同于操作系统数分钟的启动时间容器几乎瞬时启动。
那么我们该怎么使用容器呢?这就要讲到 Docker 了。注意,容器是一种通用技术,Docker 只是其中的一种实现,还有其他的实现像 K8S 等。
什么是 Docker 呢?
Docker 是一个用于开发、发布和运行应用程序的开放平台。Docker 提供了在称为 “容器“ 的松散隔离环境中打包和运行应用程序的能力。可以让我们方便的创建和使用容器,Docker 将程序以及程序所有的依赖都打包到 Docker Container 。容器是轻量级的,包含运行应用程序所需的一切(环境依赖等),因此不需要依赖主机上当前安装的内容。隔离和安全性允许在给定主机上同时运行多个容器。
Docker 组成部分
先看一下 Docker 架构图,从图中我们可以看到实际上 Docker 使用了常见的 CS 架构,也就是 client-server 模式,Docker Client 负责处理用户输入的各种命令,比如 docker build、docker run,真正工作的其实是 server,也就是Docker daemon,值得注意的是,Docker client 和 Docker daemon 可以运行在同一台机器上。我们主要看看 Docker daemon、 Images、Containers、Regisry 。
Docker daemon
Docker 守护进程侦听 Docker API 请求并管理 Docker 对象,例如镜像、容器、网络和卷。守护进程还可以与其他守护进程通信来管理 Docker 服务。是 Docker 的核心组件。
Docker 三个基本概念:
-
镜像(Image):Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
-
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
-
仓库(Repository):仓库(Repository)类似 Git 的远程仓库,集中存放镜像文件。
三者的关系如同下图:
简单来说,我们可以把镜像看作是一个可以执行的程序,容器就是正在执行中的进程,而仓库就是我们可以存档镜像的地方,方便我们通过互联网获得镜像。可以观察上图中的 docker run 命令后的线条路径。
Docker 常用命令
关于 Docker 服务本身
#启动 docker 服务
systemctl start docker
#停止 docker 服务
systemctl stop docker
关于 Docker 镜像
#列出镜像
docker image ls
docker images
# 删除指定镜像
docker rmi <镜像Id>
关于 Docker 容器
#启动:启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
# 新建并启动
docker run [镜像名/镜像ID]
# 启动已终止容器
docker start [容器ID]
# 列出本机运行的容器
docker ps
# 列出本机所有的容器(包括停止和运行)
docker ps -a
# 停止运行的容器
docker stop [容器ID]
# kill 容器进程
docker kill [容器ID]
#重启容器
docker restart [容器ID]
#删除容器
docker rm [容器ID]
#进入容器
docker exec -it [容器ID] /bin/bash
关于Docker 容器日志
# 查看 docker 日志
docker logs -f --tail=100 [容器ID] # -f 实时日志 --tail=100 显 最后 100 条