Docker的优势
- docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动
docker
需要的资源更少,docker
在操作系统级别进行虚拟化,docker
容器和内核交互,几乎没有性能损耗,性能优于通过Hypervisor
层与内核层的虚拟化docker
更轻量,docker
的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker
运行的镜像数远多于虚拟机数量,对系统的利用率非常高- 与虚拟机相比,
docker
隔离性更弱,docker
属于进程之间的隔离,虚拟机可实现系统级别隔离 - 安全性:
docker
的安全性也更弱。Docker
的租户root
和宿主机root
等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root
权限和宿主机的root
虚拟机权限是分离的,并且虚拟机利用如Intel
的VT-d
和VT-x
的ring-1
硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击 - 可管理性:
docker
的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如VMware vCenter
提供完备的虚拟机管理能力 - 高可用和可恢复性:
docker
对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制,VMware
可承诺虚拟机99.999%
高可用,保证业务连续性 - 快速创建、删除:虚拟化创建是分钟级别的,
Docker
容器创建是秒级别的,Docker
的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间 - 交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。
Docker
在Dockerfile
中记录了容器构建过程,可在集群中实现快速分发和快速部署
特性 |
容器 |
虚拟机 |
启动 |
秒级 |
分钟级 |
硬盘使用 |
一般为MB |
一般为GB |
性能 |
接近原生 |
弱于 |
系统支持量 |
单机支持上千个容器 |
一般是几十个 |
2、docker的命令执行流程图
说明:docker的三个重要概念
Image (镜像):(可以理解成一个封装好不能修改的只能在容器中执行的软件)
Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像(Image)就是一堆只读层(read-only layer)的统一视角
Container (容器):(可以理解为一个虚拟的服务器)
容器 (container) 的定义和镜像 (image) 几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
Repository (仓库):(存放镜像用的,类似git,有个远程的和本地的仓库)
Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry (仓库注册服务器)就是这样的服务。有时候会把仓库 (Repository) 和仓库注册服务器 (Registry) 混为一谈,并不严格区分。Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。实际上,一个 Docker Registry 中可以包含多个仓库 (Repository) ,每个仓库可以包含多个标签 (Tag),每个标签对应着一个镜像。所以说,镜像仓库是 Docker 用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签.。
3、Docker的安装和使用
CentOS:使用sudo yum install去安装
Ubuntu:使用sudo apt install安装
最简单的方式,直接输入sudo docker ,看提示要安装那些东西就跟着安装就行了
查看是否安装:docker version 或者 docker info (可能需要管理员权限)
使用前启动docker服务:
sudo systemctl enable docker
sudo systemctl start docker
简单运行一个hello world:
先从镜像仓库拉取一个hello world镜像:docker pull library/hello-world
运行镜像:docker run hello-world
结果:
输出这段提示以后,hello world 就会停止运行,容器自动终止。有些容器不会自动终止,因为提供的是服务,比如Mysql镜像等。
4、Docker架构
Docker Client:(可以简单理解为当前运行的主机)
Docker Client
,也称 Docker
客户端。它其实就是 Docker
提供命令行界面 (CLI)
工具,是许多 Docker
用户与 Docker
进行交互的主要方式。客户端可以构建,运行和停止应用程序,还可以远程与Docker_Host
进行交互。最常用的 Docker
客户端就是 docker
命令,我们可以通过 docker
命令很方便地在 host
上构建和运行 docker
容器。
Docker daemon:(可以理解为就是Docker软件,容器和镜像都由它去管理)
Docker daemon
是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,我们也把它称为守护进程。它负责响应来自 Docker Client 的请求,然后将这些请求翻译成系统调用完成容器管理操作。该进程会在后台启动一个 API Server ,负责接收由 Docker Client 发送的请求,接收到的请求将通过Docker daemon 内部的一个路由分发调度,由具体的函数来执行请求。
Docker Image:(可以理解为只能在容器中执行的软件,只能读不能改的那种)
Docker
镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可将 Docker 镜像看成只读模板,通过它可以创建 Docker 容器。
Docker Registry:(可以理解为镜像的git仓库,有远程和本地的仓库,本地仓库在Docker daemon中)
Docker registry
是存储 docker image 的仓库,它在 docker 生态环境中的位置如下图所示:
运行docker push、docker pull、docker search时,实际上是通过 docker daemon 与 docker registry 通信。
Docker Container:(可以理解为镜像软件执行的环境,类似一个虚拟服务器)
Docker
容器就是 Docker 镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。 Docker Container 提供了系统硬件环境,我们可以使用 Docker Images 这些制作好的系统盘,再加上我们所编写好的项目代码, run 一下就可以提供服务啦。
5、Docker常用命令
更多详细docker命令参考:https://www.runoob.com/docker/docker-command-manual.html
镜像的管理类型git仓库,所以可以从远程仓库拉取一个镜像:
拉取一个 docker 镜像:docker pull image_name
image_name
为镜像的名称,而如果我们想从 Docker Hub 上去下载某个镜像,我们可以使用以下命令:
docker pull centos:latest
centos:lastest
是镜像的名称, Docker daemon 发现本地没有我们需要的镜像,会自动去 Docker Hub 上去下载镜像,下载完成后,该镜像被默认保存到 /var/lib/docker 目录下。
接着我们如果想查看下主机下存在多少镜像,我们可以用如下命令:
docker images
我们要想知道当前有哪些容器在运行,我们可以用如下命令:
docker ps -a
-a
是查看当前所有的容器,包括未运行的
我们该如何去对一个容器进行启动,重启和停止呢?我们可以用如下命令:
注意:以下的container_name/container_id指的是docker ps列出来的容器的名称或者id,不是两个都要,只需要一个名称或者就可以了。
docker start container_name/container_id
docker restart container_name/container_id
docker stop container_name/container_id
这个时候我们如果想进入到这个容器中,我们可以使用 attach 命令:
docker attach container_name/container_id
那如果我们想运行这个容器中的镜像的话,并且调用镜像里面的 bash ,我们可以使用如下命令:
docker run -t -i container_name/container_id /bin/bash
那如果这个时候,我们想删除指定镜像的话,由于 image 被某个 container 引用(拿来运行),如果不将这个引用的 container 销毁(删除),那 image 肯定是不能被删除。我们首先得先去停止这个容器:
docker ps
docker stop container_name/container_id
然后我们用如下命令去删除这个容器:
docker rm container_name/container_id
然后这个时候我们再去删除这个镜像:
docker rmi image_name
6、Image镜像创建
镜像有多种生成方法:
- 从无到有开始创建镜像(这个比较难)
- 下载并使用别人创建好的现成的镜像(比如从仓库获取,使用备份的tar文件导入)
- 在现有镜像上创建新的镜像(使用Dokcerfile创建)
使用Dockerfile创建镜像:
Dockerfile
是自动构建 docker 镜像的配置文件, 用户可以使用 Dockerfile 快速创建自定义的镜像。Dockerfile 中的命令非常类似于 linux 下的 shell 命令。
Dockerfile
是由一行行命令语句组成,并且支持已 # 开头的注释行。
一般来说,我们可以将 Dockerfile 分为四个部分:
- 基础镜像(父镜像)信息指令
FROM
- 维护者信息指令
MAINTAINER
- 镜像操作指令
RUN
、EVN
、ADD
和WORKDIR
等 - 容器启动指令
CMD
、ENTRYPOINT
和USER
等
下面是一段简单的Dockerfile的例子:
FROM python:2.7MAINTAINER Angel_Kitty
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]
我们可以分析一下上面这个过程:
1
、从 Docker Hub 上 pull 下 python 2.7 的基础镜像
2
、显示维护者的信息
3
、copy 当前目录到容器中的/app目录下 复制本地主机的
4
、指定工作路径为 /app
5
、安装依赖包
6
、暴露 5000 端口
7
、启动 app
常用的指令
由于 Dockerfile 中所有的命令都是以下格式:INSTRUCTION argument ,指令 (INSTRUCTION) 不分大小写,但是推荐大写
FROM
FROM
是用于指定基础的 images ,一般格式为 FROM
MAINTAINER
MAINTAINER
是用于指定镜像创建者和联系方式,一般格式为 MAINTAINER
COPY
COPY
是用于复制本地主机的
当使用本地目录为源目录时,推荐使用 COPY 。一般格式为 COPY
WORKDIR
WORKDIR
用于配合 RUN,CMD,ENTRYPOINT 命令设置当前工作路径。可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令。默认路径为/。一般格式为 WORKDIR /path/to/work/dir 。
RUN
RUN
用于容器内部执行命令。每个 RUN 命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。一般格式为 RUN
EXPOSE
EXPOSE
命令用来指定对外开放的端口。一般格式为 EXPOSE
ENTRYPOINT
ENTRYPOINT
可以让你的容器表现得像一个可执行程序一样。一个 Dockerfile 中只能有一个 ENTRYPOINT,如果有多个,则最后一个生效。
ENTRYPOINT
命令也有两种格式:
ENTRYPOINT ["executable", "param1", "param2"]
:推荐使用的 exec形式
ENTRYPOINT command param1 param2
:shell 形式
CMD
CMD
命令用于启动容器时默认执行的命令,CMD 命令可以包含可执行文件,也可以不包含可执行文件。不包含可执行文件的情况下就要用 ENTRYPOINT 指定一个,然后 CMD 命令的参数就会作为ENTRYPOINT的参数。
CMD
命令有三种格式:
CMD ["executable","param1","param2"]
:推荐使用的 exec 形式。
CMD ["param1","param2"]
:无可执行程序形式
CMD command param1 param2
:shell 形式。
一个 Dockerfile 中只能有一个CMD,如果有多个,则最后一个生效。而 CMD 的 shell 形式默认调用 /bin/sh -c 执行命令。
构建Dockerfile
先创建一个空目录,在这个空目录中创建一个名称为Dockerfile的文件:
FROM nginx
MAINTAINER test
RUN echo 'Hello, Docker!
' > /usr/share/nginx/html/index.html
在 Dockerfile 文件所在目录执行:docker build -t test/test_web:v1 .
-t
是为新镜像设置仓库和名称,其中test为仓库名,test_web为镜像名,:v1为标签(不添加为默认 latest )
查看所有镜像:docker images
启动容器:docker run --name=test_web -d -p 8080:80 test/test_web:v1
说明:-p指的是绑定的端口,即监听当前主体的8080端口,并将请求转发到容器的80端口,所以在浏览器输入http://<主机ip>:8080就能看到Hello, Docker!
查看运行中的容器:docker ps