Docker (码头工人)是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司(后由于 Docker 开源后大受欢迎就将公司改名为 Docker Inc ,总部位于美国加州的旧金山)内部的一个开源的 PAAS 服务 (Platform as a ServiceService )的业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 是基于 linux 内核实现,Docker 最早采用 LXC 技术 ,LXC 是 Linux 原生支持的容器技术 ,可以提供轻量级的虚拟化 ,可以说 docker 就是基于 LXC 发展起来 的,提供 LXC 的高级封装,标准的配置方法,在LXC的基础之上,docker提供了一系列更强大的功能。而虚拟化技术 KVM(KernelKernel-based Virtual Machine Machine) 基于 模块实现, 后来Docker 改为自己研发并开源的 runc 技术运行容器,彻底抛弃了LXC。
Docker 相比虚拟机的交付速度更快,资源消耗更低,Docker 采用客户端/服务端架构,使用远程API来管理和创建容器,其可以轻松的创建一个轻量级的、可移植的、自给自足的容器,docker 的三大理念是build(构建)、ship(运输)、 run(运行),Docker遵从apache 2.0协议,并通过(namespace及cgroup等)来提供容器的资源隔离与安全保障等,所以Docke容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机6-8%性能)的额外资源开销,因此可以大幅提高资源利用率,总而言之Docker是一种用了新颖方式实现的轻量级虚拟机.类似于VM但是在原理和应用上和VM的差别还是很大的,并且docker的专业叫法是应用容器(Application Container)。
我们可以看图理解docker ,docker 翻译过来是码头工人,我们可以这么理解,架设公司一批货物,这批货物分类,有些是给宝宝用的,有的是给孕妇使用的,有的是给成年人使用的,这三个货物,最好不要混在一起,因此对三种货物分类也不一样,锁的机制不同,之前货物运输的话,可能回混到一起,然后卸货的时候,一点一点拆开卸货,
使用docker 之后,我们可以把同类的货物 放在一起,然后集中存放在一个集装箱中,利用码头工人,docker放在货船上,卸货时候,我们独立打开一种集装箱就可以获取我们的货物,比较方便,
虽然有些不同,我们这里是IT技术,一种容器技术,我们可以通过容器将每种技术放在一起,把你的应用放在一起,然后放在容器中,这样应用和应用之前火线不会干扰,同时可以装在容器里面,可以方便搬运,这也是最理想的状态,(可移植性,标准化,隔离性)
统一基础设施环境-docker环境
硬件的组成配置
操作系统的版本
运行时环境的异构
统一程序打包(装箱)方式-docker镜像
java程序
python程序
nodejs程序
使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗,我们创建虚拟机的目的是为了运行应用程序,比如Nginx、PHP、Tomcat等web程序,使用虚拟机无疑带来了一些不必要的资源开销,但是容器技术则基于减少中间运行环节带来较大的性能提升。
根据实验,一个运行着CentOS的KVM虚拟机启动后,在不做优化的情况下,虚拟机自己就需要占用100~200 MB内存。此外,用户应用运行在虚拟机里面,它对宿主机操作系统的调用就不可避免地要经过虚拟化软件的拦截和处理,这本身又是一层性能损耗,尤其对计算资源、网络和磁盘I/O的损耗非常大。
比如: 一台96G内存的物理服务器,为了运行java程序的虚拟机一般需要分配8G内存/4核的资源,只能运行13台左右虚拟机,但是改为在docker容器上运行Java程序,每个容器只需要分配4G内存即可,同样的物理服务器就可以运行25个左右容器,运行数量相当于提高一倍,可以大幅节省IT支出,通常情况下至少可节约一半以上的物理设备
Docker 主机(Host): 一个物理机或虚拟机,用于运行Docker服务进程和容器,也称为宿主机,
node节点
Docker 服务端(Server): Docker守护进程,运行docker容器
Docker 客户端(Client): 客户端使用 docker 命令或其他工具调用docker API
Docker 镜像(Images): 镜像可以理解为创建实例使用的模板,本质上就是一些程序文件的集合
Docker 仓库(Registry): 保存镜像的仓库,官方仓库: https://hub.docker.com/,可以搭建私有仓库harbor
Docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务,其本质就是将镜像中的程序启动后生成的进程
*Docker deamon 为docker 守护进程,每个容器,是其的子进程
chroot 是被认为最早的容器技术之一,它可以把一个进程的文件系统隔离起来.
一个宿主机,运行多个容器,必然带来一些问题,而namespace恰好解决了这些
namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在核内,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统 空间、网络空间、进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离:
MNT Namespace: 每个容器都要有独立的根文件系统有独立的用户空间,以实现在容器里面启动服务并且使用容器的运行环境,即一个宿主机是ubuntu的服务器,可以在里面启动一个centos运行环境的容器并且在容器里面启动一个Nginx服务,此Nginx运行时使用的运行环境就是centos系统目录的运行环境,但是在容器里面是不能访问宿主机的资源,宿主机是使用了chroot技术把容器锁定到一个指定的运行目录里面。
IPC Namespace:一个容器内的进程间通信,允许一个容器内的不同进程的(内存、缓存等)数据访问,但是不能跨容器直接访问其他容器的数据
UTS namespace(UNIX Timesharing System包含了运行内核的名称、版本、底层体系结构类型等信息)用于系统标识,其中包含了主机名hostname 和域名domainname ,它使得一个容器拥有属于自己主机名标识,这个主机名标识独立于宿主机系统和其上的其他容器
ID NamespaceLinux系统中,有一个PID为1的进程(init/systemd)是其他所有进程的父进程,那么在每个容器内也要有一个父进程来管理其下属的子进程,那么多个容器的进程通PID namespace进程隔离(比如PID编号重复、器内的主进程生成与回收子进程等)
NET Namespace每一个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP协议栈等,Docker使用network namespace启动一个vethX接口(成对产生),这样你的容器将拥有它自己的桥接ip地址,通常是docker0,而docker0实质就是Linux的虚拟网桥,网桥是在OSI七层模型的数据链路层的网络设备,通过mac地址对网络进行划分,并且在不同网络直接传递数据
User Namespace: 允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户UID和GID,只是会把用户的作用范围限制在每个容器内,即A容器和B容器可以有相同的用户名称和ID的账户,但是此用户的有效范围仅是当前容器内,不能访问另外一个容器内的文件系统,即相互隔离、互不影响、永不相见。
Cgroups 最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,资源的计量以及资源的控制(比如:将进程挂起和恢复等操作)。
容器 runtime 是真正运行容器的地方,因此运行不同的容器,runtime 需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境
runc: 早期libcontainer是Docker公司控制的一个开源项目,OCI的成立后,Docker把libcontainer
项目移交给了OCI组织,runC就是在libcontainer的基础上进化而来,目前Docker默认的runtime,
runc遵守OCI规范,管*理工具连接runtime与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给runtime执行。
容器定义工具允许用户定义容器的属性和内容,以方便容器能够被保存、共享和重建。
Docker image: *是docker 容器的模板,runtime依据docker image创建容器
Dockerfile: *包含N个命令的文本文件,通过dockerfile创建出docker image
ACI(App container image): 与docker image类似,是CoreOS开发的rkt容器的镜像格式
统一保存镜像而且是多个不同镜像版本的地方,叫做镜像仓库
Docker hub: docker官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用
阿里云,网易等第三方镜像的公共仓库
Image registry: docker 官方提供的私有仓库部署工具,无web管理界面,目前使用较少
Harbor: vmware 提供的自带web界面自带认证功能的镜像私有仓库,目前有很多公司使用
当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎容器编排通常包括容器管理、调度、集群定义和服务发现等功能
Docker compose : docker 官方实现单机的容器的编排工具
Docker swarm: docker 官方开发的容器编排引擎
Mesos+Marathon: Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发的,后在Twitter得到广泛使用。通用的
集群组员调度平台,mesos(资源分配)与marathon(容器编排平台)一起提供容器编排引擎功能
Kubernetes: google领导开发的容器编排引擎,内部项目为Borg,且其同时支持 docker 和
CoreOS,当前已成为容器编排工具事实上的标准
容器网络:
docker自带的网络docker network仅支持管理单机的容器网络,当多主机运行的时候需要使用第三方开源网络,例如:calico、flannel等
服务发现:
容器的动态扩容特性决定了容器IP也会随之变化,因此需要有一种机制开源自动识别并将用户请求动态转发到新创建的容器上,kubernetes自带服务发现功能,需要结合kube-dns服务解析内部域名
容器监控:
可以通过原生命令docker ps/top/stats 查看容器运行状态,另外也可以使用Prometheus 、heapster等第三方监控工具监控容器的运行状态
数据管理:
容器的动态迁移会导致其在不同的Host之间迁移,因此如何保证与容器相关的数据也能随之迁移或随时访问,可以使用逻辑卷/存储挂载等方式解决
日志收集:
docker 原生的日志查看工具docker logs,但是容器内部的日志需要通过ELK等专门的日志收集分析和展示工具进行处理
原文:https://blog.51cto.com/13887323/2550604