简介

介绍

例如我们完成了一个Web应用,这个时候我们想发给我们的朋友看看,或者部署到远程的云服务器上。那么首先,我们就需要配置相同的软件,例如数据库,Web服务器,必要的插件,库等等,而且你还不能保证软件可以正常的运作起来,因为别人可能使用的是完全不一样的操作系统,即便是同样使用Linux,每种发行版之间还是存在着微小的区别。为了模拟完全相同的本地开发环境,我们自然会想到虚拟机,但是虚拟机需要模拟硬件运行整个操作系统,不但体积臃肿,内存占用高,程序的运行效率性能也会受到影响。

这个时候就轮到Docker的用场了,Docker在概念上和虚拟机非常的相似,但却轻量很多,他不会去模拟底层的硬件,只为每一个应用提供完全隔离的运行环境,你可以在环境中配置不同的工具文件,并且不同的工作环境之间不会有影响,这个环境我们在Docker中也称作容器(Container)。

Docker和虚拟机VM的区别

虚拟机实现资源的隔离的方式是利用独立的Guest OS,以及利用Hypervisor虚拟化CPU、内存、IO等设备来实现的。直观上来讲VM多了一层guest OS,同时Hypervisor会对硬件资源进行虚拟化,docker直接使用硬件资源,所以资源利用率相对docker低也是比较容易理解的。

VM(VMware)在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,然后再安装应用;而Container(Docker容器),在宿主机器、宿主机器操作系统上创建Docker引擎,在引擎的基础上再安装应用。

虚拟机的Guest层,还有Hypervisor层在Docker上已经被Docker Engine层所取代,在这里我们需要知道,Guest OS 是虚拟机安装的操作系统,是一个完整的系统内核,另外Hypervisor可以理解为硬件虚拟化平台,它在后Host OS以内核驱动的形式存在。

Docker直接利用虚拟机机的系统内核,避免了虚拟机启动时所需要的系统引导时间和操作系统运行的资源消耗,利用Docker能够在几秒钟之内启动大量的容器,是虚拟机无法办到的。快速启动低资源消耗的优点,使Docker在弹性云平台自动运维系统方面具有很好的应用场景。

基本组成

Docker中有三个重要概念Dockerfile,Image和Container

  • Image即为镜像,我们可以理解为一个虚拟机的快照(Snapshot),里面包含了你要部署的应用程序以及他关联的所有库,通过镜像我们可以创建许多个不同的Container容器。

  • Container即为容器,我们可以理解为一台台运行起来的虚拟机,里面运行着我们的应用程序,每一个容器都是独立运行的,之间互不影响

  • Dockerfile就像是一个自动化脚本,他被用来创建镜像Image,过程就好比是我们在虚拟机中安装操作系统和软件一样,只不过通过Dockerfile这个自动化脚本完成了

基本使用

安装

以macOS为例,我们可以直接从官网链接进行手动下载

或者如果已经安装过brew,直接使用如下命令安装Docker:

1
brew install --cask --appdir=/Applications docker

获取镜像

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

1
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

例如我们拉取Ubuntu 18.04版本的镜像:

1
2
3
4
5
6
7
8
> docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
92dc2a97ff99: Pull complete
be13a9d27eb8: Pull complete
c8299583700a: Pull complete
Digest: sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04

上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub (docker.io)获取镜像。而镜像名称是 ubuntu:18.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 18.04 的镜像。docker pull 命令的输出结果最后一行给出了镜像的完整名称,即: docker.io/library/ubuntu:18.04

如果需要查看保存下来的镜像,我们可以使用docker image ls

1
2
3
> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 329ed837d508 3 minutes ago 63.3MB

运行容器

我们一般情况下会使用docker run命令来实例化镜像,docker run的相关参数如下:

1
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

OPTIONS说明:

  • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
  • -d: 后台运行容器,并返回容器ID;
  • -i: 以交互模式运行容器,通常与 -t 同时使用;
  • -P: 随机端口映射,容器内部端口随机映射到主机的端口
  • -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
  • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
  • –name=“nginx-lb”: 为容器指定一个名称;
  • –dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
  • –dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
  • -h “mars”: 指定容器的hostname;
  • -e username=“ritchie”: 设置环境变量;
  • –env-file=[]: 从指定文件读入环境变量;
  • –cpuset=“0-2” or --cpuset=“0,1,2”: 绑定容器到指定CPU运行;
  • **-m :**设置容器使用内存最大值;
  • –net=“bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
  • –link=[]: 添加链接到另一个容器;
  • –expose=[]: 开放一个端口或一组端口;
  • –volume , -v: 绑定一个卷

例如:

使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。

1
docker run --name mynginx -d nginx:latest

使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。

1
docker run -P -d nginx:latest

使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。

1
docker run -p 80:80 -v /data:/data -d nginx:latest

绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。

1
$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。

1
2
runoob@runoob:~$ docker run -it nginx:latest /bin/bash
root@b8573233d675:/#

同样的我们也可以通过docker container ls来查看已经创建的容器,例如:

1
2
3
4
5
6
> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ad290330b51 docker.elastic.co/elasticsearch/elasticsearch:7.14.2 "/bin/tini -- /usr/l…" 2 weeks ago Up 4 seconds 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp es
c6873fab4ecb redis "docker-entrypoint.s…" 2 months ago Up 4 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
db5b8c205e9c mysql "docker-entrypoint.s…" 2 months ago Up 2 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
66754e0b5208 zookeeper "/docker-entrypoint.…" 2 months ago Up 1 second 2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 8080/tcp zookeeper

当然相关操作,我们也可以通过面板的可视化界面来完成:

使用Dockerfile定制镜像

就像我们之前提及的一样,Dockerfile就像是一个自动化脚本,他被用来创建镜像Image,过程就好比是我们在虚拟机中安装操作系统和软件一样,只不过通过Dockerfile这个自动化脚本完成了

所以我们可以创建一个空的文件夹,在空白的目录中建立一个文本文件Dockerfile:

1
2
3
> mkdir mynginx
> cd mynginx
> touch Dockerfile

内容为:

1
2
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

其中FROM命令从仓库中拉取了nginx镜像,随后RUN方法进入并执行了echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html,对主页页面进行了修改操作。

随后我们使用命令:

1
docker build [选项] <上下文路径/URL/->
1
2
3
4
5
6
7
8
9
$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM nginx
---> e43d811ce2f4
Step 2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
---> Running in 9cdc27646c7b
---> 44aa4490ce2c
Removing intermediate container 9cdc27646c7b
Successfully built 44aa4490ce2c

从命令的输出结果中,我们可以清晰的看到镜像的构建过程。在 Step 2 中,如同我们之前所说的那样,RUN 指令启动了一个容器 9cdc27646c7b,执行了所要求的命令,并最后提交了这一层 44aa4490ce2c,随后删除了所用到的这个容器 9cdc27646c7b