在计算机技术突飞猛进的今天, Docker在国内发展的如火如荼,特别是在一线互联网公司,Docker的使用是十分广泛的,在理解docker以前,咱们先熟悉两个概念,容器和虚拟机。html
1、容器与虚拟机python
传统的虚拟机有VMware, VirtualBox ,它们须要模拟整台机器包括硬件,每台虚拟机都须要有本身的操做系统,虚拟机一旦开启,预分配给它们的资源将所有被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操做系统。nginx
而容器技术是和咱们的宿主机共享硬件资源及操做系统,能够实现资源的动态分配。容器包含应用和其全部的依赖包,可是与其余容器共享内核。容器在宿主机操做系统中,在用户控件以分离的进程运行。web
容器技术是实现操做系统虚拟化的一种途径,可让您在资源受到隔离的进程中运行应用程序及其依赖关系。经过使用容器,咱们能够轻松打包应用程序的代码、配置和依赖关系,将其编程容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器帮助保证应用程序快速、可靠、一致性部署,其间不受部署环境的影响。容器还赋予咱们对资源更多的精细化控制能力,让咱们的基础设施效率更高、经过下面这张图咱们能够很直观的反映出两者的区别。docker
Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的Linux容器解决方案。shell
Linux容器不是模拟一个完整的操做系统,而是对进程进行隔离,至关于在正常进程的外面套了一个保护层。对于容器里面的进程来讲,它接触到的各类资源都是虚拟的,从而实现与底层系统的隔离。编程
Docker将应用程序与该程序的依赖,打包在一个文件里。运行这个文件,就会生成一个虚拟容器,程序在这个虚拟容器里运行,就好像在真实的物理机上运行同样,有了Docker,就不用担忧环境问题。flask
整体来讲,Docker的接口至关简单,用户能够方便的建立和使用容器,把本身的应用放入容器,容器还能够进行版本管理,复制,分享,修改,就像管理代码同样。centos
2、Docker的优点浏览器
一、Docker启动快速,属于秒级别。虚拟机一般须要几分钟去启动。
二、Docker须要的资源更少,Docker在操做系统级别进行虚拟化,Docker容器和内核交互,几乎没有性能损耗,性能优于经过 Hypervisor
层与内核层的虚拟化
三、Docker更轻量,Docker的架构能够共用一个内核与共享应用程序库,所占内存极小。一样的硬件环境,Docker运行的镜像数远低于虚拟机数量,对系统的利用率很是高
四、安全性, Docker的安全性也更弱。Docker的租户root和宿主机root等同,一旦容器内的用户从普通用户权限提高为root权限,它就直接具有了宿主机的root权限,进而可进行无限制的操做。虚拟机租户root权限和宿主机的root虚拟机权限是分离的,而且虚拟机利用如intel的vt-d和vt-x的ring-1硬件隔离技术,这种隔离技术能够防止虚拟机突破和彼此交互,而容器至今尚未任何形式的硬件隔离,这使得容器容易受到攻击
五、可管理性:Docker的集中化管理工具还不算成熟。各类虚拟化技术都有成熟的管理工具,例如VMware Vcentor提供完备的虚拟机管理能力
六、高可用和可恢复性: Docker对业务的高可用支持是经过快速从新部署实现的。虚拟化具有负载均衡,高可用,容错,迁移和数据保护等通过生产实践检验的成熟保障机制,VMware可承诺虚拟机99.9999%高可用,保证业务连续性
七、 交付、部署:虚拟机能够经过镜像实现环境交付的一致性,但镜像分发没法体系化。 Docker在Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署
3、Docker的三个基本概念
从上图咱们能够看到,Docker中包括三个基本的概念:
一、镜像是Docker运行容器的前提,仓库是存放镜像的场所,可见镜像是Docker的核心。
那么镜像究竟是什么呢?
Docker镜像能够看做是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数。镜像不包含任何动态数据,其内容在构建以后也不会被改变。
二、Container (容器)
容器的定义和镜像几乎如出一辙,也是一堆层的统一视角,惟一区别在于容器的最上面那一层是可读可写的。
因为容器的定义并无说起是否要运行容器,因此实际上,容器 = 镜像 + 读写层。
三、Repository(仓库)
Docker仓库是集中存放镜像文件的场所,镜像构建完成后,能够很容易在当前宿主上运行,可是,若是须要在其余服务器上使用这个镜像,咱们须要一个集中的存储、分发镜像的服务,Docker Registry(仓库注册服务器)就是这样的服务。 有时候会把仓库(Repository)和仓库注册服务器(Registry)混为一谈,并不严格区分。 实际上,一个Docker Registry中能够包含多个仓库(Repository),每一个仓库能够包含多个标签 ,每一个标签对应着一个镜像。因此说,镜像仓库是Docker用来集中存放镜像文件的地方相似于咱们以前经常使用的代码仓库。
仓库又能够分为两种形式:
(1)public(共有仓库)
Docker Registry公有仓库是开放给用户使用、容许用户管理镜像的 Registry
服务。通常这类公开服务容许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
(2)private(私有仓库)
Docker官方提供了Docker Registry镜像,能够直接使用作为私有Registry服务。当用户建立了本身的镜像以后就可使用push命令将它上传到公有或者私有仓库,这样下次在另一台机器上使用这个镜像时候,只须要从仓库上 pull下来就能够了。
4、Docker的架构
Docker使用C/S架构,即客户端/服务器体系结构。Docker客户端与Docker服务器进行交互,Docker服务端负责构建、运行和分发Docker镜像。Docker客户端与服务端能够运行在一台机器上,也能够经过RESTful、stock或网络接口与远程Docker服务端进行通讯。
这张图展现了Docker客户端、服务端和Docker仓库(即Docker Hub和Docker Cloud ),默认状况下Docker会在Docker中央仓库寻找镜像文件,这种利用仓库管理镜像的设计理念相似于Git,固然这个仓库是能够经过修改配置来指定的,甚至咱们能够建立咱们本身的私有仓库。
Docker采用的是C/S架构,客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器能够运行在同一个Host上,客户端也能够经过socket或REST API与远程的服务器通讯。
一、Docker Client
Docker客户端其实就是Docker提供命令行界面工具,是许多Docker 用户与Docker 进行交互的主要方式。客户端能够构建、运行和中止应用程序,还能够远程与Docker_HOST进行交互。 最经常使用的Docker客户端就是Docker命令,咱们能够经过Docker命令很方便地在host上构建和运行Docker容器。
二、Docker Daemon
Docker Daemon是服务器组件,以Linux后台服务的方式运行,是Docker最核心的后台进程,咱们也把它称为守护进程。它负责相应来自Docker Client的请求,而后将这些请求翻译成系统调用完成容器管理操做。该进程会在后台启动一个API Server,负责接收由Docker Client发送的请求,接收到的请求将经过Docker Daemon内部的一个路由分发调用,由具体的函数来执行请求。
Docker Daemon的架构以下所示:
Docker Daemon能够认为是经过Docker Server模块接受Docker Client的请求,并在Engine中处理请求,而后根据请求类型,建立出指定的Job并运行。Docker Daemon运行在Docker Host上,负责建立、运行、监控容器,构建、存储镜像。
运行过程的做用有如下几种可能:
因为Docker Daemon和Docker Client的启动都是经过可执行文件Docker来完成的,所以二者的启动流程很是类似。Docker可执行文件运行时,运行代码经过不一样的命令行flag参数,区分二者,并最终运行二者各自相应的部分。
启动Docker Daemon时,通常可使用一下命令来完成
docker --daemon = true docker –d docker –d = true
再由docker的main函数来解析以上命令的相应的flag参数,并最终完成Docker Daemon的启动。
Docker Daemon的启动流程:
默认配置下, Docker Daemon只能相应来自本地host的客户端请求。若是要容许远程客户端请求,须要在配置文件中打开TCP监听。咱们能够照着以下步骤进行配置:
(1)编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service
,在环境变量 ExecStart
后面添加 -H tcp://0.0.0.0
,容许来自任意 IP 的客户端链接。
(2)重启 Docker Daemon
systemctl daemon-reload systemctl restart docker.service
(3)咱们经过如下命令便可实现与远程服务器通讯
docker -H 服务器IP地址 info
-H 是用来指定服务器主机,info子命令用于查看docker服务器的信息
三、Docker Image
Docker镜像能够看做是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建以后也不会被改变。咱们可将Docker镜像当作只读模板,经过它能够建立Docker容器。
镜像有多种生成方法:
咱们能够将镜像的内容和建立步骤描述在一个文本文件中,这个文本文件称做Dockerfile,经过执行docker build<docker-file>命令能够构建出docker镜像。
四、Docker Registry
Docker Registry是存储Docker Image的仓库,它在Docker生态环境中的位置以下图所示:
运行Docker Push、Docker pull、Docker search时,其实是经过 Docker Daemon与 Docker registry通讯。
五、Docker Container
Docker容器就是Docker镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。Docker Container提供了系统硬件环境,咱们可使用Docker Image这些制做好的系统盘,再加上咱们编写好的项目代码,run一下就能够提供服务了。
5、Docker组件如何协做运行容器
容器启动过程以下:
具体过程能够看以下这幅演示图:
咱们能够经过Docker Image能够查看到hello-world已经下载到本地
6、Docker经常使用命令
咱们能够经过docker -h去查看命令的详细的帮助文档。在这里我只会讲一些日常平常比赛或者生活中咱们可能会用的比较多的一些命令。
例如,咱们须要拉取一个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是查看当前全部的容器,包括未运行的
咱们该如何去对一个容器进行启动,重启和中止呢?咱们能够用以下命令:
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 rmi image_name
此时,经常使用的Docker相关的命令就讲到这里为止了,咱们在后续的文章中还会反复地提到这些命令。
7、Dockerfile
Dockerfile是自动构建docker镜像的配置文件,用户可使用Dockerfile快速建立自定义的镜像,Dockerfile中的命令很是相似于Linux下的shell命令。
咱们能够经过下面这幅图来直观地感觉下 Docker 镜像、容器和 Dockerfile 三者之间的关系。
咱们从上图中能够看到,Dockerfile能够自定义镜像,经过Docker命令去运行镜像,从而达到启动容器的目的。
Dockerfile 是由一行行命令语句组成,而且支持已#开头的注释行。
通常来讲,咱们能够将Dockerfile分为四个部分:
下面是一段简单的Dockerfile的例子:
一、从Docker Hub上pull下python 2.7的基础镜像
二、显示维护者的信息
三、copy 当前目录到容器中的/app目录下 复制本地主机的<src>(Dockerfile所在目录的相对路径)到容器里<dest>
四、指定工做路径为/app
五、安装依赖包
六、暴露5000端口
七、启动app
这个例子是启动一个Python flask app的Dockerfile(flask是Python的一个轻量级的web框架),相信你们从这个例子中可以稍微理解了Dockerfile的组成以及指令的编写过程。
8、构建Dockerfile代码实例
mkdir static_web cd static_web touch Dockerfile 而后 vi Dockerfile 开始编辑该文件 输入 i 开始编辑 如下是咱们构建的Dockerfile内容 `````````` FROM nginx MAINTAINER Angel_Kitty <angelkitty6698@gmail.com> RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html `````````` 编辑完后 按 esc 退出编辑 而后 :wq 写入 退出
咱们在Dockerfile文件所在目录执行:
docker build -t angelkitty/nginx_web:v1 .
咱们解释一下,-t是为新镜像设置仓库和名称,其中angelkitty为仓库名,nginx_web为镜像名,:v1为标签(不添加为默认latest)
咱们构建完成以后,使用docker images命令查看全部镜像,若是存在REPOSTORY为nginx和TAG是v1的信息,就表示构建成功。
接下来使用docker run命令来启动容器
docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1
这条命令会用nginx镜像启动一个容器,命名为nginx_web,而且映射了 8080 端口,这样咱们能够用浏览器去访问这个nginx服务器:http:localhost:8080或者 http://本机的IP地址:8080/,页面返回信息:
这样一个简单使用Dockerfile构建镜像,运行容器的示例就完成了!
更多资讯,请关注“素小暖”公众号