当前位置: 首页 > Linux

docker

时间:2023-04-06 06:55:10 Linux

什么是Docker?Docker使用谷歌推出的Go语言进行开发和实现。基于Linux内核的cgroup、namespace等技术,以及AUFS等UnionFS,对进程进行封装和隔离,属于操作系统层面的虚拟化技术。由于隔离进程独立于宿主机和其他隔离进程,所以又称为容器。Docker在容器的基础上进行了进一步的封装,从文件系统、网络互联到进程隔离等,极大地简化了容器的创建和维护。这使得Docker技术比虚拟机技术更轻、更快。下图比较了Docker与传统虚拟化方法的区别。传统的虚拟机技术是虚拟出一套硬件,在其上运行完整的操作系统,然后在该系统上运行所需的应用进程;而容器中的应用进程直接运行在宿主机的内核上,容器没有自己的内核,没有硬件虚拟化。因此,容器比传统的虚拟机更便携。Docker通俗解释Docker的思想来源于容器。容器能解决什么问题?在大船上,货物可以摆放整齐。而且各种货物都是按集装箱标准化的,集装箱之间不会相互影响。那我就不用水果专船,化学品专船了。只要货物装在集装箱里,我就可以用大船把它们全部运走。docker是一个类似的概念。不同的应用可能有不同的应用环境。比如.net开发的网站和PHP开发的网站依赖的软件是不一样的。如果把他们所依赖的软件都安装在一台服务器上,调试时间会很长,而且很麻烦,也会引起一些冲突。比如IIS和Apache访问端口冲突。这时候你就得隔离开发的网站了。net和php开发的网站。一般来说,我们可以在服务器上创建不同的虚拟机,将不同的应用放在不同的虚拟机上,但是虚拟机的开销比较大。Docker可以实现虚拟机隔离应用环境的功能,开销比虚拟机小。开发软件的时候用的是Ubuntu,但是运维管理是Centos。运维在将你的软件从开发环境转移到生产环境时,从Ubuntu转移到Centos时会遇到一些问题。例如:有一个特殊的版本数据库只有Ubuntu支持,Centos不支持。在转移过程中,运维不得不想办法解决这个问题。这时候如果你有docker,你可以直接打包开发环境交给运维,运维可以直接部署你给他的docker。而且部署速度很快。服务器负载方面,如果单独开一个虚拟机,虚拟机会占用空闲内存,如果部署了docker,会占用内存。Docker基本概念镜像(Image)操作系统分为内核空间和用户空间。对于Linux,内核启动后,挂载根文件系统,提供用户空间支持。Docker镜像(Image)相当于一个根文件系统。例如官方镜像ubuntu:16.04包含了Ubuntu16.04最小系统的完整根文件系统。Docker镜像是一种特殊的文件系统。除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含一些为运行时准备的配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,构建后内容不会改变。由于镜像中包含了操作系统完整的根文件系统,其体积往往非常庞大,因此在设计Docker时,充分利用了UnionFS技术,将其设计为分层存储架构。所以严格来说,镜像不是像ISO那样的打包文件。图像只是一个虚拟的概念。它的实际体现不是由一个文件组成,而是一组文件系统,或者说是多层文件系统的组合。作品。镜像构建的时候会一层层构建,上一层是下一层的基础。每一层构建完成后,不会再发生变化,下一层的任何变化只发生在本层。例如,删除上一层文件的操作,实际上并没有删除上一层文件,只是将当前层文件标记为已删除。最终容器运行的时候,虽然看不到这个文件,但实际上这个文件会一直跟在镜像后面。因此,在构建镜像时,需要格外小心。每层应该只包含需要添加到该层的内容,任何多余的东西都应该在该层构建结束之前清理干净。分层存储的特性也使得图像的重用和定制变得更加容易。您甚至可以使用之前构建的镜像作为基础层,然后进一步添加新的层来自定义您需要的内容并构建新的镜像。容器(Container)镜像(Image)与容器(Container)的关系,就像面向对象编程中的类和实例一样,镜像是一个静态定义,容器是镜像运行时的??实体。可以创建、启动、停止、删除、暂停等容器。容器的本质是一个进程,但与直接在宿主机上执行的进程不同,容器进程运行在自己独立的命名空间中。所以一个容器可以有自己的根文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器中的进程运行在一个隔离的环境中,使用起来就好像运行在一个独立于宿主机的系统下一样。这个特性使得容器封装的应用程序比直接在主机上运行更安全。容器还采用分层存储。每个容器运行时,都会以镜像为基础层,在其上创建当前容器的存储层。我们可以把这个为容器运行时读写准备的存储层称为容器存储层。容器存储层的生命周期与容器相同。当容器死亡时,容器存储层也死亡。因此,当容器被删除时,存储在容器存储层中的任何信息都将丢失。容器不应向其存储层写入任何数据,容器存储层应保持无状态。所有的文件写入操作都应该使用数据卷(Volume)或者绑定主机目录。在这些位置读写会跳过容器存储层,直接读写宿主机(或网络存储)。稳定性更高。数据卷的生命周期与容器无关。当容器死亡时,数据卷不会死亡。因此,使用数据卷后,容器删除或重启后数据不会丢失。仓库(Repository)镜像构建完成后,可以方便的在当前宿主机上运行。但是,如果我们需要在其他服务器上使用这个图片,我们就需要一个集中存储和分发图片的服务。DockerRegistry就是这样的服务。一个DockerRegistry可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库中会存放同一个软件的不同版本的镜像,往往会使用标签来对应软件的各个版本。我们可以使用<仓库名>:<标签>的格式来指定镜像是哪个版本的软件。如果没有给出标签,latest将被用作默认标签。以Ubuntu镜像为例,ubuntu是仓库的名字,里面包含了不同的版本标签,比如14.04、16.04。我们可以使用ubuntu:14.04或ubuntu:16.04来指定我们需要哪个版本的镜像。如果省略了标签,像ubuntu,它将被视为ubuntu:latest。仓库名称经常以两段路径形式出现,如jwilder/nginx-proxy。前者常表示DockerRegistry多用户环境中的用户名,后者常表示对应的软件名。但这也不是绝对的,要看具体使用的DockerRegistry软件或服务。