一、docker的简介:
应用容器是个啥样子呢,一个做好的应用容器长的就像一个装好了一组特定应用的虚拟机一样,比如我现在想用mysql数据库,我直接找个装好了的MySQL的容器就可以了,想用的时候一运行容器,MySQL服务就起来了,就可以使用MySQL了
为什么不能直接安装一个MySQL?或者是SqlServer呢也可以啊?
答:因为有的时候根据每个人的电脑的不同,在物理机安装的时候会出现各种各样的错误,突然你的机器中病毒了或者是挂了,你所有的服务都需要重新安装。
注意:
但是有了docker,或者说是有了容器就不同了,你就相当于有了一个可以运行起来的虚拟机,只要你能运行容器,MySQL的配置就剩了 ,不用再去安装MySQL,如果你想换一台电脑,直接把容器端过来,就可以使用容器里面的服务了。
Docker是基于go语言开发的,代码托管在GitHub上,并遵循Apache2.0开源协议
Dokcer可以封装任何有效的应用程序,几乎可以达在任何一台服务器之间运行相同的服务,换句话说开发者,只需构建一次应用,就可以在多平台上运行,运维人员只需要配置他们的服务,即可运行所有的应用。
同时有了容器还可以保证整个开发、测试和生产环境可以保持高度一致。
注意:
此外容器也和虚拟机一样具有隔离性,各个容器之间的数据和内存空间相互隔离,可以保证一定的安全性。
Hyper-V、kvm和Xen等虚拟机管理程序都基于硬件防止机制。这就意味着他们对系统要求很高,然而Docker容器却使用的是共享操作系统。也就是说它们使用系统资源方面比虚拟机管理程序要高效节省的多。
容器不是对硬件进行虚拟化处理,而是驻留在一个Linux实例上。
Docker可以解决虚拟机能够解决的问题,同时也能够解决虚拟机由于资源要求过高而无法解决的问题。
dock的特点:
1. 快速交付应用程序
开发者使用一个标准的images来构建开发容器,开发完成之后,系统管理员就可以使用这个容器来部署代码。
Docker可以快速创建容器,快速部署应用程序,并让整个过程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。
Docker容器很轻!很快!容器的启动时间是次秒级的,节约开发、测试、部署时间
2.更容易部署和扩展
docker容器可以在几乎所有的环境中运行,物理机、虚拟机、公有云、私有云、个人电脑、服务器等等
docker容器兼容很多平台,这样就可以把一个应用程序从一个平台迁移到另外一个
3.效率更高
docker容器不需要hypervisor,他是内核级的虚拟化。
4.快速部署也意味着更简单的管理
通常只需要小小的改变就可以代替以往巨型和大量的更新工作
那么既然容器和虚拟机这么类似为啥不用虚拟机?
答:docker相对于VM还是有很多优点的:
1.启动速度快,容器通常在1秒内可以启动,而VM要很久。
2.资源利用率高,一台普通服务器可以跑上千个容器,而跑VM。。。。。。
3.性能开销小,VM需要额外的CPU和内存来完成OS的功能,这一部分占据了额外的资源。
下面的图片比较了Docker和传统虚拟化方式的不同之处
可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。
二、docker的体系结构
docker使用c/s架构,docker daemon 作为server端接受client的请求,并处理(创建、运行、分发容器),他们可以运行在一个机器上,也通过socket或者RESTful API通信
Docker daemon 一般在宿主机后台运行
Docker client以系统命令的形式存在,用户用docker命令来跟docker daemon交互。
一、’Docker守护进程(Docker daemon)
如上图分析所示,Docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过Docker客户端间接和其他通信
二、ocker客户端(Docker client)
Docker客户端,实际上是Docker的二进制程序,是用户与Docker交互方式。它接受用户指令并且与背后的Docker守护进程通信。
三、.docker 内部:
要理解docker内部构建,需要理解以下三种操作:
Docker 镜像-Docker images
Docker 仓库 -Docker registeries
Docker 容器-Docker container
1.Docker镜像
Docker镜像是Docker容器运行时的只读模板,镜像可以用来创建Docker容器。每一个镜像由一系列的层(layes)组成。
Docker使用unionFS(联合文件系统)来将这些层联合到单独的镜像中。
UnionFS允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。正因为有了这些层的存在,Docker是如此的轻量。当你改变了一个Docker镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。现在你不用程序发布整个镜像,只需要升级,层使得分发Docker镜像变得简单和快速。
每个docker都有很多层次构成,docker使用 union file systems 将这些不同的层结合到一个image中去。
例如:CentOS镜像中安装nginx,就成了nginx镜像,其实在此时docker镜像的层级概念就体现出来了。底层一个CentOS操作系统镜像,上面叠加一个nginx层,就完成了一个nginx镜像的构建。层级概念就不难理解,此时我们一般称CentOS操作系统镜像为nginx镜像层的父镜像。
2.docker仓库:
docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。同样的,docker仓库也有公有和私有的概念。公有的docker仓库名字是docker HUB。docker HUB提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(public)和私有仓库(Private)两种形式
最大的公开仓库是Docker HUB,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,
可以提供大陆用户更稳定快速地访问。
当然,用户也可以在本地网络内创建一个私有仓库。
当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下次在另一台机器上使用这个镜像时候,只需要从仓库上pull下来就可以了。
注:Docker仓库的概念更Git类似,注册服务器可以理解为GitHUb这样的托管服务。
3.Docker容器:
docker利用容器来运行应用,一个Docker容器包含了所有的某个应用运行所需要的环境。
每一个Docker容器都是从docker镜像创建的。docker容器可以运行、开始、停止、移动和删除。每一个docker容器都是独立和安全的应用平台。
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的Linux运行环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
与虚拟机相比,容器有一个很大的差异,它们被设计用来运行单进程,无法很好的模拟一个完整的环境。docker设计者极力推崇一个容器一个进程的方式,如果你要选择在一个容器中运行多个进程,那唯一情况是:出于调试目的。
容器中是设计来运行一个应用的,而非一台机器。你可能会把容器当虚拟机用,但你将失去很多的灵活性,因为docker提供了用于分离应用与数据的工具,使得你可以快捷地更新运行中的代码/系统,而不影响数据。
Docker从0.9版本开始使用libcontainer替代lxc,libcontainer和Linux系统的交互图如下:
四、Docker底层技术
Docker底层的2个核心技术分别是Namespace和Control groups
Namespace 用来隔离各个容器
(1.)pid Namespace
不同用户的进程就是通过pid Namespace 隔离开的,且不同 Namespace 中可以有相同pid。
所有的LXC进程在Docker中的父进程为Docker进程,每个lxc进程具有不同的Namespace。
(2.)net Namespace
有了pid Namespace ,每个Namespace中的pid能够相互隔离,但是网络端口还是共享Host的端口。网络隔离是通过net Namespace 实现的,每个net Namespace 有独立的 network devices,IP address,IP routing tables,/proc/net 目录。这样每个container的网络就能隔离开来。Docker 默认采用veth的方式将container中的虚拟网卡同host上的一个Docker bridge:docker0 连接在一起。
(3.) ipc Namespace
container 中进程交互还是采用Linux常见的进程间交互方法(interprocess communication - IPC),
括常见的信号量、消息队列和共享内存。container的进程间交互实际上还是Host上具有相同pid
Namespace中的进程间交互。
(4.)mnt Namespace
类似chroot,将一个进程放到一个特定的目录执行。mnt Namespace 允许不同Namespace的进程看到的文
件结构不同,这样每个 Namespace 中的进程所看到的文件目录就被隔离开了。在container里头,看到
的文件系统,就是一个完整的Linux系统,有/etc、/lib等,通过chroot实现。
(5.)uts Namespace
UTS(“UNIX Time-sharing System“)Namespace允许每个container拥有独立的hostname和domain
name,使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
(6.)user Namespace
每个container可以有不同的user 和 group id,也就是说可以在container内部用container内部的用户执
行程序而非Host上的用户。
总结:
有了以上6种Namespace从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个container就可以对
外展现出一个独立计算机的能力,并且不同ccontainer从OS层面实现了隔离。然而不同Namespace之间资
源还是相互竞争的,仍然需要类似ulimit来管理每个container所能使用的资源 --cgroup
Cgroups(Control groups)实现了对资源的配额和度量。